xref: /freebsd/contrib/expat/tests/misc_tests.c (revision fe9278888fd4414abe2d922e469cf608005f4c65)
14543ef51SXin LI /* Tests in the "miscellaneous" test case for the Expat test suite
24543ef51SXin LI                             __  __            _
34543ef51SXin LI                          ___\ \/ /_ __   __ _| |_
44543ef51SXin LI                         / _ \\  /| '_ \ / _` | __|
54543ef51SXin LI                        |  __//  \| |_) | (_| | |_
64543ef51SXin LI                         \___/_/\_\ .__/ \__,_|\__|
74543ef51SXin LI                                  |_| XML parser
84543ef51SXin LI 
94543ef51SXin LI    Copyright (c) 2001-2006 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
104543ef51SXin LI    Copyright (c) 2003      Greg Stein <gstein@users.sourceforge.net>
114543ef51SXin LI    Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
124543ef51SXin LI    Copyright (c) 2005-2012 Karl Waclawek <karl@waclawek.net>
13*fe927888SPhilip Paeps    Copyright (c) 2016-2025 Sebastian Pipping <sebastian@pipping.org>
144543ef51SXin LI    Copyright (c) 2017-2022 Rhodri James <rhodri@wildebeest.org.uk>
154543ef51SXin LI    Copyright (c) 2017      Joe Orton <jorton@redhat.com>
164543ef51SXin LI    Copyright (c) 2017      José Gutiérrez de la Concha <jose@zeroc.com>
174543ef51SXin LI    Copyright (c) 2018      Marco Maggi <marco.maggi-ipsu@poste.it>
184543ef51SXin LI    Copyright (c) 2019      David Loffredo <loffredo@steptools.com>
194543ef51SXin LI    Copyright (c) 2020      Tim Gates <tim.gates@iress.com>
204543ef51SXin LI    Copyright (c) 2021      Donghee Na <donghee.na@python.org>
214543ef51SXin LI    Copyright (c) 2023      Sony Corporation / Snild Dolkow <snild@sony.com>
224543ef51SXin LI    Licensed under the MIT license:
234543ef51SXin LI 
244543ef51SXin LI    Permission is  hereby granted,  free of charge,  to any  person obtaining
254543ef51SXin LI    a  copy  of  this  software   and  associated  documentation  files  (the
264543ef51SXin LI    "Software"),  to  deal in  the  Software  without restriction,  including
274543ef51SXin LI    without  limitation the  rights  to use,  copy,  modify, merge,  publish,
284543ef51SXin LI    distribute, sublicense, and/or sell copies of the Software, and to permit
294543ef51SXin LI    persons  to whom  the Software  is  furnished to  do so,  subject to  the
304543ef51SXin LI    following conditions:
314543ef51SXin LI 
324543ef51SXin LI    The above copyright  notice and this permission notice  shall be included
334543ef51SXin LI    in all copies or substantial portions of the Software.
344543ef51SXin LI 
354543ef51SXin LI    THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT  WARRANTY  OF  ANY  KIND,
364543ef51SXin LI    EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT LIMITED  TO  THE WARRANTIES  OF
374543ef51SXin LI    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
384543ef51SXin LI    NO EVENT SHALL THE AUTHORS OR  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
394543ef51SXin LI    DAMAGES OR  OTHER LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT,  TORT OR
404543ef51SXin LI    OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
414543ef51SXin LI    USE OR OTHER DEALINGS IN THE SOFTWARE.
424543ef51SXin LI */
434543ef51SXin LI 
444543ef51SXin LI #if defined(NDEBUG)
454543ef51SXin LI #  undef NDEBUG /* because test suite relies on assert(...) at the moment */
464543ef51SXin LI #endif
474543ef51SXin LI 
484543ef51SXin LI #include <assert.h>
494543ef51SXin LI #include <string.h>
504543ef51SXin LI 
514543ef51SXin LI #include "expat_config.h"
524543ef51SXin LI 
534543ef51SXin LI #include "expat.h"
544543ef51SXin LI #include "internal.h"
554543ef51SXin LI #include "minicheck.h"
564543ef51SXin LI #include "memcheck.h"
574543ef51SXin LI #include "common.h"
584543ef51SXin LI #include "ascii.h" /* for ASCII_xxx */
594543ef51SXin LI #include "handlers.h"
604543ef51SXin LI #include "misc_tests.h"
614543ef51SXin LI 
62*fe927888SPhilip Paeps void XMLCALL accumulate_characters_ext_handler(void *userData,
63*fe927888SPhilip Paeps                                                const XML_Char *s, int len);
64*fe927888SPhilip Paeps 
654543ef51SXin LI /* Test that a failure to allocate the parser structure fails gracefully */
START_TEST(test_misc_alloc_create_parser)664543ef51SXin LI START_TEST(test_misc_alloc_create_parser) {
674543ef51SXin LI   XML_Memory_Handling_Suite memsuite = {duff_allocator, realloc, free};
684543ef51SXin LI   unsigned int i;
694543ef51SXin LI   const unsigned int max_alloc_count = 10;
704543ef51SXin LI 
714543ef51SXin LI   /* Something this simple shouldn't need more than 10 allocations */
724543ef51SXin LI   for (i = 0; i < max_alloc_count; i++) {
734543ef51SXin LI     g_allocation_count = i;
744543ef51SXin LI     g_parser = XML_ParserCreate_MM(NULL, &memsuite, NULL);
754543ef51SXin LI     if (g_parser != NULL)
764543ef51SXin LI       break;
774543ef51SXin LI   }
784543ef51SXin LI   if (i == 0)
794543ef51SXin LI     fail("Parser unexpectedly ignored failing allocator");
804543ef51SXin LI   else if (i == max_alloc_count)
814543ef51SXin LI     fail("Parser not created with max allocation count");
824543ef51SXin LI }
834543ef51SXin LI END_TEST
844543ef51SXin LI 
854543ef51SXin LI /* Test memory allocation failures for a parser with an encoding */
START_TEST(test_misc_alloc_create_parser_with_encoding)864543ef51SXin LI START_TEST(test_misc_alloc_create_parser_with_encoding) {
874543ef51SXin LI   XML_Memory_Handling_Suite memsuite = {duff_allocator, realloc, free};
884543ef51SXin LI   unsigned int i;
894543ef51SXin LI   const unsigned int max_alloc_count = 10;
904543ef51SXin LI 
914543ef51SXin LI   /* Try several levels of allocation */
924543ef51SXin LI   for (i = 0; i < max_alloc_count; i++) {
934543ef51SXin LI     g_allocation_count = i;
944543ef51SXin LI     g_parser = XML_ParserCreate_MM(XCS("us-ascii"), &memsuite, NULL);
954543ef51SXin LI     if (g_parser != NULL)
964543ef51SXin LI       break;
974543ef51SXin LI   }
984543ef51SXin LI   if (i == 0)
994543ef51SXin LI     fail("Parser ignored failing allocator");
1004543ef51SXin LI   else if (i == max_alloc_count)
1014543ef51SXin LI     fail("Parser not created with max allocation count");
1024543ef51SXin LI }
1034543ef51SXin LI END_TEST
1044543ef51SXin LI 
1054543ef51SXin LI /* Test that freeing a NULL parser doesn't cause an explosion.
1064543ef51SXin LI  * (Not actually tested anywhere else)
1074543ef51SXin LI  */
START_TEST(test_misc_null_parser)1084543ef51SXin LI START_TEST(test_misc_null_parser) {
1094543ef51SXin LI   XML_ParserFree(NULL);
1104543ef51SXin LI }
1114543ef51SXin LI END_TEST
1124543ef51SXin LI 
1134543ef51SXin LI #if defined(__has_feature)
1144543ef51SXin LI #  if __has_feature(undefined_behavior_sanitizer)
1154543ef51SXin LI #    define EXPAT_TESTS_UBSAN 1
1164543ef51SXin LI #  else
1174543ef51SXin LI #    define EXPAT_TESTS_UBSAN 0
1184543ef51SXin LI #  endif
1194543ef51SXin LI #else
1204543ef51SXin LI #  define EXPAT_TESTS_UBSAN 0
1214543ef51SXin LI #endif
1224543ef51SXin LI 
1234543ef51SXin LI /* Test that XML_ErrorString rejects out-of-range codes */
START_TEST(test_misc_error_string)1244543ef51SXin LI START_TEST(test_misc_error_string) {
1254543ef51SXin LI #if ! EXPAT_TESTS_UBSAN // because this would trigger UBSan
1264543ef51SXin LI   union {
1274543ef51SXin LI     enum XML_Error xml_error;
1284543ef51SXin LI     int integer;
1294543ef51SXin LI   } trickery;
1304543ef51SXin LI 
1314543ef51SXin LI   assert_true(sizeof(enum XML_Error) == sizeof(int)); // self-test
1324543ef51SXin LI 
1334543ef51SXin LI   trickery.integer = -1;
1344543ef51SXin LI   if (XML_ErrorString(trickery.xml_error) != NULL)
1354543ef51SXin LI     fail("Negative error code not rejected");
1364543ef51SXin LI 
1374543ef51SXin LI   trickery.integer = 100;
1384543ef51SXin LI   if (XML_ErrorString(trickery.xml_error) != NULL)
1394543ef51SXin LI     fail("Large error code not rejected");
1404543ef51SXin LI #endif
1414543ef51SXin LI }
1424543ef51SXin LI END_TEST
1434543ef51SXin LI 
1444543ef51SXin LI /* Test the version information is consistent */
1454543ef51SXin LI 
1464543ef51SXin LI /* Since we are working in XML_LChars (potentially 16-bits), we
1474543ef51SXin LI  * can't use the standard C library functions for character
1484543ef51SXin LI  * manipulation and have to roll our own.
1494543ef51SXin LI  */
1504543ef51SXin LI static int
parse_version(const XML_LChar * version_text,XML_Expat_Version * version_struct)1514543ef51SXin LI parse_version(const XML_LChar *version_text,
1524543ef51SXin LI               XML_Expat_Version *version_struct) {
1534543ef51SXin LI   if (! version_text)
1544543ef51SXin LI     return XML_FALSE;
1554543ef51SXin LI 
1564543ef51SXin LI   while (*version_text != 0x00) {
1574543ef51SXin LI     if (*version_text >= ASCII_0 && *version_text <= ASCII_9)
1584543ef51SXin LI       break;
1594543ef51SXin LI     version_text++;
1604543ef51SXin LI   }
1614543ef51SXin LI   if (*version_text == 0x00)
1624543ef51SXin LI     return XML_FALSE;
1634543ef51SXin LI 
1644543ef51SXin LI   /* version_struct->major = strtoul(version_text, 10, &version_text) */
1654543ef51SXin LI   version_struct->major = 0;
1664543ef51SXin LI   while (*version_text >= ASCII_0 && *version_text <= ASCII_9) {
1674543ef51SXin LI     version_struct->major
1684543ef51SXin LI         = 10 * version_struct->major + (*version_text++ - ASCII_0);
1694543ef51SXin LI   }
1704543ef51SXin LI   if (*version_text++ != ASCII_PERIOD)
1714543ef51SXin LI     return XML_FALSE;
1724543ef51SXin LI 
1734543ef51SXin LI   /* Now for the minor version number */
1744543ef51SXin LI   version_struct->minor = 0;
1754543ef51SXin LI   while (*version_text >= ASCII_0 && *version_text <= ASCII_9) {
1764543ef51SXin LI     version_struct->minor
1774543ef51SXin LI         = 10 * version_struct->minor + (*version_text++ - ASCII_0);
1784543ef51SXin LI   }
1794543ef51SXin LI   if (*version_text++ != ASCII_PERIOD)
1804543ef51SXin LI     return XML_FALSE;
1814543ef51SXin LI 
1824543ef51SXin LI   /* Finally the micro version number */
1834543ef51SXin LI   version_struct->micro = 0;
1844543ef51SXin LI   while (*version_text >= ASCII_0 && *version_text <= ASCII_9) {
1854543ef51SXin LI     version_struct->micro
1864543ef51SXin LI         = 10 * version_struct->micro + (*version_text++ - ASCII_0);
1874543ef51SXin LI   }
1884543ef51SXin LI   if (*version_text != 0x00)
1894543ef51SXin LI     return XML_FALSE;
1904543ef51SXin LI   return XML_TRUE;
1914543ef51SXin LI }
1924543ef51SXin LI 
1934543ef51SXin LI static int
versions_equal(const XML_Expat_Version * first,const XML_Expat_Version * second)1944543ef51SXin LI versions_equal(const XML_Expat_Version *first,
1954543ef51SXin LI                const XML_Expat_Version *second) {
1964543ef51SXin LI   return (first->major == second->major && first->minor == second->minor
1974543ef51SXin LI           && first->micro == second->micro);
1984543ef51SXin LI }
1994543ef51SXin LI 
START_TEST(test_misc_version)2004543ef51SXin LI START_TEST(test_misc_version) {
2014543ef51SXin LI   XML_Expat_Version read_version = XML_ExpatVersionInfo();
2024543ef51SXin LI   /* Silence compiler warning with the following assignment */
2034543ef51SXin LI   XML_Expat_Version parsed_version = {0, 0, 0};
2044543ef51SXin LI   const XML_LChar *version_text = XML_ExpatVersion();
2054543ef51SXin LI 
2064543ef51SXin LI   if (version_text == NULL)
2074543ef51SXin LI     fail("Could not obtain version text");
2084543ef51SXin LI   assert(version_text != NULL);
2094543ef51SXin LI   if (! parse_version(version_text, &parsed_version))
2104543ef51SXin LI     fail("Unable to parse version text");
2114543ef51SXin LI   if (! versions_equal(&read_version, &parsed_version))
2124543ef51SXin LI     fail("Version mismatch");
2134543ef51SXin LI 
214*fe927888SPhilip Paeps   if (xcstrcmp(version_text, XCS("expat_2.7.1"))) /* needs bump on releases */
2154543ef51SXin LI     fail("XML_*_VERSION in expat.h out of sync?\n");
2164543ef51SXin LI }
2174543ef51SXin LI END_TEST
2184543ef51SXin LI 
2194543ef51SXin LI /* Test feature information */
START_TEST(test_misc_features)2204543ef51SXin LI START_TEST(test_misc_features) {
2214543ef51SXin LI   const XML_Feature *features = XML_GetFeatureList();
2224543ef51SXin LI 
2234543ef51SXin LI   /* Prevent problems with double-freeing parsers */
2244543ef51SXin LI   g_parser = NULL;
2254543ef51SXin LI   if (features == NULL) {
2264543ef51SXin LI     fail("Failed to get feature information");
2274543ef51SXin LI   } else {
2284543ef51SXin LI     /* Loop through the features checking what we can */
2294543ef51SXin LI     while (features->feature != XML_FEATURE_END) {
2304543ef51SXin LI       switch (features->feature) {
2314543ef51SXin LI       case XML_FEATURE_SIZEOF_XML_CHAR:
2324543ef51SXin LI         if (features->value != sizeof(XML_Char))
2334543ef51SXin LI           fail("Incorrect size of XML_Char");
2344543ef51SXin LI         break;
2354543ef51SXin LI       case XML_FEATURE_SIZEOF_XML_LCHAR:
2364543ef51SXin LI         if (features->value != sizeof(XML_LChar))
2374543ef51SXin LI           fail("Incorrect size of XML_LChar");
2384543ef51SXin LI         break;
2394543ef51SXin LI       default:
2404543ef51SXin LI         break;
2414543ef51SXin LI       }
2424543ef51SXin LI       features++;
2434543ef51SXin LI     }
2444543ef51SXin LI   }
2454543ef51SXin LI }
2464543ef51SXin LI END_TEST
2474543ef51SXin LI 
2484543ef51SXin LI /* Regression test for GitHub Issue #17: memory leak parsing attribute
2494543ef51SXin LI  * values with mixed bound and unbound namespaces.
2504543ef51SXin LI  */
START_TEST(test_misc_attribute_leak)2514543ef51SXin LI START_TEST(test_misc_attribute_leak) {
2524543ef51SXin LI   const char *text = "<D xmlns:L=\"D\" l:a='' L:a=''/>";
2534543ef51SXin LI   XML_Memory_Handling_Suite memsuite
2544543ef51SXin LI       = {tracking_malloc, tracking_realloc, tracking_free};
2554543ef51SXin LI 
2564543ef51SXin LI   g_parser = XML_ParserCreate_MM(XCS("UTF-8"), &memsuite, XCS("\n"));
2574543ef51SXin LI   expect_failure(text, XML_ERROR_UNBOUND_PREFIX, "Unbound prefixes not found");
2584543ef51SXin LI   XML_ParserFree(g_parser);
2594543ef51SXin LI   /* Prevent the teardown trying to double free */
2604543ef51SXin LI   g_parser = NULL;
2614543ef51SXin LI 
2624543ef51SXin LI   if (! tracking_report())
2634543ef51SXin LI     fail("Memory leak found");
2644543ef51SXin LI }
2654543ef51SXin LI END_TEST
2664543ef51SXin LI 
2674543ef51SXin LI /* Test parser created for UTF-16LE is successful */
START_TEST(test_misc_utf16le)2684543ef51SXin LI START_TEST(test_misc_utf16le) {
2694543ef51SXin LI   const char text[] =
2704543ef51SXin LI       /* <?xml version='1.0'?><q>Hi</q> */
2714543ef51SXin LI       "<\0?\0x\0m\0l\0 \0"
2724543ef51SXin LI       "v\0e\0r\0s\0i\0o\0n\0=\0'\0\x31\0.\0\x30\0'\0?\0>\0"
2734543ef51SXin LI       "<\0q\0>\0H\0i\0<\0/\0q\0>\0";
2744543ef51SXin LI   const XML_Char *expected = XCS("Hi");
2754543ef51SXin LI   CharData storage;
2764543ef51SXin LI 
2774543ef51SXin LI   g_parser = XML_ParserCreate(XCS("UTF-16LE"));
2784543ef51SXin LI   if (g_parser == NULL)
2794543ef51SXin LI     fail("Parser not created");
2804543ef51SXin LI 
2814543ef51SXin LI   CharData_Init(&storage);
2824543ef51SXin LI   XML_SetUserData(g_parser, &storage);
2834543ef51SXin LI   XML_SetCharacterDataHandler(g_parser, accumulate_characters);
2844543ef51SXin LI   if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)sizeof(text) - 1, XML_TRUE)
2854543ef51SXin LI       == XML_STATUS_ERROR)
2864543ef51SXin LI     xml_failure(g_parser);
2874543ef51SXin LI   CharData_CheckXMLChars(&storage, expected);
2884543ef51SXin LI }
2894543ef51SXin LI END_TEST
2904543ef51SXin LI 
START_TEST(test_misc_stop_during_end_handler_issue_240_1)2914543ef51SXin LI START_TEST(test_misc_stop_during_end_handler_issue_240_1) {
2924543ef51SXin LI   XML_Parser parser;
2934543ef51SXin LI   DataIssue240 *mydata;
2944543ef51SXin LI   enum XML_Status result;
2954543ef51SXin LI   const char *const doc1 = "<doc><e1/><e><foo/></e></doc>";
2964543ef51SXin LI 
2974543ef51SXin LI   parser = XML_ParserCreate(NULL);
2984543ef51SXin LI   XML_SetElementHandler(parser, start_element_issue_240, end_element_issue_240);
2994543ef51SXin LI   mydata = (DataIssue240 *)malloc(sizeof(DataIssue240));
300*fe927888SPhilip Paeps   assert_true(mydata != NULL);
3014543ef51SXin LI   mydata->parser = parser;
3024543ef51SXin LI   mydata->deep = 0;
3034543ef51SXin LI   XML_SetUserData(parser, mydata);
3044543ef51SXin LI 
3054543ef51SXin LI   result = _XML_Parse_SINGLE_BYTES(parser, doc1, (int)strlen(doc1), 1);
3064543ef51SXin LI   XML_ParserFree(parser);
3074543ef51SXin LI   free(mydata);
3084543ef51SXin LI   if (result != XML_STATUS_ERROR)
3094543ef51SXin LI     fail("Stopping the parser did not work as expected");
3104543ef51SXin LI }
3114543ef51SXin LI END_TEST
3124543ef51SXin LI 
START_TEST(test_misc_stop_during_end_handler_issue_240_2)3134543ef51SXin LI START_TEST(test_misc_stop_during_end_handler_issue_240_2) {
3144543ef51SXin LI   XML_Parser parser;
3154543ef51SXin LI   DataIssue240 *mydata;
3164543ef51SXin LI   enum XML_Status result;
3174543ef51SXin LI   const char *const doc2 = "<doc><elem/></doc>";
3184543ef51SXin LI 
3194543ef51SXin LI   parser = XML_ParserCreate(NULL);
3204543ef51SXin LI   XML_SetElementHandler(parser, start_element_issue_240, end_element_issue_240);
3214543ef51SXin LI   mydata = (DataIssue240 *)malloc(sizeof(DataIssue240));
322*fe927888SPhilip Paeps   assert_true(mydata != NULL);
3234543ef51SXin LI   mydata->parser = parser;
3244543ef51SXin LI   mydata->deep = 0;
3254543ef51SXin LI   XML_SetUserData(parser, mydata);
3264543ef51SXin LI 
3274543ef51SXin LI   result = _XML_Parse_SINGLE_BYTES(parser, doc2, (int)strlen(doc2), 1);
3284543ef51SXin LI   XML_ParserFree(parser);
3294543ef51SXin LI   free(mydata);
3304543ef51SXin LI   if (result != XML_STATUS_ERROR)
3314543ef51SXin LI     fail("Stopping the parser did not work as expected");
3324543ef51SXin LI }
3334543ef51SXin LI END_TEST
3344543ef51SXin LI 
START_TEST(test_misc_deny_internal_entity_closing_doctype_issue_317)3354543ef51SXin LI START_TEST(test_misc_deny_internal_entity_closing_doctype_issue_317) {
336*fe927888SPhilip Paeps   const char *const inputOne
337*fe927888SPhilip Paeps       = "<!DOCTYPE d [\n"
338*fe927888SPhilip Paeps         "<!ENTITY % element_d '<!ELEMENT d (#PCDATA)*>'>\n"
339*fe927888SPhilip Paeps         "%element_d;\n"
3404543ef51SXin LI         "<!ENTITY % e ']><d/>'>\n"
3414543ef51SXin LI         "\n"
3424543ef51SXin LI         "%e;";
343908f215eSXin LI   const char *const inputTwo
344908f215eSXin LI       = "<!DOCTYPE d [\n"
345*fe927888SPhilip Paeps         "<!ENTITY % element_d '<!ELEMENT d (#PCDATA)*>'>\n"
346*fe927888SPhilip Paeps         "%element_d;\n"
347908f215eSXin LI         "<!ENTITY % e1 ']><d/>'><!ENTITY % e2 '&#37;e1;'>\n"
3484543ef51SXin LI         "\n"
3494543ef51SXin LI         "%e2;";
350*fe927888SPhilip Paeps   const char *const inputThree
351*fe927888SPhilip Paeps       = "<!DOCTYPE d [\n"
352*fe927888SPhilip Paeps         "<!ENTITY % element_d '<!ELEMENT d (#PCDATA)*>'>\n"
353*fe927888SPhilip Paeps         "%element_d;\n"
3544543ef51SXin LI         "<!ENTITY % e ']><d'>\n"
3554543ef51SXin LI         "\n"
356908f215eSXin LI         "%e;/>";
357*fe927888SPhilip Paeps   const char *const inputIssue317
358*fe927888SPhilip Paeps       = "<!DOCTYPE doc [\n"
359*fe927888SPhilip Paeps         "<!ENTITY % element_doc '<!ELEMENT doc (#PCDATA)*>'>\n"
360*fe927888SPhilip Paeps         "%element_doc;\n"
3614543ef51SXin LI         "<!ENTITY % foo ']>\n"
3624543ef51SXin LI         "<doc>Hell<oc (#PCDATA)*>'>\n"
3634543ef51SXin LI         "%foo;\n"
3644543ef51SXin LI         "]>\n"
3654543ef51SXin LI         "<doc>Hello, world</dVc>";
3664543ef51SXin LI 
3674543ef51SXin LI   const char *const inputs[] = {inputOne, inputTwo, inputThree, inputIssue317};
368*fe927888SPhilip Paeps   const XML_Bool suspendOrNot[] = {XML_FALSE, XML_TRUE};
3694543ef51SXin LI   size_t inputIndex = 0;
3704543ef51SXin LI 
3714543ef51SXin LI   for (; inputIndex < sizeof(inputs) / sizeof(inputs[0]); inputIndex++) {
372*fe927888SPhilip Paeps     for (size_t suspendOrNotIndex = 0;
373*fe927888SPhilip Paeps          suspendOrNotIndex < sizeof(suspendOrNot) / sizeof(suspendOrNot[0]);
374*fe927888SPhilip Paeps          suspendOrNotIndex++) {
375*fe927888SPhilip Paeps       const char *const input = inputs[inputIndex];
376*fe927888SPhilip Paeps       const XML_Bool suspend = suspendOrNot[suspendOrNotIndex];
377*fe927888SPhilip Paeps       if (suspend && (g_chunkSize > 0)) {
378*fe927888SPhilip Paeps         // We cannot use _XML_Parse_SINGLE_BYTES below due to suspension, and
379*fe927888SPhilip Paeps         // so chunk sizes >0 would only repeat the very same test
380*fe927888SPhilip Paeps         // due to use of plain XML_Parse; we are saving upon that runtime:
381*fe927888SPhilip Paeps         return;
382*fe927888SPhilip Paeps       }
383*fe927888SPhilip Paeps 
384*fe927888SPhilip Paeps       set_subtest("[input=%d suspend=%s] %s", (int)inputIndex,
385*fe927888SPhilip Paeps                   suspend ? "true" : "false", input);
3864543ef51SXin LI       XML_Parser parser;
3874543ef51SXin LI       enum XML_Status parseResult;
3884543ef51SXin LI       int setParamEntityResult;
3894543ef51SXin LI       XML_Size lineNumber;
3904543ef51SXin LI       XML_Size columnNumber;
3914543ef51SXin LI 
3924543ef51SXin LI       parser = XML_ParserCreate(NULL);
3934543ef51SXin LI       setParamEntityResult
3944543ef51SXin LI           = XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
3954543ef51SXin LI       if (setParamEntityResult != 1)
3964543ef51SXin LI         fail("Failed to set XML_PARAM_ENTITY_PARSING_ALWAYS.");
3974543ef51SXin LI 
398*fe927888SPhilip Paeps       if (suspend) {
399*fe927888SPhilip Paeps         XML_SetUserData(parser, parser);
400*fe927888SPhilip Paeps         XML_SetElementDeclHandler(parser, suspend_after_element_declaration);
401*fe927888SPhilip Paeps       }
402*fe927888SPhilip Paeps 
403*fe927888SPhilip Paeps       if (suspend) {
404*fe927888SPhilip Paeps         // can't use SINGLE_BYTES here, because it'll return early on
405*fe927888SPhilip Paeps         // suspension, and we won't know exactly how much input we actually
406*fe927888SPhilip Paeps         // managed to give Expat.
407*fe927888SPhilip Paeps         parseResult = XML_Parse(parser, input, (int)strlen(input), 0);
408*fe927888SPhilip Paeps 
409*fe927888SPhilip Paeps         while (parseResult == XML_STATUS_SUSPENDED) {
410*fe927888SPhilip Paeps           parseResult = XML_ResumeParser(parser);
411*fe927888SPhilip Paeps         }
412*fe927888SPhilip Paeps 
413*fe927888SPhilip Paeps         if (parseResult != XML_STATUS_ERROR) {
414*fe927888SPhilip Paeps           // can't use SINGLE_BYTES here, because it'll return early on
415*fe927888SPhilip Paeps           // suspension, and we won't know exactly how much input we actually
416*fe927888SPhilip Paeps           // managed to give Expat.
417*fe927888SPhilip Paeps           parseResult = XML_Parse(parser, "", 0, 1);
418*fe927888SPhilip Paeps         }
419*fe927888SPhilip Paeps 
420*fe927888SPhilip Paeps         while (parseResult == XML_STATUS_SUSPENDED) {
421*fe927888SPhilip Paeps           parseResult = XML_ResumeParser(parser);
422*fe927888SPhilip Paeps         }
423*fe927888SPhilip Paeps       } else {
424*fe927888SPhilip Paeps         parseResult
425*fe927888SPhilip Paeps             = _XML_Parse_SINGLE_BYTES(parser, input, (int)strlen(input), 0);
426*fe927888SPhilip Paeps 
4274543ef51SXin LI         if (parseResult != XML_STATUS_ERROR) {
4284543ef51SXin LI           parseResult = _XML_Parse_SINGLE_BYTES(parser, "", 0, 1);
429*fe927888SPhilip Paeps         }
430*fe927888SPhilip Paeps       }
431*fe927888SPhilip Paeps 
4324543ef51SXin LI       if (parseResult != XML_STATUS_ERROR) {
4334543ef51SXin LI         fail("Parsing was expected to fail but succeeded.");
4344543ef51SXin LI       }
4354543ef51SXin LI 
4364543ef51SXin LI       if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_TOKEN)
4374543ef51SXin LI         fail("Error code does not match XML_ERROR_INVALID_TOKEN");
4384543ef51SXin LI 
4394543ef51SXin LI       lineNumber = XML_GetCurrentLineNumber(parser);
440*fe927888SPhilip Paeps       if (lineNumber != 6)
4414543ef51SXin LI         fail("XML_GetCurrentLineNumber does not work as expected.");
4424543ef51SXin LI 
4434543ef51SXin LI       columnNumber = XML_GetCurrentColumnNumber(parser);
4444543ef51SXin LI       if (columnNumber != 0)
4454543ef51SXin LI         fail("XML_GetCurrentColumnNumber does not work as expected.");
4464543ef51SXin LI 
4474543ef51SXin LI       XML_ParserFree(parser);
4484543ef51SXin LI     }
4494543ef51SXin LI   }
450*fe927888SPhilip Paeps }
4514543ef51SXin LI END_TEST
4524543ef51SXin LI 
START_TEST(test_misc_tag_mismatch_reset_leak)4534543ef51SXin LI START_TEST(test_misc_tag_mismatch_reset_leak) {
4544543ef51SXin LI #ifdef XML_NS
4554543ef51SXin LI   const char *const text = "<open xmlns='https://namespace1.test'></close>";
4564543ef51SXin LI   XML_Parser parser = XML_ParserCreateNS(NULL, XCS('\n'));
4574543ef51SXin LI 
4584543ef51SXin LI   if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE)
4594543ef51SXin LI       != XML_STATUS_ERROR)
4604543ef51SXin LI     fail("Call to parse was expected to fail");
4614543ef51SXin LI   if (XML_GetErrorCode(parser) != XML_ERROR_TAG_MISMATCH)
4624543ef51SXin LI     fail("Call to parse was expected to fail from a closing tag mismatch");
4634543ef51SXin LI 
4644543ef51SXin LI   XML_ParserReset(parser, NULL);
4654543ef51SXin LI 
4664543ef51SXin LI   if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE)
4674543ef51SXin LI       != XML_STATUS_ERROR)
4684543ef51SXin LI     fail("Call to parse was expected to fail");
4694543ef51SXin LI   if (XML_GetErrorCode(parser) != XML_ERROR_TAG_MISMATCH)
4704543ef51SXin LI     fail("Call to parse was expected to fail from a closing tag mismatch");
4714543ef51SXin LI 
4724543ef51SXin LI   XML_ParserFree(parser);
4734543ef51SXin LI #endif
4744543ef51SXin LI }
4754543ef51SXin LI END_TEST
4764543ef51SXin LI 
START_TEST(test_misc_create_external_entity_parser_with_null_context)4774543ef51SXin LI START_TEST(test_misc_create_external_entity_parser_with_null_context) {
4784543ef51SXin LI   // With XML_DTD undefined, the only supported case of external entities
4794543ef51SXin LI   // is pattern "<!ENTITY entity123 SYSTEM 'filename123'>". A NULL context
4804543ef51SXin LI   // was causing a segfault through a null pointer dereference in function
4814543ef51SXin LI   // setContext, previously.
4824543ef51SXin LI   XML_Parser parser = XML_ParserCreate(NULL);
4834543ef51SXin LI   XML_Parser ext_parser = XML_ExternalEntityParserCreate(parser, NULL, NULL);
4844543ef51SXin LI #ifdef XML_DTD
4854543ef51SXin LI   assert_true(ext_parser != NULL);
4864543ef51SXin LI   XML_ParserFree(ext_parser);
4874543ef51SXin LI #else
4884543ef51SXin LI   assert_true(ext_parser == NULL);
4894543ef51SXin LI #endif /* XML_DTD */
4904543ef51SXin LI   XML_ParserFree(parser);
4914543ef51SXin LI }
4924543ef51SXin LI END_TEST
4934543ef51SXin LI 
START_TEST(test_misc_general_entities_support)4944543ef51SXin LI START_TEST(test_misc_general_entities_support) {
4954543ef51SXin LI   const char *const doc
4964543ef51SXin LI       = "<!DOCTYPE r [\n"
4974543ef51SXin LI         "<!ENTITY e1 'v1'>\n"
4984543ef51SXin LI         "<!ENTITY e2 SYSTEM 'v2'>\n"
4994543ef51SXin LI         "]>\n"
5004543ef51SXin LI         "<r a1='[&e1;]'>[&e1;][&e2;][&amp;&apos;&gt;&lt;&quot;]</r>";
5014543ef51SXin LI 
5024543ef51SXin LI   CharData storage;
5034543ef51SXin LI   CharData_Init(&storage);
5044543ef51SXin LI 
5054543ef51SXin LI   XML_Parser parser = XML_ParserCreate(NULL);
5064543ef51SXin LI   XML_SetUserData(parser, &storage);
5074543ef51SXin LI   XML_SetStartElementHandler(parser, accumulate_start_element);
5084543ef51SXin LI   XML_SetExternalEntityRefHandler(parser,
5094543ef51SXin LI                                   external_entity_failer__if_not_xml_ge);
5104543ef51SXin LI   XML_SetEntityDeclHandler(parser, accumulate_entity_decl);
511908f215eSXin LI   XML_SetCharacterDataHandler(parser, accumulate_characters);
5124543ef51SXin LI 
5134543ef51SXin LI   if (_XML_Parse_SINGLE_BYTES(parser, doc, (int)strlen(doc), XML_TRUE)
5144543ef51SXin LI       != XML_STATUS_OK) {
5154543ef51SXin LI     xml_failure(parser);
5164543ef51SXin LI   }
5174543ef51SXin LI 
5184543ef51SXin LI   XML_ParserFree(parser);
5194543ef51SXin LI 
5204543ef51SXin LI   CharData_CheckXMLChars(&storage,
5214543ef51SXin LI   /* clang-format off */
5224543ef51SXin LI #if XML_GE == 1
5234543ef51SXin LI                          XCS("e1=v1\n")
5244543ef51SXin LI                          XCS("e2=(null)\n")
5254543ef51SXin LI                          XCS("(r(a1=[v1]))\n")
5264543ef51SXin LI                          XCS("[v1][][&'><\"]")
5274543ef51SXin LI #else
5284543ef51SXin LI                          XCS("e1=&amp;e1;\n")
5294543ef51SXin LI                          XCS("e2=(null)\n")
5304543ef51SXin LI                          XCS("(r(a1=[&e1;]))\n")
5314543ef51SXin LI                          XCS("[&e1;][&e2;][&'><\"]")
5324543ef51SXin LI #endif
5334543ef51SXin LI   );
5344543ef51SXin LI   /* clang-format on */
5354543ef51SXin LI }
5364543ef51SXin LI END_TEST
5374543ef51SXin LI 
5384543ef51SXin LI static void XMLCALL
resumable_stopping_character_handler(void * userData,const XML_Char * s,int len)5394543ef51SXin LI resumable_stopping_character_handler(void *userData, const XML_Char *s,
5404543ef51SXin LI                                      int len) {
5414543ef51SXin LI   UNUSED_P(s);
5424543ef51SXin LI   UNUSED_P(len);
5434543ef51SXin LI   XML_Parser parser = (XML_Parser)userData;
5444543ef51SXin LI   XML_StopParser(parser, XML_TRUE);
5454543ef51SXin LI }
5464543ef51SXin LI 
5474543ef51SXin LI // NOTE: This test needs active LeakSanitizer to be of actual use
START_TEST(test_misc_char_handler_stop_without_leak)5484543ef51SXin LI START_TEST(test_misc_char_handler_stop_without_leak) {
5494543ef51SXin LI   const char *const data
5504543ef51SXin LI       = "<!DOCTYPE t1[<!ENTITY e1 'angle<'><!ENTITY e2 '&e1;'>]><t1>&e2;";
5514543ef51SXin LI   XML_Parser parser = XML_ParserCreate(NULL);
5524543ef51SXin LI   assert_true(parser != NULL);
5534543ef51SXin LI   XML_SetUserData(parser, parser);
5544543ef51SXin LI   XML_SetCharacterDataHandler(parser, resumable_stopping_character_handler);
5554543ef51SXin LI   _XML_Parse_SINGLE_BYTES(parser, data, (int)strlen(data), XML_FALSE);
5564543ef51SXin LI   XML_ParserFree(parser);
5574543ef51SXin LI }
5584543ef51SXin LI END_TEST
5594543ef51SXin LI 
START_TEST(test_misc_resumeparser_not_crashing)560908f215eSXin LI START_TEST(test_misc_resumeparser_not_crashing) {
561908f215eSXin LI   XML_Parser parser = XML_ParserCreate(NULL);
562908f215eSXin LI   XML_GetBuffer(parser, 1);
563908f215eSXin LI   XML_StopParser(parser, /*resumable=*/XML_TRUE);
564908f215eSXin LI   XML_ResumeParser(parser); // could crash here, previously
565908f215eSXin LI   XML_ParserFree(parser);
566908f215eSXin LI }
567908f215eSXin LI END_TEST
568908f215eSXin LI 
START_TEST(test_misc_stopparser_rejects_unstarted_parser)569908f215eSXin LI START_TEST(test_misc_stopparser_rejects_unstarted_parser) {
570908f215eSXin LI   const XML_Bool cases[] = {XML_TRUE, XML_FALSE};
571908f215eSXin LI   for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) {
572908f215eSXin LI     const XML_Bool resumable = cases[i];
573908f215eSXin LI     XML_Parser parser = XML_ParserCreate(NULL);
574908f215eSXin LI     assert_true(XML_GetErrorCode(parser) == XML_ERROR_NONE);
575908f215eSXin LI     assert_true(XML_StopParser(parser, resumable) == XML_STATUS_ERROR);
576908f215eSXin LI     assert_true(XML_GetErrorCode(parser) == XML_ERROR_NOT_STARTED);
577908f215eSXin LI     XML_ParserFree(parser);
578908f215eSXin LI   }
579908f215eSXin LI }
580908f215eSXin LI END_TEST
581908f215eSXin LI 
582*fe927888SPhilip Paeps /* Adaptation of accumulate_characters that takes ExtHdlrData input to work with
583*fe927888SPhilip Paeps  * test_renter_loop_finite_content below */
584*fe927888SPhilip Paeps void XMLCALL
accumulate_characters_ext_handler(void * userData,const XML_Char * s,int len)585*fe927888SPhilip Paeps accumulate_characters_ext_handler(void *userData, const XML_Char *s, int len) {
586*fe927888SPhilip Paeps   ExtHdlrData *const test_data = (ExtHdlrData *)userData;
587*fe927888SPhilip Paeps   CharData_AppendXMLChars(test_data->storage, s, len);
588*fe927888SPhilip Paeps }
589*fe927888SPhilip Paeps 
590*fe927888SPhilip Paeps /* Test that internalEntityProcessor does not re-enter forever;
591*fe927888SPhilip Paeps  * based on files tests/xmlconf/xmltest/valid/ext-sa/012.{xml,ent} */
START_TEST(test_renter_loop_finite_content)592*fe927888SPhilip Paeps START_TEST(test_renter_loop_finite_content) {
593*fe927888SPhilip Paeps   CharData storage;
594*fe927888SPhilip Paeps   CharData_Init(&storage);
595*fe927888SPhilip Paeps   const char *const text = "<!DOCTYPE doc [\n"
596*fe927888SPhilip Paeps                            "<!ENTITY e1 '&e2;'>\n"
597*fe927888SPhilip Paeps                            "<!ENTITY e2 '&e3;'>\n"
598*fe927888SPhilip Paeps                            "<!ENTITY e3 SYSTEM '012.ent'>\n"
599*fe927888SPhilip Paeps                            "<!ENTITY e4 '&e5;'>\n"
600*fe927888SPhilip Paeps                            "<!ENTITY e5 '(e5)'>\n"
601*fe927888SPhilip Paeps                            "<!ELEMENT doc (#PCDATA)>\n"
602*fe927888SPhilip Paeps                            "]>\n"
603*fe927888SPhilip Paeps                            "<doc>&e1;</doc>\n";
604*fe927888SPhilip Paeps   ExtHdlrData test_data = {"&e4;\n", external_entity_null_loader, &storage};
605*fe927888SPhilip Paeps   const XML_Char *const expected = XCS("(e5)\n");
606*fe927888SPhilip Paeps 
607*fe927888SPhilip Paeps   XML_Parser parser = XML_ParserCreate(NULL);
608*fe927888SPhilip Paeps   assert_true(parser != NULL);
609*fe927888SPhilip Paeps   XML_SetUserData(parser, &test_data);
610*fe927888SPhilip Paeps   XML_SetExternalEntityRefHandler(parser, external_entity_oneshot_loader);
611*fe927888SPhilip Paeps   XML_SetCharacterDataHandler(parser, accumulate_characters_ext_handler);
612*fe927888SPhilip Paeps   if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE)
613*fe927888SPhilip Paeps       == XML_STATUS_ERROR)
614*fe927888SPhilip Paeps     xml_failure(parser);
615*fe927888SPhilip Paeps 
616*fe927888SPhilip Paeps   CharData_CheckXMLChars(&storage, expected);
617*fe927888SPhilip Paeps   XML_ParserFree(parser);
618*fe927888SPhilip Paeps }
619*fe927888SPhilip Paeps END_TEST
620*fe927888SPhilip Paeps 
621*fe927888SPhilip Paeps // Inspired by function XML_OriginalString of Perl's XML::Parser
622*fe927888SPhilip Paeps static char *
dup_original_string(XML_Parser parser)623*fe927888SPhilip Paeps dup_original_string(XML_Parser parser) {
624*fe927888SPhilip Paeps   const int byte_count = XML_GetCurrentByteCount(parser);
625*fe927888SPhilip Paeps 
626*fe927888SPhilip Paeps   assert_true(byte_count >= 0);
627*fe927888SPhilip Paeps 
628*fe927888SPhilip Paeps   int offset = -1;
629*fe927888SPhilip Paeps   int size = -1;
630*fe927888SPhilip Paeps 
631*fe927888SPhilip Paeps   const char *const context = XML_GetInputContext(parser, &offset, &size);
632*fe927888SPhilip Paeps 
633*fe927888SPhilip Paeps #if XML_CONTEXT_BYTES > 0
634*fe927888SPhilip Paeps   assert_true(context != NULL);
635*fe927888SPhilip Paeps   assert_true(offset >= 0);
636*fe927888SPhilip Paeps   assert_true(size >= 0);
637*fe927888SPhilip Paeps   return portable_strndup(context + offset, byte_count);
638*fe927888SPhilip Paeps #else
639*fe927888SPhilip Paeps   assert_true(context == NULL);
640*fe927888SPhilip Paeps   return NULL;
641*fe927888SPhilip Paeps #endif
642*fe927888SPhilip Paeps }
643*fe927888SPhilip Paeps 
644*fe927888SPhilip Paeps static void
on_characters_issue_980(void * userData,const XML_Char * s,int len)645*fe927888SPhilip Paeps on_characters_issue_980(void *userData, const XML_Char *s, int len) {
646*fe927888SPhilip Paeps   (void)s;
647*fe927888SPhilip Paeps   (void)len;
648*fe927888SPhilip Paeps   XML_Parser parser = (XML_Parser)userData;
649*fe927888SPhilip Paeps 
650*fe927888SPhilip Paeps   char *const original_string = dup_original_string(parser);
651*fe927888SPhilip Paeps 
652*fe927888SPhilip Paeps #if XML_CONTEXT_BYTES > 0
653*fe927888SPhilip Paeps   assert_true(original_string != NULL);
654*fe927888SPhilip Paeps   assert_true(strcmp(original_string, "&draft.day;") == 0);
655*fe927888SPhilip Paeps   free(original_string);
656*fe927888SPhilip Paeps #else
657*fe927888SPhilip Paeps   assert_true(original_string == NULL);
658*fe927888SPhilip Paeps #endif
659*fe927888SPhilip Paeps }
660*fe927888SPhilip Paeps 
START_TEST(test_misc_expected_event_ptr_issue_980)661*fe927888SPhilip Paeps START_TEST(test_misc_expected_event_ptr_issue_980) {
662*fe927888SPhilip Paeps   // NOTE: This is a tiny subset of sample "REC-xml-19980210.xml"
663*fe927888SPhilip Paeps   //       from Perl's XML::Parser
664*fe927888SPhilip Paeps   const char *const doc = "<!DOCTYPE day [\n"
665*fe927888SPhilip Paeps                           "  <!ENTITY draft.day '10'>\n"
666*fe927888SPhilip Paeps                           "]>\n"
667*fe927888SPhilip Paeps                           "<day>&draft.day;</day>\n";
668*fe927888SPhilip Paeps 
669*fe927888SPhilip Paeps   XML_Parser parser = XML_ParserCreate(NULL);
670*fe927888SPhilip Paeps   XML_SetUserData(parser, parser);
671*fe927888SPhilip Paeps   XML_SetCharacterDataHandler(parser, on_characters_issue_980);
672*fe927888SPhilip Paeps 
673*fe927888SPhilip Paeps   assert_true(_XML_Parse_SINGLE_BYTES(parser, doc, (int)strlen(doc),
674*fe927888SPhilip Paeps                                       /*isFinal=*/XML_TRUE)
675*fe927888SPhilip Paeps               == XML_STATUS_OK);
676*fe927888SPhilip Paeps 
677*fe927888SPhilip Paeps   XML_ParserFree(parser);
678*fe927888SPhilip Paeps }
679*fe927888SPhilip Paeps END_TEST
680*fe927888SPhilip Paeps 
6814543ef51SXin LI void
make_miscellaneous_test_case(Suite * s)6824543ef51SXin LI make_miscellaneous_test_case(Suite *s) {
6834543ef51SXin LI   TCase *tc_misc = tcase_create("miscellaneous tests");
6844543ef51SXin LI 
6854543ef51SXin LI   suite_add_tcase(s, tc_misc);
6864543ef51SXin LI   tcase_add_checked_fixture(tc_misc, NULL, basic_teardown);
6874543ef51SXin LI 
6884543ef51SXin LI   tcase_add_test(tc_misc, test_misc_alloc_create_parser);
6894543ef51SXin LI   tcase_add_test(tc_misc, test_misc_alloc_create_parser_with_encoding);
6904543ef51SXin LI   tcase_add_test(tc_misc, test_misc_null_parser);
6914543ef51SXin LI   tcase_add_test(tc_misc, test_misc_error_string);
6924543ef51SXin LI   tcase_add_test(tc_misc, test_misc_version);
6934543ef51SXin LI   tcase_add_test(tc_misc, test_misc_features);
6944543ef51SXin LI   tcase_add_test(tc_misc, test_misc_attribute_leak);
6954543ef51SXin LI   tcase_add_test(tc_misc, test_misc_utf16le);
6964543ef51SXin LI   tcase_add_test(tc_misc, test_misc_stop_during_end_handler_issue_240_1);
6974543ef51SXin LI   tcase_add_test(tc_misc, test_misc_stop_during_end_handler_issue_240_2);
6984543ef51SXin LI   tcase_add_test__ifdef_xml_dtd(
6994543ef51SXin LI       tc_misc, test_misc_deny_internal_entity_closing_doctype_issue_317);
7004543ef51SXin LI   tcase_add_test(tc_misc, test_misc_tag_mismatch_reset_leak);
7014543ef51SXin LI   tcase_add_test(tc_misc,
7024543ef51SXin LI                  test_misc_create_external_entity_parser_with_null_context);
7034543ef51SXin LI   tcase_add_test(tc_misc, test_misc_general_entities_support);
7044543ef51SXin LI   tcase_add_test(tc_misc, test_misc_char_handler_stop_without_leak);
705908f215eSXin LI   tcase_add_test(tc_misc, test_misc_resumeparser_not_crashing);
706908f215eSXin LI   tcase_add_test(tc_misc, test_misc_stopparser_rejects_unstarted_parser);
707*fe927888SPhilip Paeps   tcase_add_test__if_xml_ge(tc_misc, test_renter_loop_finite_content);
708*fe927888SPhilip Paeps   tcase_add_test(tc_misc, test_misc_expected_event_ptr_issue_980);
7094543ef51SXin LI }
710