add program to test XML entities and coverage for it - sfeed_tests - sfeed tests and RSS and Atom files
 (HTM) git clone git://git.codemadness.org/sfeed_tests
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 6eca9afe6aebc7c3f32f341272b1ac7734085e45
 (DIR) parent e415995086723ab71dbf59368780681dd6ec7b91
 (HTM) Author: Hiltjo Posthuma <hiltjo@codemadness.org>
       Date:   Thu, 11 Dec 2025 20:19:35 +0100
       
       add program to test XML entities and coverage for it
       
       This tests some of the xml_entitytostr() functions from the application-use side.
       
       Some paths cannot happen because of how sfeed works.
       
       This increases test coverage from 98% to 100%.
       
       Diffstat:
         A xml_test_entities/build_coverage.sh |      21 +++++++++++++++++++++
         A xml_test_entities/main.c            |     144 +++++++++++++++++++++++++++++++
       
       2 files changed, 165 insertions(+), 0 deletions(-)
       ---
 (DIR) diff --git a/xml_test_entities/build_coverage.sh b/xml_test_entities/build_coverage.sh
       @@ -0,0 +1,21 @@
       +#!/bin/sh
       +# NOTE: make sure to disable pledge on OpenBSD, gcov needs rpath.
       +
       +XMLO="$HOME/p/sfeed/xml.o"
       +SFEEDDIR="$HOME/p/sfeed"
       +
       +header="$(readlink -f "$0")"
       +header="$(dirname "$header")/../gcov_dump.h"
       +
       +CC="gcc"
       +CFLAGS="-include $header -fprofile-arcs -ftest-coverage"
       +LDFLAGS="-fprofile-arcs"
       +
       +BIN="${SFEEDDIR}/test_xml_entities"
       +
       +rm -f *.gcda *.gcno *.o
       +rm -f main
       +
       +${CC} -o main.o -c main.c ${CFLAGS} ${LDFLAGS} "-I${SFEEDDIR}"
       +
       +${CC} -o "${BIN}" "$XMLO" main.o ${CFLAGS} ${LDFLAGS}
 (DIR) diff --git a/xml_test_entities/main.c b/xml_test_entities/main.c
       @@ -0,0 +1,144 @@
       +#include <stdio.h>
       +#include <string.h>
       +
       +#include "xml.h"
       +
       +int count, ok, failed;
       +
       +int
       +test(char *buf, size_t bufsiz,
       +     const char *input, int ret, const char *expect, int expectret)
       +{
       +        count++;
       +
       +        ret = xml_entitytostr(input, buf, bufsiz);
       +        if (ret != expectret) {
       +                printf("[%d] FAILED: input=%s, status=%d, expected status=%d\n",
       +                        count, input, ret, expectret);
       +                failed++;
       +                return 0;
       +        }
       +        /* if return status is -1 the result in buf should not be used */
       +        if (ret == -1) {
       +                ok++;
       +                return 0;
       +        }
       +
       +        if (strcmp(expect, buf)) {
       +                printf("[%d] FAILED: input=%s, expected=%s, got=%s\n",
       +                        count, input, expect, buf);
       +                failed++;
       +                return 0;
       +        }
       +        ok++;
       +
       +        return 1;
       +}
       +
       +int
       +main(void)
       +{
       +        char buf[8];
       +
       +        /* named entities */
       +        test(buf, sizeof(buf), "&amp;", 1, "&", 1);
       +        test(buf, sizeof(buf), "&lt;", 1, "<", 1);
       +        test(buf, sizeof(buf), "&gt;", 1, ">", 1);
       +        test(buf, sizeof(buf), "&apos;", 1, "'", 1);
       +        test(buf, sizeof(buf), "&quot;", 1, "\"", 1);
       +
       +        /* case-sensitivity of named entities (should not match) */
       +        test(buf, sizeof(buf), "&AMP;", -1, "&", -1);
       +        test(buf, sizeof(buf), "&LT;", -1, "<", -1);
       +        test(buf, sizeof(buf), "&GT;", -1, ">", -1);
       +        test(buf, sizeof(buf), "&APOS;", -1, "'", -1);
       +        test(buf, sizeof(buf), "&QUOT;", -1, "\"", -1);
       +
       +        /* HTML entities (should not match) */
       +        test(buf, sizeof(buf), "&euro;", -1, "&", -1);
       +        test(buf, sizeof(buf), "&EURO;", -1, "&", -1);
       +
       +        /* numeric entities */
       +        test(buf, sizeof(buf), "&#65;", 1, "A", 1);
       +        test(buf, sizeof(buf), "&#x41;", 1, "A", 1);
       +
       +        /* numeric entities rare characters */
       +        /* The XML specification doesn't recommend this. But we allow it */
       +        test(buf, sizeof(buf), "&#x00;", 0, "", 0); /* NUL */
       +        test(buf, sizeof(buf), "&#x01;", 1, "\x01", 1);
       +
       +        /* surrogate range */
       +        test(buf, sizeof(buf), "&#xd800;", -1, "", -1); /* start range >= */
       +        test(buf, sizeof(buf), "&#xdfff;", -1, "", -1); /* end range <= */
       +        test(buf, sizeof(buf), "&#xdc00;", -1, "\xed\xb0\x80", -1);
       +        /* near range */
       +        test(buf, sizeof(buf), "&#xe0000;", 4, "\xf3\xa0\x80\x80", 4);
       +        test(buf, sizeof(buf), "&#xd7ff;", 3, "\xed\x9f\xbf", 3);
       +        test(buf, sizeof(buf), "&#xd7fb;", 3, "\xed\x9f\xbb", 3);
       +
       +        test(buf, sizeof(buf), "&#x-1;", -1, "", -1);
       +        test(buf, sizeof(buf), "&#-1;", -1, "", -1);
       +        test(buf, sizeof(buf), "&#x-0;", -1, "", -1);
       +        test(buf, sizeof(buf), "&#-0;", -1, "", -1);
       +        test(buf, sizeof(buf), "&#+1;", -1, "", -1);
       +        test(buf, sizeof(buf), "&;", -1, "", -1);
       +        test(buf, sizeof(buf), "& ;", -1, "", -1);
       +        test(buf, sizeof(buf), "&amp;;", -1, "", -1);
       +        test(buf, sizeof(buf), "&#65;;", -1, "", -1);
       +        test(buf, sizeof(buf), "&amp;;a", -1, "", -1);
       +        test(buf, sizeof(buf), "&#65;;a", -1, "", -1);
       +        test(buf, sizeof(buf), "&# 65;", -1, "", -1);
       +        test(buf, sizeof(buf), "&#65", -1, "", -1);
       +        test(buf, sizeof(buf), "&", -1, "", -1);
       +        test(buf, sizeof(buf), "&#", -1, "", -1);
       +        test(buf, sizeof(buf), "&#x", -1, "", -1);
       +
       +        /* just in range (limit) */
       +        test(buf, sizeof(buf), "&#x10ffff;", 4, "\xf4\x8f\xbf\xbf", 4);
       +        test(buf, sizeof(buf), "&#1114111;", 4, "\xf4\x8f\xbf\xbf", 4);
       +        /* outside range (range + 1) */
       +        test(buf, sizeof(buf), "&#x110000;", -1, "", -1);
       +        test(buf, sizeof(buf), "&#1114112;", -1, "", -1);
       +
       +        /* 2 bytes */
       +        test(buf, sizeof(buf), "&#x0370;", 2, "\xcd\xb0", 2);
       +        test(buf, sizeof(buf), "&#x370;", 2, "\xcd\xb0", 2);
       +        test(buf, sizeof(buf), "&#x00000370;", 2, "\xcd\xb0", 2);
       +        /* 3 bytes */
       +        test(buf, sizeof(buf), "&#x169b;", 3, "\xe1\x9a\x9b", 3);
       +        test(buf, sizeof(buf), "&#x169B;", 3, "\xe1\x9a\x9b", 3);
       +        test(buf, sizeof(buf), "&#x0169b;", 3, "\xe1\x9a\x9b", 3);
       +        test(buf, sizeof(buf), "&#x00169b;", 3, "\xe1\x9a\x9b", 3);
       +        /* 4 bytes */
       +        test(buf, sizeof(buf), "&#x10300;", 4, "\xf0\x90\x8c\x80", 4);
       +        test(buf, sizeof(buf), "&#x010300;", 4, "\xf0\x90\x8c\x80", 4);
       +        test(buf, sizeof(buf), "&#x0010300;", 4, "\xf0\x90\x8c\x80", 4);
       +        test(buf, sizeof(buf), "&#x1faf0;", 4, "\xf0\x9f\xab\xb0", 4);
       +        test(buf, sizeof(buf), "&#x1fAf0;", 4, "\xf0\x9f\xab\xb0", 4);
       +
       +        /* --- */
       +
       +        /* does not start with "&" */
       +        test(buf, sizeof(buf), " &amp;", -1, "", -1);
       +        test(buf, sizeof(buf), "#65;", -1, "", -1);
       +        test(buf, sizeof(buf), "#x65;", -1, "", -1);
       +
       +        /* --- */
       +
       +        /* test buffer size checks */
       +        /* named entities must have bufsiz >= 2 */
       +        test(buf, 0, "&amp;", -1, "", -1);
       +        test(buf, 1, "&amp;", -1, "", -1);
       +        test(buf, 2, "&amp;", 1, "&", 1);
       +
       +        /* numeric entities must have bufsiz >= 5 */
       +        test(buf, 0, "&#65;", -1, "", -1);
       +        test(buf, 1, "&#65;", -1, "", -1);
       +        test(buf, 4, "&#65;", -1, "", -1);
       +        test(buf, 5, "&#65;", 1, "A", 1);
       +
       +        printf("%s (%d tested, %d OK, %d failed)\n",
       +                failed == 0 ? "OK" : "FAILED", count, ok, failed);
       +
       +        return failed != 0;
       +}