14543ef51SXin LI /* XML handler functions 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> 134543ef51SXin LI Copyright (c) 2016-2024 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-2024 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 <stdio.h> 494543ef51SXin LI #include <string.h> 504543ef51SXin LI #include <assert.h> 514543ef51SXin LI 524543ef51SXin LI #include "expat_config.h" 534543ef51SXin LI 544543ef51SXin LI #include "expat.h" 554543ef51SXin LI #include "internal.h" 564543ef51SXin LI #include "chardata.h" 574543ef51SXin LI #include "structdata.h" 584543ef51SXin LI #include "common.h" 594543ef51SXin LI #include "handlers.h" 604543ef51SXin LI 614543ef51SXin LI /* Global variables for user parameter settings tests */ 624543ef51SXin LI /* Variable holding the expected handler userData */ 634543ef51SXin LI const void *g_handler_data = NULL; 644543ef51SXin LI /* Count of the number of times the comment handler has been invoked */ 654543ef51SXin LI int g_comment_count = 0; 664543ef51SXin LI /* Count of the number of skipped entities */ 674543ef51SXin LI int g_skip_count = 0; 684543ef51SXin LI /* Count of the number of times the XML declaration handler is invoked */ 694543ef51SXin LI int g_xdecl_count = 0; 704543ef51SXin LI 714543ef51SXin LI /* Start/End Element Handlers */ 724543ef51SXin LI 734543ef51SXin LI void XMLCALL 744543ef51SXin LI start_element_event_handler(void *userData, const XML_Char *name, 754543ef51SXin LI const XML_Char **atts) { 764543ef51SXin LI UNUSED_P(atts); 774543ef51SXin LI CharData_AppendXMLChars((CharData *)userData, name, -1); 784543ef51SXin LI } 794543ef51SXin LI 804543ef51SXin LI void XMLCALL 814543ef51SXin LI end_element_event_handler(void *userData, const XML_Char *name) { 824543ef51SXin LI CharData *storage = (CharData *)userData; 834543ef51SXin LI CharData_AppendXMLChars(storage, XCS("/"), 1); 844543ef51SXin LI CharData_AppendXMLChars(storage, name, -1); 854543ef51SXin LI } 864543ef51SXin LI 874543ef51SXin LI void XMLCALL 884543ef51SXin LI start_element_event_handler2(void *userData, const XML_Char *name, 894543ef51SXin LI const XML_Char **attr) { 904543ef51SXin LI StructData *storage = (StructData *)userData; 914543ef51SXin LI UNUSED_P(attr); 924543ef51SXin LI StructData_AddItem(storage, name, XML_GetCurrentColumnNumber(g_parser), 934543ef51SXin LI XML_GetCurrentLineNumber(g_parser), STRUCT_START_TAG); 944543ef51SXin LI } 954543ef51SXin LI 964543ef51SXin LI void XMLCALL 974543ef51SXin LI end_element_event_handler2(void *userData, const XML_Char *name) { 984543ef51SXin LI StructData *storage = (StructData *)userData; 994543ef51SXin LI StructData_AddItem(storage, name, XML_GetCurrentColumnNumber(g_parser), 1004543ef51SXin LI XML_GetCurrentLineNumber(g_parser), STRUCT_END_TAG); 1014543ef51SXin LI } 1024543ef51SXin LI 1034543ef51SXin LI void XMLCALL 1044543ef51SXin LI counting_start_element_handler(void *userData, const XML_Char *name, 1054543ef51SXin LI const XML_Char **atts) { 106*908f215eSXin LI ParserAndElementInfo *const parserAndElementInfos 107*908f215eSXin LI = (ParserAndElementInfo *)userData; 108*908f215eSXin LI ElementInfo *info = parserAndElementInfos->info; 1094543ef51SXin LI AttrInfo *attr; 1104543ef51SXin LI int count, id, i; 1114543ef51SXin LI 1124543ef51SXin LI while (info->name != NULL) { 1134543ef51SXin LI if (! xcstrcmp(name, info->name)) 1144543ef51SXin LI break; 1154543ef51SXin LI info++; 1164543ef51SXin LI } 1174543ef51SXin LI if (info->name == NULL) 1184543ef51SXin LI fail("Element not recognised"); 1194543ef51SXin LI /* The attribute count is twice what you might expect. It is a 1204543ef51SXin LI * count of items in atts, an array which contains alternating 1214543ef51SXin LI * attribute names and attribute values. For the naive user this 1224543ef51SXin LI * is possibly a little unexpected, but it is what the 1234543ef51SXin LI * documentation in expat.h tells us to expect. 1244543ef51SXin LI */ 125*908f215eSXin LI count = XML_GetSpecifiedAttributeCount(parserAndElementInfos->parser); 1264543ef51SXin LI if (info->attr_count * 2 != count) { 1274543ef51SXin LI fail("Not got expected attribute count"); 1284543ef51SXin LI return; 1294543ef51SXin LI } 130*908f215eSXin LI id = XML_GetIdAttributeIndex(parserAndElementInfos->parser); 1314543ef51SXin LI if (id == -1 && info->id_name != NULL) { 1324543ef51SXin LI fail("ID not present"); 1334543ef51SXin LI return; 1344543ef51SXin LI } 1354543ef51SXin LI if (id != -1 && xcstrcmp(atts[id], info->id_name)) { 1364543ef51SXin LI fail("ID does not have the correct name"); 1374543ef51SXin LI return; 1384543ef51SXin LI } 1394543ef51SXin LI for (i = 0; i < info->attr_count; i++) { 1404543ef51SXin LI attr = info->attributes; 1414543ef51SXin LI while (attr->name != NULL) { 1424543ef51SXin LI if (! xcstrcmp(atts[0], attr->name)) 1434543ef51SXin LI break; 1444543ef51SXin LI attr++; 1454543ef51SXin LI } 1464543ef51SXin LI if (attr->name == NULL) { 1474543ef51SXin LI fail("Attribute not recognised"); 1484543ef51SXin LI return; 1494543ef51SXin LI } 1504543ef51SXin LI if (xcstrcmp(atts[1], attr->value)) { 1514543ef51SXin LI fail("Attribute has wrong value"); 1524543ef51SXin LI return; 1534543ef51SXin LI } 1544543ef51SXin LI /* Remember, two entries in atts per attribute (see above) */ 1554543ef51SXin LI atts += 2; 1564543ef51SXin LI } 1574543ef51SXin LI } 1584543ef51SXin LI 1594543ef51SXin LI void XMLCALL 1604543ef51SXin LI suspending_end_handler(void *userData, const XML_Char *s) { 1614543ef51SXin LI UNUSED_P(s); 1624543ef51SXin LI XML_StopParser((XML_Parser)userData, 1); 1634543ef51SXin LI } 1644543ef51SXin LI 1654543ef51SXin LI void XMLCALL 1664543ef51SXin LI start_element_suspender(void *userData, const XML_Char *name, 1674543ef51SXin LI const XML_Char **atts) { 1684543ef51SXin LI UNUSED_P(userData); 1694543ef51SXin LI UNUSED_P(atts); 1704543ef51SXin LI if (! xcstrcmp(name, XCS("suspend"))) 1714543ef51SXin LI XML_StopParser(g_parser, XML_TRUE); 1724543ef51SXin LI if (! xcstrcmp(name, XCS("abort"))) 1734543ef51SXin LI XML_StopParser(g_parser, XML_FALSE); 1744543ef51SXin LI } 1754543ef51SXin LI 1764543ef51SXin LI /* Check that an element name and attribute name match the expected values. 1774543ef51SXin LI The expected values are passed as an array reference of string pointers 1784543ef51SXin LI provided as the userData argument; the first is the expected 1794543ef51SXin LI element name, and the second is the expected attribute name. 1804543ef51SXin LI */ 1814543ef51SXin LI int g_triplet_start_flag = XML_FALSE; 1824543ef51SXin LI int g_triplet_end_flag = XML_FALSE; 1834543ef51SXin LI 1844543ef51SXin LI void XMLCALL 1854543ef51SXin LI triplet_start_checker(void *userData, const XML_Char *name, 1864543ef51SXin LI const XML_Char **atts) { 1874543ef51SXin LI XML_Char **elemstr = (XML_Char **)userData; 1884543ef51SXin LI char buffer[1024]; 1894543ef51SXin LI if (xcstrcmp(elemstr[0], name) != 0) { 1904543ef51SXin LI snprintf(buffer, sizeof(buffer), 1914543ef51SXin LI "unexpected start string: '%" XML_FMT_STR "'", name); 1924543ef51SXin LI fail(buffer); 1934543ef51SXin LI } 1944543ef51SXin LI if (xcstrcmp(elemstr[1], atts[0]) != 0) { 1954543ef51SXin LI snprintf(buffer, sizeof(buffer), 1964543ef51SXin LI "unexpected attribute string: '%" XML_FMT_STR "'", atts[0]); 1974543ef51SXin LI fail(buffer); 1984543ef51SXin LI } 1994543ef51SXin LI g_triplet_start_flag = XML_TRUE; 2004543ef51SXin LI } 2014543ef51SXin LI 2024543ef51SXin LI /* Check that the element name passed to the end-element handler matches 2034543ef51SXin LI the expected value. The expected value is passed as the first element 2044543ef51SXin LI in an array of strings passed as the userData argument. 2054543ef51SXin LI */ 2064543ef51SXin LI void XMLCALL 2074543ef51SXin LI triplet_end_checker(void *userData, const XML_Char *name) { 2084543ef51SXin LI XML_Char **elemstr = (XML_Char **)userData; 2094543ef51SXin LI if (xcstrcmp(elemstr[0], name) != 0) { 2104543ef51SXin LI char buffer[1024]; 2114543ef51SXin LI snprintf(buffer, sizeof(buffer), 2124543ef51SXin LI "unexpected end string: '%" XML_FMT_STR "'", name); 2134543ef51SXin LI fail(buffer); 2144543ef51SXin LI } 2154543ef51SXin LI g_triplet_end_flag = XML_TRUE; 2164543ef51SXin LI } 2174543ef51SXin LI 2184543ef51SXin LI void XMLCALL 2194543ef51SXin LI overwrite_start_checker(void *userData, const XML_Char *name, 2204543ef51SXin LI const XML_Char **atts) { 2214543ef51SXin LI CharData *storage = (CharData *)userData; 2224543ef51SXin LI CharData_AppendXMLChars(storage, XCS("start "), 6); 2234543ef51SXin LI CharData_AppendXMLChars(storage, name, -1); 2244543ef51SXin LI while (*atts != NULL) { 2254543ef51SXin LI CharData_AppendXMLChars(storage, XCS("\nattribute "), 11); 2264543ef51SXin LI CharData_AppendXMLChars(storage, *atts, -1); 2274543ef51SXin LI atts += 2; 2284543ef51SXin LI } 2294543ef51SXin LI CharData_AppendXMLChars(storage, XCS("\n"), 1); 2304543ef51SXin LI } 2314543ef51SXin LI 2324543ef51SXin LI void XMLCALL 2334543ef51SXin LI overwrite_end_checker(void *userData, const XML_Char *name) { 2344543ef51SXin LI CharData *storage = (CharData *)userData; 2354543ef51SXin LI CharData_AppendXMLChars(storage, XCS("end "), 4); 2364543ef51SXin LI CharData_AppendXMLChars(storage, name, -1); 2374543ef51SXin LI CharData_AppendXMLChars(storage, XCS("\n"), 1); 2384543ef51SXin LI } 2394543ef51SXin LI 2404543ef51SXin LI void XMLCALL 2414543ef51SXin LI start_element_fail(void *userData, const XML_Char *name, 2424543ef51SXin LI const XML_Char **atts) { 2434543ef51SXin LI UNUSED_P(userData); 2444543ef51SXin LI UNUSED_P(name); 2454543ef51SXin LI UNUSED_P(atts); 2464543ef51SXin LI 2474543ef51SXin LI /* We should never get here. */ 2484543ef51SXin LI fail("should never reach start_element_fail()"); 2494543ef51SXin LI } 2504543ef51SXin LI 2514543ef51SXin LI void XMLCALL 2524543ef51SXin LI start_ns_clearing_start_element(void *userData, const XML_Char *prefix, 2534543ef51SXin LI const XML_Char *uri) { 2544543ef51SXin LI UNUSED_P(prefix); 2554543ef51SXin LI UNUSED_P(uri); 2564543ef51SXin LI XML_SetStartElementHandler((XML_Parser)userData, NULL); 2574543ef51SXin LI } 2584543ef51SXin LI 2594543ef51SXin LI void XMLCALL 2604543ef51SXin LI start_element_issue_240(void *userData, const XML_Char *name, 2614543ef51SXin LI const XML_Char **atts) { 2624543ef51SXin LI DataIssue240 *mydata = (DataIssue240 *)userData; 2634543ef51SXin LI UNUSED_P(name); 2644543ef51SXin LI UNUSED_P(atts); 2654543ef51SXin LI mydata->deep++; 2664543ef51SXin LI } 2674543ef51SXin LI 2684543ef51SXin LI void XMLCALL 2694543ef51SXin LI end_element_issue_240(void *userData, const XML_Char *name) { 2704543ef51SXin LI DataIssue240 *mydata = (DataIssue240 *)userData; 2714543ef51SXin LI 2724543ef51SXin LI UNUSED_P(name); 2734543ef51SXin LI mydata->deep--; 2744543ef51SXin LI if (mydata->deep == 0) { 2754543ef51SXin LI XML_StopParser(mydata->parser, 0); 2764543ef51SXin LI } 2774543ef51SXin LI } 2784543ef51SXin LI 2794543ef51SXin LI /* Text encoding handlers */ 2804543ef51SXin LI 2814543ef51SXin LI int XMLCALL 2824543ef51SXin LI UnknownEncodingHandler(void *data, const XML_Char *encoding, 2834543ef51SXin LI XML_Encoding *info) { 2844543ef51SXin LI UNUSED_P(data); 2854543ef51SXin LI if (xcstrcmp(encoding, XCS("unsupported-encoding")) == 0) { 2864543ef51SXin LI int i; 2874543ef51SXin LI for (i = 0; i < 256; ++i) 2884543ef51SXin LI info->map[i] = i; 2894543ef51SXin LI info->data = NULL; 2904543ef51SXin LI info->convert = NULL; 2914543ef51SXin LI info->release = NULL; 2924543ef51SXin LI return XML_STATUS_OK; 2934543ef51SXin LI } 2944543ef51SXin LI return XML_STATUS_ERROR; 2954543ef51SXin LI } 2964543ef51SXin LI 2974543ef51SXin LI static void 2984543ef51SXin LI dummy_release(void *data) { 2994543ef51SXin LI UNUSED_P(data); 3004543ef51SXin LI } 3014543ef51SXin LI 3024543ef51SXin LI int XMLCALL 3034543ef51SXin LI UnrecognisedEncodingHandler(void *data, const XML_Char *encoding, 3044543ef51SXin LI XML_Encoding *info) { 3054543ef51SXin LI UNUSED_P(data); 3064543ef51SXin LI UNUSED_P(encoding); 3074543ef51SXin LI info->data = NULL; 3084543ef51SXin LI info->convert = NULL; 3094543ef51SXin LI info->release = dummy_release; 3104543ef51SXin LI return XML_STATUS_ERROR; 3114543ef51SXin LI } 3124543ef51SXin LI 3134543ef51SXin LI int XMLCALL 3144543ef51SXin LI unknown_released_encoding_handler(void *data, const XML_Char *encoding, 3154543ef51SXin LI XML_Encoding *info) { 3164543ef51SXin LI UNUSED_P(data); 3174543ef51SXin LI if (! xcstrcmp(encoding, XCS("unsupported-encoding"))) { 3184543ef51SXin LI int i; 3194543ef51SXin LI 3204543ef51SXin LI for (i = 0; i < 256; i++) 3214543ef51SXin LI info->map[i] = i; 3224543ef51SXin LI info->data = NULL; 3234543ef51SXin LI info->convert = NULL; 3244543ef51SXin LI info->release = dummy_release; 3254543ef51SXin LI return XML_STATUS_OK; 3264543ef51SXin LI } 3274543ef51SXin LI return XML_STATUS_ERROR; 3284543ef51SXin LI } 3294543ef51SXin LI 3304543ef51SXin LI static int XMLCALL 3314543ef51SXin LI failing_converter(void *data, const char *s) { 3324543ef51SXin LI UNUSED_P(data); 3334543ef51SXin LI UNUSED_P(s); 3344543ef51SXin LI /* Always claim to have failed */ 3354543ef51SXin LI return -1; 3364543ef51SXin LI } 3374543ef51SXin LI 3384543ef51SXin LI static int XMLCALL 3394543ef51SXin LI prefix_converter(void *data, const char *s) { 3404543ef51SXin LI UNUSED_P(data); 3414543ef51SXin LI /* If the first byte is 0xff, raise an error */ 3424543ef51SXin LI if (s[0] == (char)-1) 3434543ef51SXin LI return -1; 3444543ef51SXin LI /* Just add the low bits of the first byte to the second */ 3454543ef51SXin LI return (s[1] + (s[0] & 0x7f)) & 0x01ff; 3464543ef51SXin LI } 3474543ef51SXin LI 3484543ef51SXin LI int XMLCALL 3494543ef51SXin LI MiscEncodingHandler(void *data, const XML_Char *encoding, XML_Encoding *info) { 3504543ef51SXin LI int i; 3514543ef51SXin LI int high_map = -2; /* Assume a 2-byte sequence */ 3524543ef51SXin LI 3534543ef51SXin LI if (! xcstrcmp(encoding, XCS("invalid-9")) 3544543ef51SXin LI || ! xcstrcmp(encoding, XCS("ascii-like")) 3554543ef51SXin LI || ! xcstrcmp(encoding, XCS("invalid-len")) 3564543ef51SXin LI || ! xcstrcmp(encoding, XCS("invalid-a")) 3574543ef51SXin LI || ! xcstrcmp(encoding, XCS("invalid-surrogate")) 3584543ef51SXin LI || ! xcstrcmp(encoding, XCS("invalid-high"))) 3594543ef51SXin LI high_map = -1; 3604543ef51SXin LI 3614543ef51SXin LI for (i = 0; i < 128; ++i) 3624543ef51SXin LI info->map[i] = i; 3634543ef51SXin LI for (; i < 256; ++i) 3644543ef51SXin LI info->map[i] = high_map; 3654543ef51SXin LI 3664543ef51SXin LI /* If required, put an invalid value in the ASCII entries */ 3674543ef51SXin LI if (! xcstrcmp(encoding, XCS("invalid-9"))) 3684543ef51SXin LI info->map[9] = 5; 3694543ef51SXin LI /* If required, have a top-bit set character starts a 5-byte sequence */ 3704543ef51SXin LI if (! xcstrcmp(encoding, XCS("invalid-len"))) 3714543ef51SXin LI info->map[0x81] = -5; 3724543ef51SXin LI /* If required, make a top-bit set character a valid ASCII character */ 3734543ef51SXin LI if (! xcstrcmp(encoding, XCS("invalid-a"))) 3744543ef51SXin LI info->map[0x82] = 'a'; 3754543ef51SXin LI /* If required, give a top-bit set character a forbidden value, 3764543ef51SXin LI * what would otherwise be the first of a surrogate pair. 3774543ef51SXin LI */ 3784543ef51SXin LI if (! xcstrcmp(encoding, XCS("invalid-surrogate"))) 3794543ef51SXin LI info->map[0x83] = 0xd801; 3804543ef51SXin LI /* If required, give a top-bit set character too high a value */ 3814543ef51SXin LI if (! xcstrcmp(encoding, XCS("invalid-high"))) 3824543ef51SXin LI info->map[0x84] = 0x010101; 3834543ef51SXin LI 3844543ef51SXin LI info->data = data; 3854543ef51SXin LI info->release = NULL; 3864543ef51SXin LI if (! xcstrcmp(encoding, XCS("failing-conv"))) 3874543ef51SXin LI info->convert = failing_converter; 3884543ef51SXin LI else if (! xcstrcmp(encoding, XCS("prefix-conv"))) 3894543ef51SXin LI info->convert = prefix_converter; 3904543ef51SXin LI else 3914543ef51SXin LI info->convert = NULL; 3924543ef51SXin LI return XML_STATUS_OK; 3934543ef51SXin LI } 3944543ef51SXin LI 3954543ef51SXin LI int XMLCALL 3964543ef51SXin LI long_encoding_handler(void *userData, const XML_Char *encoding, 3974543ef51SXin LI XML_Encoding *info) { 3984543ef51SXin LI int i; 3994543ef51SXin LI 4004543ef51SXin LI UNUSED_P(userData); 4014543ef51SXin LI UNUSED_P(encoding); 4024543ef51SXin LI for (i = 0; i < 256; i++) 4034543ef51SXin LI info->map[i] = i; 4044543ef51SXin LI info->data = NULL; 4054543ef51SXin LI info->convert = NULL; 4064543ef51SXin LI info->release = NULL; 4074543ef51SXin LI return XML_STATUS_OK; 4084543ef51SXin LI } 4094543ef51SXin LI 4104543ef51SXin LI /* External Entity Handlers */ 4114543ef51SXin LI 4124543ef51SXin LI int XMLCALL 4134543ef51SXin LI external_entity_optioner(XML_Parser parser, const XML_Char *context, 4144543ef51SXin LI const XML_Char *base, const XML_Char *systemId, 4154543ef51SXin LI const XML_Char *publicId) { 4164543ef51SXin LI ExtOption *options = (ExtOption *)XML_GetUserData(parser); 4174543ef51SXin LI XML_Parser ext_parser; 4184543ef51SXin LI 4194543ef51SXin LI UNUSED_P(base); 4204543ef51SXin LI UNUSED_P(publicId); 4214543ef51SXin LI while (options->parse_text != NULL) { 4224543ef51SXin LI if (! xcstrcmp(systemId, options->system_id)) { 4234543ef51SXin LI enum XML_Status rc; 4244543ef51SXin LI ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 4254543ef51SXin LI if (ext_parser == NULL) 4264543ef51SXin LI return XML_STATUS_ERROR; 4274543ef51SXin LI rc = _XML_Parse_SINGLE_BYTES(ext_parser, options->parse_text, 4284543ef51SXin LI (int)strlen(options->parse_text), XML_TRUE); 4294543ef51SXin LI XML_ParserFree(ext_parser); 4304543ef51SXin LI return rc; 4314543ef51SXin LI } 4324543ef51SXin LI options++; 4334543ef51SXin LI } 4344543ef51SXin LI fail("No suitable option found"); 4354543ef51SXin LI return XML_STATUS_ERROR; 4364543ef51SXin LI } 4374543ef51SXin LI 4384543ef51SXin LI int XMLCALL 4394543ef51SXin LI external_entity_loader(XML_Parser parser, const XML_Char *context, 4404543ef51SXin LI const XML_Char *base, const XML_Char *systemId, 4414543ef51SXin LI const XML_Char *publicId) { 4424543ef51SXin LI ExtTest *test_data = (ExtTest *)XML_GetUserData(parser); 4434543ef51SXin LI XML_Parser extparser; 4444543ef51SXin LI 4454543ef51SXin LI UNUSED_P(base); 4464543ef51SXin LI UNUSED_P(systemId); 4474543ef51SXin LI UNUSED_P(publicId); 4484543ef51SXin LI extparser = XML_ExternalEntityParserCreate(parser, context, NULL); 4494543ef51SXin LI if (extparser == NULL) 4504543ef51SXin LI fail("Could not create external entity parser."); 4514543ef51SXin LI if (test_data->encoding != NULL) { 4524543ef51SXin LI if (! XML_SetEncoding(extparser, test_data->encoding)) 4534543ef51SXin LI fail("XML_SetEncoding() ignored for external entity"); 4544543ef51SXin LI } 4554543ef51SXin LI if (_XML_Parse_SINGLE_BYTES(extparser, test_data->parse_text, 4564543ef51SXin LI (int)strlen(test_data->parse_text), XML_TRUE) 4574543ef51SXin LI == XML_STATUS_ERROR) { 4584543ef51SXin LI xml_failure(extparser); 4594543ef51SXin LI return XML_STATUS_ERROR; 4604543ef51SXin LI } 4614543ef51SXin LI XML_ParserFree(extparser); 4624543ef51SXin LI return XML_STATUS_OK; 4634543ef51SXin LI } 4644543ef51SXin LI 4654543ef51SXin LI int XMLCALL 4664543ef51SXin LI external_entity_faulter(XML_Parser parser, const XML_Char *context, 4674543ef51SXin LI const XML_Char *base, const XML_Char *systemId, 4684543ef51SXin LI const XML_Char *publicId) { 4694543ef51SXin LI XML_Parser ext_parser; 4704543ef51SXin LI ExtFaults *fault = (ExtFaults *)XML_GetUserData(parser); 4714543ef51SXin LI 4724543ef51SXin LI UNUSED_P(base); 4734543ef51SXin LI UNUSED_P(systemId); 4744543ef51SXin LI UNUSED_P(publicId); 4754543ef51SXin LI ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 4764543ef51SXin LI if (ext_parser == NULL) 4774543ef51SXin LI fail("Could not create external entity parser"); 4784543ef51SXin LI if (fault->encoding != NULL) { 4794543ef51SXin LI if (! XML_SetEncoding(ext_parser, fault->encoding)) 4804543ef51SXin LI fail("XML_SetEncoding failed"); 4814543ef51SXin LI } 4824543ef51SXin LI if (_XML_Parse_SINGLE_BYTES(ext_parser, fault->parse_text, 4834543ef51SXin LI (int)strlen(fault->parse_text), XML_TRUE) 4844543ef51SXin LI != XML_STATUS_ERROR) 4854543ef51SXin LI fail(fault->fail_text); 4864543ef51SXin LI if (XML_GetErrorCode(ext_parser) != fault->error) 4874543ef51SXin LI xml_failure(ext_parser); 4884543ef51SXin LI 4894543ef51SXin LI XML_ParserFree(ext_parser); 4904543ef51SXin LI return XML_STATUS_ERROR; 4914543ef51SXin LI } 4924543ef51SXin LI 4934543ef51SXin LI int XMLCALL 4944543ef51SXin LI external_entity_null_loader(XML_Parser parser, const XML_Char *context, 4954543ef51SXin LI const XML_Char *base, const XML_Char *systemId, 4964543ef51SXin LI const XML_Char *publicId) { 4974543ef51SXin LI UNUSED_P(parser); 4984543ef51SXin LI UNUSED_P(context); 4994543ef51SXin LI UNUSED_P(base); 5004543ef51SXin LI UNUSED_P(systemId); 5014543ef51SXin LI UNUSED_P(publicId); 5024543ef51SXin LI return XML_STATUS_OK; 5034543ef51SXin LI } 5044543ef51SXin LI 5054543ef51SXin LI int XMLCALL 5064543ef51SXin LI external_entity_resetter(XML_Parser parser, const XML_Char *context, 5074543ef51SXin LI const XML_Char *base, const XML_Char *systemId, 5084543ef51SXin LI const XML_Char *publicId) { 5094543ef51SXin LI const char *text = "<!ELEMENT doc (#PCDATA)*>"; 5104543ef51SXin LI XML_Parser ext_parser; 5114543ef51SXin LI XML_ParsingStatus status; 5124543ef51SXin LI 5134543ef51SXin LI UNUSED_P(base); 5144543ef51SXin LI UNUSED_P(systemId); 5154543ef51SXin LI UNUSED_P(publicId); 5164543ef51SXin LI ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 5174543ef51SXin LI if (ext_parser == NULL) 5184543ef51SXin LI fail("Could not create external entity parser"); 5194543ef51SXin LI XML_GetParsingStatus(ext_parser, &status); 5204543ef51SXin LI if (status.parsing != XML_INITIALIZED) { 5214543ef51SXin LI fail("Parsing status is not INITIALIZED"); 5224543ef51SXin LI return XML_STATUS_ERROR; 5234543ef51SXin LI } 5244543ef51SXin LI if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE) 5254543ef51SXin LI == XML_STATUS_ERROR) { 5264543ef51SXin LI xml_failure(parser); 5274543ef51SXin LI return XML_STATUS_ERROR; 5284543ef51SXin LI } 5294543ef51SXin LI XML_GetParsingStatus(ext_parser, &status); 5304543ef51SXin LI if (status.parsing != XML_FINISHED) { 5314543ef51SXin LI fail("Parsing status is not FINISHED"); 5324543ef51SXin LI return XML_STATUS_ERROR; 5334543ef51SXin LI } 5344543ef51SXin LI /* Check we can't parse here */ 5354543ef51SXin LI if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE) 5364543ef51SXin LI != XML_STATUS_ERROR) 5374543ef51SXin LI fail("Parsing when finished not faulted"); 5384543ef51SXin LI if (XML_GetErrorCode(ext_parser) != XML_ERROR_FINISHED) 5394543ef51SXin LI fail("Parsing when finished faulted with wrong code"); 5404543ef51SXin LI XML_ParserReset(ext_parser, NULL); 5414543ef51SXin LI XML_GetParsingStatus(ext_parser, &status); 5424543ef51SXin LI if (status.parsing != XML_FINISHED) { 5434543ef51SXin LI fail("Parsing status not still FINISHED"); 5444543ef51SXin LI return XML_STATUS_ERROR; 5454543ef51SXin LI } 5464543ef51SXin LI XML_ParserFree(ext_parser); 5474543ef51SXin LI return XML_STATUS_OK; 5484543ef51SXin LI } 5494543ef51SXin LI 5504543ef51SXin LI void XMLCALL 5514543ef51SXin LI entity_suspending_decl_handler(void *userData, const XML_Char *name, 5524543ef51SXin LI XML_Content *model) { 5534543ef51SXin LI XML_Parser ext_parser = (XML_Parser)userData; 5544543ef51SXin LI 5554543ef51SXin LI UNUSED_P(name); 5564543ef51SXin LI if (XML_StopParser(ext_parser, XML_TRUE) != XML_STATUS_ERROR) 5574543ef51SXin LI fail("Attempting to suspend a subordinate parser not faulted"); 5584543ef51SXin LI if (XML_GetErrorCode(ext_parser) != XML_ERROR_SUSPEND_PE) 5594543ef51SXin LI fail("Suspending subordinate parser get wrong code"); 5604543ef51SXin LI XML_SetElementDeclHandler(ext_parser, NULL); 5614543ef51SXin LI XML_FreeContentModel(g_parser, model); 5624543ef51SXin LI } 5634543ef51SXin LI 5644543ef51SXin LI int XMLCALL 5654543ef51SXin LI external_entity_suspender(XML_Parser parser, const XML_Char *context, 5664543ef51SXin LI const XML_Char *base, const XML_Char *systemId, 5674543ef51SXin LI const XML_Char *publicId) { 5684543ef51SXin LI const char *text = "<!ELEMENT doc (#PCDATA)*>"; 5694543ef51SXin LI XML_Parser ext_parser; 5704543ef51SXin LI 5714543ef51SXin LI UNUSED_P(base); 5724543ef51SXin LI UNUSED_P(systemId); 5734543ef51SXin LI UNUSED_P(publicId); 5744543ef51SXin LI ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 5754543ef51SXin LI if (ext_parser == NULL) 5764543ef51SXin LI fail("Could not create external entity parser"); 5774543ef51SXin LI XML_SetElementDeclHandler(ext_parser, entity_suspending_decl_handler); 5784543ef51SXin LI XML_SetUserData(ext_parser, ext_parser); 5794543ef51SXin LI if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE) 5804543ef51SXin LI == XML_STATUS_ERROR) { 5814543ef51SXin LI xml_failure(ext_parser); 5824543ef51SXin LI return XML_STATUS_ERROR; 5834543ef51SXin LI } 5844543ef51SXin LI XML_ParserFree(ext_parser); 5854543ef51SXin LI return XML_STATUS_OK; 5864543ef51SXin LI } 5874543ef51SXin LI 5884543ef51SXin LI void XMLCALL 5894543ef51SXin LI entity_suspending_xdecl_handler(void *userData, const XML_Char *version, 5904543ef51SXin LI const XML_Char *encoding, int standalone) { 5914543ef51SXin LI XML_Parser ext_parser = (XML_Parser)userData; 5924543ef51SXin LI 5934543ef51SXin LI UNUSED_P(version); 5944543ef51SXin LI UNUSED_P(encoding); 5954543ef51SXin LI UNUSED_P(standalone); 5964543ef51SXin LI XML_StopParser(ext_parser, g_resumable); 5974543ef51SXin LI XML_SetXmlDeclHandler(ext_parser, NULL); 5984543ef51SXin LI } 5994543ef51SXin LI 6004543ef51SXin LI int XMLCALL 6014543ef51SXin LI external_entity_suspend_xmldecl(XML_Parser parser, const XML_Char *context, 6024543ef51SXin LI const XML_Char *base, const XML_Char *systemId, 6034543ef51SXin LI const XML_Char *publicId) { 6044543ef51SXin LI const char *text = "<?xml version='1.0' encoding='us-ascii'?>"; 6054543ef51SXin LI XML_Parser ext_parser; 6064543ef51SXin LI XML_ParsingStatus status; 6074543ef51SXin LI enum XML_Status rc; 6084543ef51SXin LI 6094543ef51SXin LI UNUSED_P(base); 6104543ef51SXin LI UNUSED_P(systemId); 6114543ef51SXin LI UNUSED_P(publicId); 6124543ef51SXin LI ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 6134543ef51SXin LI if (ext_parser == NULL) 6144543ef51SXin LI fail("Could not create external entity parser"); 6154543ef51SXin LI XML_SetXmlDeclHandler(ext_parser, entity_suspending_xdecl_handler); 6164543ef51SXin LI XML_SetUserData(ext_parser, ext_parser); 6174543ef51SXin LI rc = _XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE); 6184543ef51SXin LI XML_GetParsingStatus(ext_parser, &status); 6194543ef51SXin LI if (g_resumable) { 6204543ef51SXin LI if (rc == XML_STATUS_ERROR) 6214543ef51SXin LI xml_failure(ext_parser); 6224543ef51SXin LI if (status.parsing != XML_SUSPENDED) 6234543ef51SXin LI fail("Ext Parsing status not SUSPENDED"); 6244543ef51SXin LI } else { 6254543ef51SXin LI if (rc != XML_STATUS_ERROR) 6264543ef51SXin LI fail("Ext parsing not aborted"); 6274543ef51SXin LI if (XML_GetErrorCode(ext_parser) != XML_ERROR_ABORTED) 6284543ef51SXin LI xml_failure(ext_parser); 6294543ef51SXin LI if (status.parsing != XML_FINISHED) 6304543ef51SXin LI fail("Ext Parsing status not FINISHED"); 6314543ef51SXin LI } 6324543ef51SXin LI 6334543ef51SXin LI XML_ParserFree(ext_parser); 6344543ef51SXin LI return XML_STATUS_OK; 6354543ef51SXin LI } 6364543ef51SXin LI 6374543ef51SXin LI int XMLCALL 6384543ef51SXin LI external_entity_suspending_faulter(XML_Parser parser, const XML_Char *context, 6394543ef51SXin LI const XML_Char *base, 6404543ef51SXin LI const XML_Char *systemId, 6414543ef51SXin LI const XML_Char *publicId) { 6424543ef51SXin LI XML_Parser ext_parser; 6434543ef51SXin LI ExtFaults *fault = (ExtFaults *)XML_GetUserData(parser); 6444543ef51SXin LI void *buffer; 6454543ef51SXin LI int parse_len = (int)strlen(fault->parse_text); 6464543ef51SXin LI 6474543ef51SXin LI UNUSED_P(base); 6484543ef51SXin LI UNUSED_P(systemId); 6494543ef51SXin LI UNUSED_P(publicId); 6504543ef51SXin LI ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 6514543ef51SXin LI if (ext_parser == NULL) 6524543ef51SXin LI fail("Could not create external entity parser"); 6534543ef51SXin LI XML_SetXmlDeclHandler(ext_parser, entity_suspending_xdecl_handler); 6544543ef51SXin LI XML_SetUserData(ext_parser, ext_parser); 6554543ef51SXin LI g_resumable = XML_TRUE; 6564543ef51SXin LI buffer = XML_GetBuffer(ext_parser, parse_len); 6574543ef51SXin LI if (buffer == NULL) 6584543ef51SXin LI fail("Could not allocate parse buffer"); 6594543ef51SXin LI assert(buffer != NULL); 6604543ef51SXin LI memcpy(buffer, fault->parse_text, parse_len); 6614543ef51SXin LI if (XML_ParseBuffer(ext_parser, parse_len, XML_FALSE) != XML_STATUS_SUSPENDED) 6624543ef51SXin LI fail("XML declaration did not suspend"); 6634543ef51SXin LI if (XML_ResumeParser(ext_parser) != XML_STATUS_OK) 6644543ef51SXin LI xml_failure(ext_parser); 6654543ef51SXin LI if (XML_ParseBuffer(ext_parser, 0, XML_TRUE) != XML_STATUS_ERROR) 6664543ef51SXin LI fail(fault->fail_text); 6674543ef51SXin LI if (XML_GetErrorCode(ext_parser) != fault->error) 6684543ef51SXin LI xml_failure(ext_parser); 6694543ef51SXin LI 6704543ef51SXin LI XML_ParserFree(ext_parser); 6714543ef51SXin LI return XML_STATUS_ERROR; 6724543ef51SXin LI } 6734543ef51SXin LI 6744543ef51SXin LI int XMLCALL 6754543ef51SXin LI external_entity_failer__if_not_xml_ge(XML_Parser parser, 6764543ef51SXin LI const XML_Char *context, 6774543ef51SXin LI const XML_Char *base, 6784543ef51SXin LI const XML_Char *systemId, 6794543ef51SXin LI const XML_Char *publicId) { 6804543ef51SXin LI UNUSED_P(parser); 6814543ef51SXin LI UNUSED_P(context); 6824543ef51SXin LI UNUSED_P(base); 6834543ef51SXin LI UNUSED_P(systemId); 6844543ef51SXin LI UNUSED_P(publicId); 6854543ef51SXin LI #if XML_GE == 0 6864543ef51SXin LI fail( 6874543ef51SXin LI "Function external_entity_suspending_failer was called despite XML_GE==0."); 6884543ef51SXin LI #endif 6894543ef51SXin LI return XML_STATUS_OK; 6904543ef51SXin LI } 6914543ef51SXin LI 6924543ef51SXin LI int XMLCALL 6934543ef51SXin LI external_entity_cr_catcher(XML_Parser parser, const XML_Char *context, 6944543ef51SXin LI const XML_Char *base, const XML_Char *systemId, 6954543ef51SXin LI const XML_Char *publicId) { 6964543ef51SXin LI const char *text = "\r"; 6974543ef51SXin LI XML_Parser ext_parser; 6984543ef51SXin LI 6994543ef51SXin LI UNUSED_P(base); 7004543ef51SXin LI UNUSED_P(systemId); 7014543ef51SXin LI UNUSED_P(publicId); 7024543ef51SXin LI ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 7034543ef51SXin LI if (ext_parser == NULL) 7044543ef51SXin LI fail("Could not create external entity parser"); 7054543ef51SXin LI XML_SetCharacterDataHandler(ext_parser, cr_cdata_handler); 7064543ef51SXin LI if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE) 7074543ef51SXin LI == XML_STATUS_ERROR) 7084543ef51SXin LI xml_failure(ext_parser); 7094543ef51SXin LI XML_ParserFree(ext_parser); 7104543ef51SXin LI return XML_STATUS_OK; 7114543ef51SXin LI } 7124543ef51SXin LI 7134543ef51SXin LI int XMLCALL 7144543ef51SXin LI external_entity_bad_cr_catcher(XML_Parser parser, const XML_Char *context, 7154543ef51SXin LI const XML_Char *base, const XML_Char *systemId, 7164543ef51SXin LI const XML_Char *publicId) { 7174543ef51SXin LI const char *text = "<tag>\r"; 7184543ef51SXin LI XML_Parser ext_parser; 7194543ef51SXin LI 7204543ef51SXin LI UNUSED_P(base); 7214543ef51SXin LI UNUSED_P(systemId); 7224543ef51SXin LI UNUSED_P(publicId); 7234543ef51SXin LI ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 7244543ef51SXin LI if (ext_parser == NULL) 7254543ef51SXin LI fail("Could not create external entity parser"); 7264543ef51SXin LI XML_SetCharacterDataHandler(ext_parser, cr_cdata_handler); 7274543ef51SXin LI if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE) 7284543ef51SXin LI == XML_STATUS_OK) 7294543ef51SXin LI fail("Async entity error not caught"); 7304543ef51SXin LI if (XML_GetErrorCode(ext_parser) != XML_ERROR_ASYNC_ENTITY) 7314543ef51SXin LI xml_failure(ext_parser); 7324543ef51SXin LI XML_ParserFree(ext_parser); 7334543ef51SXin LI return XML_STATUS_OK; 7344543ef51SXin LI } 7354543ef51SXin LI 7364543ef51SXin LI int XMLCALL 7374543ef51SXin LI external_entity_rsqb_catcher(XML_Parser parser, const XML_Char *context, 7384543ef51SXin LI const XML_Char *base, const XML_Char *systemId, 7394543ef51SXin LI const XML_Char *publicId) { 7404543ef51SXin LI const char *text = "<tag>]"; 7414543ef51SXin LI XML_Parser ext_parser; 7424543ef51SXin LI 7434543ef51SXin LI UNUSED_P(base); 7444543ef51SXin LI UNUSED_P(systemId); 7454543ef51SXin LI UNUSED_P(publicId); 7464543ef51SXin LI ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 7474543ef51SXin LI if (ext_parser == NULL) 7484543ef51SXin LI fail("Could not create external entity parser"); 7494543ef51SXin LI XML_SetCharacterDataHandler(ext_parser, rsqb_handler); 7504543ef51SXin LI if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE) 7514543ef51SXin LI != XML_STATUS_ERROR) 7524543ef51SXin LI fail("Async entity error not caught"); 7534543ef51SXin LI if (XML_GetErrorCode(ext_parser) != XML_ERROR_ASYNC_ENTITY) 7544543ef51SXin LI xml_failure(ext_parser); 7554543ef51SXin LI XML_ParserFree(ext_parser); 7564543ef51SXin LI return XML_STATUS_OK; 7574543ef51SXin LI } 7584543ef51SXin LI 7594543ef51SXin LI int XMLCALL 7604543ef51SXin LI external_entity_good_cdata_ascii(XML_Parser parser, const XML_Char *context, 7614543ef51SXin LI const XML_Char *base, const XML_Char *systemId, 7624543ef51SXin LI const XML_Char *publicId) { 7634543ef51SXin LI const char *text = "<a><![CDATA[<greeting>Hello, world!</greeting>]]></a>"; 7644543ef51SXin LI const XML_Char *expected = XCS("<greeting>Hello, world!</greeting>"); 7654543ef51SXin LI CharData storage; 7664543ef51SXin LI XML_Parser ext_parser; 7674543ef51SXin LI 7684543ef51SXin LI UNUSED_P(base); 7694543ef51SXin LI UNUSED_P(systemId); 7704543ef51SXin LI UNUSED_P(publicId); 7714543ef51SXin LI CharData_Init(&storage); 7724543ef51SXin LI ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 7734543ef51SXin LI if (ext_parser == NULL) 7744543ef51SXin LI fail("Could not create external entity parser"); 7754543ef51SXin LI XML_SetUserData(ext_parser, &storage); 7764543ef51SXin LI XML_SetCharacterDataHandler(ext_parser, accumulate_characters); 7774543ef51SXin LI 7784543ef51SXin LI if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE) 7794543ef51SXin LI == XML_STATUS_ERROR) 7804543ef51SXin LI xml_failure(ext_parser); 7814543ef51SXin LI CharData_CheckXMLChars(&storage, expected); 7824543ef51SXin LI 7834543ef51SXin LI XML_ParserFree(ext_parser); 7844543ef51SXin LI return XML_STATUS_OK; 7854543ef51SXin LI } 7864543ef51SXin LI 7874543ef51SXin LI int XMLCALL 7884543ef51SXin LI external_entity_param_checker(XML_Parser parser, const XML_Char *context, 7894543ef51SXin LI const XML_Char *base, const XML_Char *systemId, 7904543ef51SXin LI const XML_Char *publicId) { 7914543ef51SXin LI const char *text = "<!-- Subordinate parser -->\n" 7924543ef51SXin LI "<!ELEMENT doc (#PCDATA)*>"; 7934543ef51SXin LI XML_Parser ext_parser; 7944543ef51SXin LI 7954543ef51SXin LI UNUSED_P(base); 7964543ef51SXin LI UNUSED_P(systemId); 7974543ef51SXin LI UNUSED_P(publicId); 7984543ef51SXin LI ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 7994543ef51SXin LI if (ext_parser == NULL) 8004543ef51SXin LI fail("Could not create external entity parser"); 8014543ef51SXin LI g_handler_data = ext_parser; 8024543ef51SXin LI if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE) 8034543ef51SXin LI == XML_STATUS_ERROR) { 8044543ef51SXin LI xml_failure(parser); 8054543ef51SXin LI return XML_STATUS_ERROR; 8064543ef51SXin LI } 8074543ef51SXin LI g_handler_data = parser; 8084543ef51SXin LI XML_ParserFree(ext_parser); 8094543ef51SXin LI return XML_STATUS_OK; 8104543ef51SXin LI } 8114543ef51SXin LI 8124543ef51SXin LI int XMLCALL 8134543ef51SXin LI external_entity_ref_param_checker(XML_Parser parameter, const XML_Char *context, 8144543ef51SXin LI const XML_Char *base, 8154543ef51SXin LI const XML_Char *systemId, 8164543ef51SXin LI const XML_Char *publicId) { 8174543ef51SXin LI const char *text = "<!ELEMENT doc (#PCDATA)*>"; 8184543ef51SXin LI XML_Parser ext_parser; 8194543ef51SXin LI 8204543ef51SXin LI UNUSED_P(base); 8214543ef51SXin LI UNUSED_P(systemId); 8224543ef51SXin LI UNUSED_P(publicId); 8234543ef51SXin LI if ((void *)parameter != g_handler_data) 8244543ef51SXin LI fail("External entity ref handler parameter not correct"); 8254543ef51SXin LI 8264543ef51SXin LI /* Here we use the global 'parser' variable */ 8274543ef51SXin LI ext_parser = XML_ExternalEntityParserCreate(g_parser, context, NULL); 8284543ef51SXin LI if (ext_parser == NULL) 8294543ef51SXin LI fail("Could not create external entity parser"); 8304543ef51SXin LI if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE) 8314543ef51SXin LI == XML_STATUS_ERROR) 8324543ef51SXin LI xml_failure(ext_parser); 8334543ef51SXin LI 8344543ef51SXin LI XML_ParserFree(ext_parser); 8354543ef51SXin LI return XML_STATUS_OK; 8364543ef51SXin LI } 8374543ef51SXin LI 8384543ef51SXin LI int XMLCALL 8394543ef51SXin LI external_entity_param(XML_Parser parser, const XML_Char *context, 8404543ef51SXin LI const XML_Char *base, const XML_Char *systemId, 8414543ef51SXin LI const XML_Char *publicId) { 8424543ef51SXin LI const char *text1 = "<!ELEMENT doc EMPTY>\n" 8434543ef51SXin LI "<!ENTITY % e1 SYSTEM '004-2.ent'>\n" 8444543ef51SXin LI "<!ENTITY % e2 '%e1;'>\n" 8454543ef51SXin LI "%e1;\n"; 8464543ef51SXin LI const char *text2 = "<!ELEMENT el EMPTY>\n" 8474543ef51SXin LI "<el/>\n"; 8484543ef51SXin LI XML_Parser ext_parser; 8494543ef51SXin LI 8504543ef51SXin LI UNUSED_P(base); 8514543ef51SXin LI UNUSED_P(publicId); 8524543ef51SXin LI if (systemId == NULL) 8534543ef51SXin LI return XML_STATUS_OK; 8544543ef51SXin LI 8554543ef51SXin LI ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 8564543ef51SXin LI if (ext_parser == NULL) 8574543ef51SXin LI fail("Could not create external entity parser"); 8584543ef51SXin LI 8594543ef51SXin LI if (! xcstrcmp(systemId, XCS("004-1.ent"))) { 8604543ef51SXin LI if (_XML_Parse_SINGLE_BYTES(ext_parser, text1, (int)strlen(text1), XML_TRUE) 8614543ef51SXin LI != XML_STATUS_ERROR) 8624543ef51SXin LI fail("Inner DTD with invalid tag not rejected"); 8634543ef51SXin LI if (XML_GetErrorCode(ext_parser) != XML_ERROR_EXTERNAL_ENTITY_HANDLING) 8644543ef51SXin LI xml_failure(ext_parser); 8654543ef51SXin LI } else if (! xcstrcmp(systemId, XCS("004-2.ent"))) { 8664543ef51SXin LI if (_XML_Parse_SINGLE_BYTES(ext_parser, text2, (int)strlen(text2), XML_TRUE) 8674543ef51SXin LI != XML_STATUS_ERROR) 8684543ef51SXin LI fail("Invalid tag in external param not rejected"); 8694543ef51SXin LI if (XML_GetErrorCode(ext_parser) != XML_ERROR_SYNTAX) 8704543ef51SXin LI xml_failure(ext_parser); 8714543ef51SXin LI } else { 8724543ef51SXin LI fail("Unknown system ID"); 8734543ef51SXin LI } 8744543ef51SXin LI 8754543ef51SXin LI XML_ParserFree(ext_parser); 8764543ef51SXin LI return XML_STATUS_ERROR; 8774543ef51SXin LI } 8784543ef51SXin LI 8794543ef51SXin LI int XMLCALL 8804543ef51SXin LI external_entity_load_ignore(XML_Parser parser, const XML_Char *context, 8814543ef51SXin LI const XML_Char *base, const XML_Char *systemId, 8824543ef51SXin LI const XML_Char *publicId) { 8834543ef51SXin LI const char *text = "<![IGNORE[<!ELEMENT e (#PCDATA)*>]]>"; 8844543ef51SXin LI XML_Parser ext_parser; 8854543ef51SXin LI 8864543ef51SXin LI UNUSED_P(base); 8874543ef51SXin LI UNUSED_P(systemId); 8884543ef51SXin LI UNUSED_P(publicId); 8894543ef51SXin LI ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 8904543ef51SXin LI if (ext_parser == NULL) 8914543ef51SXin LI fail("Could not create external entity parser"); 8924543ef51SXin LI if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE) 8934543ef51SXin LI == XML_STATUS_ERROR) 8944543ef51SXin LI xml_failure(parser); 8954543ef51SXin LI 8964543ef51SXin LI XML_ParserFree(ext_parser); 8974543ef51SXin LI return XML_STATUS_OK; 8984543ef51SXin LI } 8994543ef51SXin LI 9004543ef51SXin LI int XMLCALL 9014543ef51SXin LI external_entity_load_ignore_utf16(XML_Parser parser, const XML_Char *context, 9024543ef51SXin LI const XML_Char *base, 9034543ef51SXin LI const XML_Char *systemId, 9044543ef51SXin LI const XML_Char *publicId) { 9054543ef51SXin LI const char text[] = 9064543ef51SXin LI /* <![IGNORE[<!ELEMENT e (#PCDATA)*>]]> */ 9074543ef51SXin LI "<\0!\0[\0I\0G\0N\0O\0R\0E\0[\0" 9084543ef51SXin LI "<\0!\0E\0L\0E\0M\0E\0N\0T\0 \0e\0 \0" 9094543ef51SXin LI "(\0#\0P\0C\0D\0A\0T\0A\0)\0*\0>\0]\0]\0>\0"; 9104543ef51SXin LI XML_Parser ext_parser; 9114543ef51SXin LI 9124543ef51SXin LI UNUSED_P(base); 9134543ef51SXin LI UNUSED_P(systemId); 9144543ef51SXin LI UNUSED_P(publicId); 9154543ef51SXin LI ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 9164543ef51SXin LI if (ext_parser == NULL) 9174543ef51SXin LI fail("Could not create external entity parser"); 9184543ef51SXin LI if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)sizeof(text) - 1, XML_TRUE) 9194543ef51SXin LI == XML_STATUS_ERROR) 9204543ef51SXin LI xml_failure(parser); 9214543ef51SXin LI 9224543ef51SXin LI XML_ParserFree(ext_parser); 9234543ef51SXin LI return XML_STATUS_OK; 9244543ef51SXin LI } 9254543ef51SXin LI 9264543ef51SXin LI int XMLCALL 9274543ef51SXin LI external_entity_load_ignore_utf16_be(XML_Parser parser, const XML_Char *context, 9284543ef51SXin LI const XML_Char *base, 9294543ef51SXin LI const XML_Char *systemId, 9304543ef51SXin LI const XML_Char *publicId) { 9314543ef51SXin LI const char text[] = 9324543ef51SXin LI /* <![IGNORE[<!ELEMENT e (#PCDATA)*>]]> */ 9334543ef51SXin LI "\0<\0!\0[\0I\0G\0N\0O\0R\0E\0[" 9344543ef51SXin LI "\0<\0!\0E\0L\0E\0M\0E\0N\0T\0 \0e\0 " 9354543ef51SXin LI "\0(\0#\0P\0C\0D\0A\0T\0A\0)\0*\0>\0]\0]\0>"; 9364543ef51SXin LI XML_Parser ext_parser; 9374543ef51SXin LI 9384543ef51SXin LI UNUSED_P(base); 9394543ef51SXin LI UNUSED_P(systemId); 9404543ef51SXin LI UNUSED_P(publicId); 9414543ef51SXin LI ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 9424543ef51SXin LI if (ext_parser == NULL) 9434543ef51SXin LI fail("Could not create external entity parser"); 9444543ef51SXin LI if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)sizeof(text) - 1, XML_TRUE) 9454543ef51SXin LI == XML_STATUS_ERROR) 9464543ef51SXin LI xml_failure(parser); 9474543ef51SXin LI 9484543ef51SXin LI XML_ParserFree(ext_parser); 9494543ef51SXin LI return XML_STATUS_OK; 9504543ef51SXin LI } 9514543ef51SXin LI 9524543ef51SXin LI int XMLCALL 9534543ef51SXin LI external_entity_valuer(XML_Parser parser, const XML_Char *context, 9544543ef51SXin LI const XML_Char *base, const XML_Char *systemId, 9554543ef51SXin LI const XML_Char *publicId) { 9564543ef51SXin LI const char *text1 = "<!ELEMENT doc EMPTY>\n" 9574543ef51SXin LI "<!ENTITY % e1 SYSTEM '004-2.ent'>\n" 9584543ef51SXin LI "<!ENTITY % e2 '%e1;'>\n" 9594543ef51SXin LI "%e1;\n"; 9604543ef51SXin LI XML_Parser ext_parser; 9614543ef51SXin LI 9624543ef51SXin LI UNUSED_P(base); 9634543ef51SXin LI UNUSED_P(publicId); 9644543ef51SXin LI if (systemId == NULL) 9654543ef51SXin LI return XML_STATUS_OK; 9664543ef51SXin LI ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 9674543ef51SXin LI if (ext_parser == NULL) 9684543ef51SXin LI fail("Could not create external entity parser"); 9694543ef51SXin LI if (! xcstrcmp(systemId, XCS("004-1.ent"))) { 9704543ef51SXin LI if (_XML_Parse_SINGLE_BYTES(ext_parser, text1, (int)strlen(text1), XML_TRUE) 9714543ef51SXin LI == XML_STATUS_ERROR) 9724543ef51SXin LI xml_failure(ext_parser); 9734543ef51SXin LI } else if (! xcstrcmp(systemId, XCS("004-2.ent"))) { 9744543ef51SXin LI ExtFaults *fault = (ExtFaults *)XML_GetUserData(parser); 9754543ef51SXin LI enum XML_Status status; 9764543ef51SXin LI enum XML_Error error; 9774543ef51SXin LI 9784543ef51SXin LI status = _XML_Parse_SINGLE_BYTES(ext_parser, fault->parse_text, 9794543ef51SXin LI (int)strlen(fault->parse_text), XML_TRUE); 9804543ef51SXin LI if (fault->error == XML_ERROR_NONE) { 9814543ef51SXin LI if (status == XML_STATUS_ERROR) 9824543ef51SXin LI xml_failure(ext_parser); 9834543ef51SXin LI } else { 9844543ef51SXin LI if (status != XML_STATUS_ERROR) 9854543ef51SXin LI fail(fault->fail_text); 9864543ef51SXin LI error = XML_GetErrorCode(ext_parser); 9874543ef51SXin LI if (error != fault->error 9884543ef51SXin LI && (fault->error != XML_ERROR_XML_DECL 9894543ef51SXin LI || error != XML_ERROR_TEXT_DECL)) 9904543ef51SXin LI xml_failure(ext_parser); 9914543ef51SXin LI } 9924543ef51SXin LI } 9934543ef51SXin LI 9944543ef51SXin LI XML_ParserFree(ext_parser); 9954543ef51SXin LI return XML_STATUS_OK; 9964543ef51SXin LI } 9974543ef51SXin LI 9984543ef51SXin LI int XMLCALL 9994543ef51SXin LI external_entity_not_standalone(XML_Parser parser, const XML_Char *context, 10004543ef51SXin LI const XML_Char *base, const XML_Char *systemId, 10014543ef51SXin LI const XML_Char *publicId) { 10024543ef51SXin LI const char *text1 = "<!ELEMENT doc EMPTY>\n" 10034543ef51SXin LI "<!ENTITY % e1 SYSTEM 'bar'>\n" 10044543ef51SXin LI "%e1;\n"; 10054543ef51SXin LI const char *text2 = "<!ATTLIST doc a1 CDATA 'value'>"; 10064543ef51SXin LI XML_Parser ext_parser; 10074543ef51SXin LI 10084543ef51SXin LI UNUSED_P(base); 10094543ef51SXin LI UNUSED_P(publicId); 10104543ef51SXin LI if (systemId == NULL) 10114543ef51SXin LI return XML_STATUS_OK; 10124543ef51SXin LI ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 10134543ef51SXin LI if (ext_parser == NULL) 10144543ef51SXin LI fail("Could not create external entity parser"); 10154543ef51SXin LI if (! xcstrcmp(systemId, XCS("foo"))) { 10164543ef51SXin LI XML_SetNotStandaloneHandler(ext_parser, reject_not_standalone_handler); 10174543ef51SXin LI if (_XML_Parse_SINGLE_BYTES(ext_parser, text1, (int)strlen(text1), XML_TRUE) 10184543ef51SXin LI != XML_STATUS_ERROR) 10194543ef51SXin LI fail("Expected not standalone rejection"); 10204543ef51SXin LI if (XML_GetErrorCode(ext_parser) != XML_ERROR_NOT_STANDALONE) 10214543ef51SXin LI xml_failure(ext_parser); 10224543ef51SXin LI XML_SetNotStandaloneHandler(ext_parser, NULL); 10234543ef51SXin LI XML_ParserFree(ext_parser); 10244543ef51SXin LI return XML_STATUS_ERROR; 10254543ef51SXin LI } else if (! xcstrcmp(systemId, XCS("bar"))) { 10264543ef51SXin LI if (_XML_Parse_SINGLE_BYTES(ext_parser, text2, (int)strlen(text2), XML_TRUE) 10274543ef51SXin LI == XML_STATUS_ERROR) 10284543ef51SXin LI xml_failure(ext_parser); 10294543ef51SXin LI } 10304543ef51SXin LI 10314543ef51SXin LI XML_ParserFree(ext_parser); 10324543ef51SXin LI return XML_STATUS_OK; 10334543ef51SXin LI } 10344543ef51SXin LI 10354543ef51SXin LI int XMLCALL 10364543ef51SXin LI external_entity_value_aborter(XML_Parser parser, const XML_Char *context, 10374543ef51SXin LI const XML_Char *base, const XML_Char *systemId, 10384543ef51SXin LI const XML_Char *publicId) { 10394543ef51SXin LI const char *text1 = "<!ELEMENT doc EMPTY>\n" 10404543ef51SXin LI "<!ENTITY % e1 SYSTEM '004-2.ent'>\n" 10414543ef51SXin LI "<!ENTITY % e2 '%e1;'>\n" 10424543ef51SXin LI "%e1;\n"; 10434543ef51SXin LI const char *text2 = "<?xml version='1.0' encoding='utf-8'?>"; 10444543ef51SXin LI XML_Parser ext_parser; 10454543ef51SXin LI 10464543ef51SXin LI UNUSED_P(base); 10474543ef51SXin LI UNUSED_P(publicId); 10484543ef51SXin LI if (systemId == NULL) 10494543ef51SXin LI return XML_STATUS_OK; 10504543ef51SXin LI ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 10514543ef51SXin LI if (ext_parser == NULL) 10524543ef51SXin LI fail("Could not create external entity parser"); 10534543ef51SXin LI if (! xcstrcmp(systemId, XCS("004-1.ent"))) { 10544543ef51SXin LI if (_XML_Parse_SINGLE_BYTES(ext_parser, text1, (int)strlen(text1), XML_TRUE) 10554543ef51SXin LI == XML_STATUS_ERROR) 10564543ef51SXin LI xml_failure(ext_parser); 10574543ef51SXin LI } 10584543ef51SXin LI if (! xcstrcmp(systemId, XCS("004-2.ent"))) { 10594543ef51SXin LI XML_SetXmlDeclHandler(ext_parser, entity_suspending_xdecl_handler); 10604543ef51SXin LI XML_SetUserData(ext_parser, ext_parser); 10614543ef51SXin LI if (_XML_Parse_SINGLE_BYTES(ext_parser, text2, (int)strlen(text2), XML_TRUE) 10624543ef51SXin LI != XML_STATUS_ERROR) 10634543ef51SXin LI fail("Aborted parse not faulted"); 10644543ef51SXin LI if (XML_GetErrorCode(ext_parser) != XML_ERROR_ABORTED) 10654543ef51SXin LI xml_failure(ext_parser); 10664543ef51SXin LI } 10674543ef51SXin LI 10684543ef51SXin LI XML_ParserFree(ext_parser); 10694543ef51SXin LI return XML_STATUS_OK; 10704543ef51SXin LI } 10714543ef51SXin LI 10724543ef51SXin LI int XMLCALL 10734543ef51SXin LI external_entity_public(XML_Parser parser, const XML_Char *context, 10744543ef51SXin LI const XML_Char *base, const XML_Char *systemId, 10754543ef51SXin LI const XML_Char *publicId) { 10764543ef51SXin LI const char *text1 = (const char *)XML_GetUserData(parser); 10774543ef51SXin LI const char *text2 = "<!ATTLIST doc a CDATA 'value'>"; 10784543ef51SXin LI const char *text = NULL; 10794543ef51SXin LI XML_Parser ext_parser; 10804543ef51SXin LI int parse_res; 10814543ef51SXin LI 10824543ef51SXin LI UNUSED_P(base); 10834543ef51SXin LI ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 10844543ef51SXin LI if (ext_parser == NULL) 10854543ef51SXin LI return XML_STATUS_ERROR; 10864543ef51SXin LI if (systemId != NULL && ! xcstrcmp(systemId, XCS("http://example.org/"))) { 10874543ef51SXin LI text = text1; 10884543ef51SXin LI } else if (publicId != NULL && ! xcstrcmp(publicId, XCS("foo"))) { 10894543ef51SXin LI text = text2; 10904543ef51SXin LI } else 10914543ef51SXin LI fail("Unexpected parameters to external entity parser"); 10924543ef51SXin LI assert(text != NULL); 10934543ef51SXin LI parse_res 10944543ef51SXin LI = _XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE); 10954543ef51SXin LI XML_ParserFree(ext_parser); 10964543ef51SXin LI return parse_res; 10974543ef51SXin LI } 10984543ef51SXin LI 10994543ef51SXin LI int XMLCALL 11004543ef51SXin LI external_entity_devaluer(XML_Parser parser, const XML_Char *context, 11014543ef51SXin LI const XML_Char *base, const XML_Char *systemId, 11024543ef51SXin LI const XML_Char *publicId) { 11034543ef51SXin LI const char *text = "<!ELEMENT doc EMPTY>\n" 11044543ef51SXin LI "<!ENTITY % e1 SYSTEM 'bar'>\n" 11054543ef51SXin LI "%e1;\n"; 11064543ef51SXin LI XML_Parser ext_parser; 11074543ef51SXin LI int clear_handler_flag = (XML_GetUserData(parser) != NULL); 11084543ef51SXin LI 11094543ef51SXin LI UNUSED_P(base); 11104543ef51SXin LI UNUSED_P(publicId); 11114543ef51SXin LI if (systemId == NULL || ! xcstrcmp(systemId, XCS("bar"))) 11124543ef51SXin LI return XML_STATUS_OK; 11134543ef51SXin LI if (xcstrcmp(systemId, XCS("foo"))) 11144543ef51SXin LI fail("Unexpected system ID"); 11154543ef51SXin LI ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 11164543ef51SXin LI if (ext_parser == NULL) 11174543ef51SXin LI fail("Could note create external entity parser"); 11184543ef51SXin LI if (clear_handler_flag) 11194543ef51SXin LI XML_SetExternalEntityRefHandler(ext_parser, NULL); 11204543ef51SXin LI if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE) 11214543ef51SXin LI == XML_STATUS_ERROR) 11224543ef51SXin LI xml_failure(ext_parser); 11234543ef51SXin LI 11244543ef51SXin LI XML_ParserFree(ext_parser); 11254543ef51SXin LI return XML_STATUS_OK; 11264543ef51SXin LI } 11274543ef51SXin LI 11284543ef51SXin LI int XMLCALL 11294543ef51SXin LI external_entity_oneshot_loader(XML_Parser parser, const XML_Char *context, 11304543ef51SXin LI const XML_Char *base, const XML_Char *systemId, 11314543ef51SXin LI const XML_Char *publicId) { 11324543ef51SXin LI ExtHdlrData *test_data = (ExtHdlrData *)XML_GetUserData(parser); 11334543ef51SXin LI XML_Parser ext_parser; 11344543ef51SXin LI 11354543ef51SXin LI UNUSED_P(base); 11364543ef51SXin LI UNUSED_P(systemId); 11374543ef51SXin LI UNUSED_P(publicId); 11384543ef51SXin LI ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 11394543ef51SXin LI if (ext_parser == NULL) 11404543ef51SXin LI fail("Could not create external entity parser."); 11414543ef51SXin LI /* Use the requested entity parser for further externals */ 11424543ef51SXin LI XML_SetExternalEntityRefHandler(ext_parser, test_data->handler); 11434543ef51SXin LI if (_XML_Parse_SINGLE_BYTES(ext_parser, test_data->parse_text, 11444543ef51SXin LI (int)strlen(test_data->parse_text), XML_TRUE) 11454543ef51SXin LI == XML_STATUS_ERROR) { 11464543ef51SXin LI xml_failure(ext_parser); 11474543ef51SXin LI } 11484543ef51SXin LI 11494543ef51SXin LI XML_ParserFree(ext_parser); 11504543ef51SXin LI return XML_STATUS_OK; 11514543ef51SXin LI } 11524543ef51SXin LI 11534543ef51SXin LI int XMLCALL 11544543ef51SXin LI external_entity_loader2(XML_Parser parser, const XML_Char *context, 11554543ef51SXin LI const XML_Char *base, const XML_Char *systemId, 11564543ef51SXin LI const XML_Char *publicId) { 11574543ef51SXin LI ExtTest2 *test_data = (ExtTest2 *)XML_GetUserData(parser); 11584543ef51SXin LI XML_Parser extparser; 11594543ef51SXin LI 11604543ef51SXin LI UNUSED_P(base); 11614543ef51SXin LI UNUSED_P(systemId); 11624543ef51SXin LI UNUSED_P(publicId); 11634543ef51SXin LI extparser = XML_ExternalEntityParserCreate(parser, context, NULL); 11644543ef51SXin LI if (extparser == NULL) 11654543ef51SXin LI fail("Coulr not create external entity parser"); 11664543ef51SXin LI if (test_data->encoding != NULL) { 11674543ef51SXin LI if (! XML_SetEncoding(extparser, test_data->encoding)) 11684543ef51SXin LI fail("XML_SetEncoding() ignored for external entity"); 11694543ef51SXin LI } 11704543ef51SXin LI if (_XML_Parse_SINGLE_BYTES(extparser, test_data->parse_text, 11714543ef51SXin LI test_data->parse_len, XML_TRUE) 11724543ef51SXin LI == XML_STATUS_ERROR) { 11734543ef51SXin LI xml_failure(extparser); 11744543ef51SXin LI } 11754543ef51SXin LI 11764543ef51SXin LI XML_ParserFree(extparser); 11774543ef51SXin LI return XML_STATUS_OK; 11784543ef51SXin LI } 11794543ef51SXin LI 11804543ef51SXin LI int XMLCALL 11814543ef51SXin LI external_entity_faulter2(XML_Parser parser, const XML_Char *context, 11824543ef51SXin LI const XML_Char *base, const XML_Char *systemId, 11834543ef51SXin LI const XML_Char *publicId) { 11844543ef51SXin LI ExtFaults2 *test_data = (ExtFaults2 *)XML_GetUserData(parser); 11854543ef51SXin LI XML_Parser extparser; 11864543ef51SXin LI 11874543ef51SXin LI UNUSED_P(base); 11884543ef51SXin LI UNUSED_P(systemId); 11894543ef51SXin LI UNUSED_P(publicId); 11904543ef51SXin LI extparser = XML_ExternalEntityParserCreate(parser, context, NULL); 11914543ef51SXin LI if (extparser == NULL) 11924543ef51SXin LI fail("Could not create external entity parser"); 11934543ef51SXin LI if (test_data->encoding != NULL) { 11944543ef51SXin LI if (! XML_SetEncoding(extparser, test_data->encoding)) 11954543ef51SXin LI fail("XML_SetEncoding() ignored for external entity"); 11964543ef51SXin LI } 11974543ef51SXin LI if (_XML_Parse_SINGLE_BYTES(extparser, test_data->parse_text, 11984543ef51SXin LI test_data->parse_len, XML_TRUE) 11994543ef51SXin LI != XML_STATUS_ERROR) 12004543ef51SXin LI fail(test_data->fail_text); 12014543ef51SXin LI if (XML_GetErrorCode(extparser) != test_data->error) 12024543ef51SXin LI xml_failure(extparser); 12034543ef51SXin LI 12044543ef51SXin LI XML_ParserFree(extparser); 12054543ef51SXin LI return XML_STATUS_ERROR; 12064543ef51SXin LI } 12074543ef51SXin LI 12084543ef51SXin LI int XMLCALL 12094543ef51SXin LI external_entity_unfinished_attlist(XML_Parser parser, const XML_Char *context, 12104543ef51SXin LI const XML_Char *base, 12114543ef51SXin LI const XML_Char *systemId, 12124543ef51SXin LI const XML_Char *publicId) { 12134543ef51SXin LI const char *text = "<!ELEMENT barf ANY>\n" 12144543ef51SXin LI "<!ATTLIST barf my_attr (blah|%blah;a|foo) #REQUIRED>\n" 12154543ef51SXin LI "<!--COMMENT-->\n"; 12164543ef51SXin LI XML_Parser ext_parser; 12174543ef51SXin LI 12184543ef51SXin LI UNUSED_P(base); 12194543ef51SXin LI UNUSED_P(publicId); 12204543ef51SXin LI if (systemId == NULL) 12214543ef51SXin LI return XML_STATUS_OK; 12224543ef51SXin LI 12234543ef51SXin LI ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 12244543ef51SXin LI if (ext_parser == NULL) 12254543ef51SXin LI fail("Could not create external entity parser"); 12264543ef51SXin LI 12274543ef51SXin LI if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE) 12284543ef51SXin LI == XML_STATUS_ERROR) 12294543ef51SXin LI xml_failure(ext_parser); 12304543ef51SXin LI 12314543ef51SXin LI XML_ParserFree(ext_parser); 12324543ef51SXin LI return XML_STATUS_OK; 12334543ef51SXin LI } 12344543ef51SXin LI 12354543ef51SXin LI int XMLCALL 12364543ef51SXin LI external_entity_handler(XML_Parser parser, const XML_Char *context, 12374543ef51SXin LI const XML_Char *base, const XML_Char *systemId, 12384543ef51SXin LI const XML_Char *publicId) { 12394543ef51SXin LI void *user_data = XML_GetUserData(parser); 12404543ef51SXin LI const char *text; 12414543ef51SXin LI XML_Parser p2; 12424543ef51SXin LI 12434543ef51SXin LI UNUSED_P(base); 12444543ef51SXin LI UNUSED_P(systemId); 12454543ef51SXin LI UNUSED_P(publicId); 12464543ef51SXin LI if (user_data == NULL) 12474543ef51SXin LI text = ("<!ELEMENT doc (e+)>\n" 12484543ef51SXin LI "<!ATTLIST doc xmlns CDATA #IMPLIED>\n" 12494543ef51SXin LI "<!ELEMENT e EMPTY>\n"); 12504543ef51SXin LI else 12514543ef51SXin LI text = ("<?xml version='1.0' encoding='us-ascii'?>" 12524543ef51SXin LI "<e/>"); 12534543ef51SXin LI 12544543ef51SXin LI /* Set user data to any non-NULL value */ 12554543ef51SXin LI XML_SetUserData(parser, parser); 12564543ef51SXin LI p2 = XML_ExternalEntityParserCreate(parser, context, NULL); 12574543ef51SXin LI if (_XML_Parse_SINGLE_BYTES(p2, text, (int)strlen(text), XML_TRUE) 12584543ef51SXin LI == XML_STATUS_ERROR) { 12594543ef51SXin LI xml_failure(p2); 12604543ef51SXin LI return XML_STATUS_ERROR; 12614543ef51SXin LI } 12624543ef51SXin LI XML_ParserFree(p2); 12634543ef51SXin LI return XML_STATUS_OK; 12644543ef51SXin LI } 12654543ef51SXin LI 12664543ef51SXin LI int XMLCALL 12674543ef51SXin LI external_entity_duff_loader(XML_Parser parser, const XML_Char *context, 12684543ef51SXin LI const XML_Char *base, const XML_Char *systemId, 12694543ef51SXin LI const XML_Char *publicId) { 12704543ef51SXin LI XML_Parser new_parser; 12714543ef51SXin LI unsigned int i; 12724543ef51SXin LI const unsigned int max_alloc_count = 10; 12734543ef51SXin LI 12744543ef51SXin LI UNUSED_P(base); 12754543ef51SXin LI UNUSED_P(systemId); 12764543ef51SXin LI UNUSED_P(publicId); 12774543ef51SXin LI /* Try a few different allocation levels */ 12784543ef51SXin LI for (i = 0; i < max_alloc_count; i++) { 12794543ef51SXin LI g_allocation_count = i; 12804543ef51SXin LI new_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 12814543ef51SXin LI if (new_parser != NULL) { 12824543ef51SXin LI XML_ParserFree(new_parser); 12834543ef51SXin LI break; 12844543ef51SXin LI } 12854543ef51SXin LI } 12864543ef51SXin LI if (i == 0) 12874543ef51SXin LI fail("External parser creation ignored failing allocator"); 12884543ef51SXin LI else if (i == max_alloc_count) 12894543ef51SXin LI fail("Extern parser not created with max allocation count"); 12904543ef51SXin LI 12914543ef51SXin LI /* Make sure other random allocation doesn't now fail */ 12924543ef51SXin LI g_allocation_count = ALLOC_ALWAYS_SUCCEED; 12934543ef51SXin LI 12944543ef51SXin LI /* Make sure the failure code path is executed too */ 12954543ef51SXin LI return XML_STATUS_ERROR; 12964543ef51SXin LI } 12974543ef51SXin LI 12984543ef51SXin LI int XMLCALL 12994543ef51SXin LI external_entity_dbl_handler(XML_Parser parser, const XML_Char *context, 13004543ef51SXin LI const XML_Char *base, const XML_Char *systemId, 13014543ef51SXin LI const XML_Char *publicId) { 13024543ef51SXin LI int *pcallno = (int *)XML_GetUserData(parser); 13034543ef51SXin LI int callno = *pcallno; 13044543ef51SXin LI const char *text; 13054543ef51SXin LI XML_Parser new_parser = NULL; 13064543ef51SXin LI int i; 13074543ef51SXin LI const int max_alloc_count = 20; 13084543ef51SXin LI 13094543ef51SXin LI UNUSED_P(base); 13104543ef51SXin LI UNUSED_P(systemId); 13114543ef51SXin LI UNUSED_P(publicId); 13124543ef51SXin LI if (callno == 0) { 13134543ef51SXin LI /* First time through, check how many calls to malloc occur */ 13144543ef51SXin LI text = ("<!ELEMENT doc (e+)>\n" 13154543ef51SXin LI "<!ATTLIST doc xmlns CDATA #IMPLIED>\n" 13164543ef51SXin LI "<!ELEMENT e EMPTY>\n"); 13174543ef51SXin LI g_allocation_count = 10000; 13184543ef51SXin LI new_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 13194543ef51SXin LI if (new_parser == NULL) { 13204543ef51SXin LI fail("Unable to allocate first external parser"); 13214543ef51SXin LI return XML_STATUS_ERROR; 13224543ef51SXin LI } 13234543ef51SXin LI /* Stash the number of calls in the user data */ 13244543ef51SXin LI *pcallno = 10000 - g_allocation_count; 13254543ef51SXin LI } else { 13264543ef51SXin LI text = ("<?xml version='1.0' encoding='us-ascii'?>" 13274543ef51SXin LI "<e/>"); 13284543ef51SXin LI /* Try at varying levels to exercise more code paths */ 13294543ef51SXin LI for (i = 0; i < max_alloc_count; i++) { 13304543ef51SXin LI g_allocation_count = callno + i; 13314543ef51SXin LI new_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 13324543ef51SXin LI if (new_parser != NULL) 13334543ef51SXin LI break; 13344543ef51SXin LI } 13354543ef51SXin LI if (i == 0) { 13364543ef51SXin LI fail("Second external parser unexpectedly created"); 13374543ef51SXin LI XML_ParserFree(new_parser); 13384543ef51SXin LI return XML_STATUS_ERROR; 13394543ef51SXin LI } else if (i == max_alloc_count) { 13404543ef51SXin LI fail("Second external parser not created"); 13414543ef51SXin LI return XML_STATUS_ERROR; 13424543ef51SXin LI } 13434543ef51SXin LI } 13444543ef51SXin LI 13454543ef51SXin LI g_allocation_count = ALLOC_ALWAYS_SUCCEED; 13464543ef51SXin LI if (_XML_Parse_SINGLE_BYTES(new_parser, text, (int)strlen(text), XML_TRUE) 13474543ef51SXin LI == XML_STATUS_ERROR) { 13484543ef51SXin LI xml_failure(new_parser); 13494543ef51SXin LI return XML_STATUS_ERROR; 13504543ef51SXin LI } 13514543ef51SXin LI XML_ParserFree(new_parser); 13524543ef51SXin LI return XML_STATUS_OK; 13534543ef51SXin LI } 13544543ef51SXin LI 13554543ef51SXin LI int XMLCALL 13564543ef51SXin LI external_entity_dbl_handler_2(XML_Parser parser, const XML_Char *context, 13574543ef51SXin LI const XML_Char *base, const XML_Char *systemId, 13584543ef51SXin LI const XML_Char *publicId) { 13594543ef51SXin LI int *pcallno = (int *)XML_GetUserData(parser); 13604543ef51SXin LI int callno = *pcallno; 13614543ef51SXin LI const char *text; 13624543ef51SXin LI XML_Parser new_parser; 13634543ef51SXin LI enum XML_Status rv; 13644543ef51SXin LI 13654543ef51SXin LI UNUSED_P(base); 13664543ef51SXin LI UNUSED_P(systemId); 13674543ef51SXin LI UNUSED_P(publicId); 13684543ef51SXin LI if (callno == 0) { 13694543ef51SXin LI /* Try different allocation levels for whole exercise */ 13704543ef51SXin LI text = ("<!ELEMENT doc (e+)>\n" 13714543ef51SXin LI "<!ATTLIST doc xmlns CDATA #IMPLIED>\n" 13724543ef51SXin LI "<!ELEMENT e EMPTY>\n"); 13734543ef51SXin LI *pcallno = 1; 13744543ef51SXin LI new_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 13754543ef51SXin LI if (new_parser == NULL) 13764543ef51SXin LI return XML_STATUS_ERROR; 13774543ef51SXin LI rv = _XML_Parse_SINGLE_BYTES(new_parser, text, (int)strlen(text), XML_TRUE); 13784543ef51SXin LI } else { 13794543ef51SXin LI /* Just run through once */ 13804543ef51SXin LI text = ("<?xml version='1.0' encoding='us-ascii'?>" 13814543ef51SXin LI "<e/>"); 13824543ef51SXin LI new_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 13834543ef51SXin LI if (new_parser == NULL) 13844543ef51SXin LI return XML_STATUS_ERROR; 13854543ef51SXin LI rv = _XML_Parse_SINGLE_BYTES(new_parser, text, (int)strlen(text), XML_TRUE); 13864543ef51SXin LI } 13874543ef51SXin LI XML_ParserFree(new_parser); 13884543ef51SXin LI if (rv == XML_STATUS_ERROR) 13894543ef51SXin LI return XML_STATUS_ERROR; 13904543ef51SXin LI return XML_STATUS_OK; 13914543ef51SXin LI } 13924543ef51SXin LI 13934543ef51SXin LI int XMLCALL 13944543ef51SXin LI external_entity_alloc_set_encoding(XML_Parser parser, const XML_Char *context, 13954543ef51SXin LI const XML_Char *base, 13964543ef51SXin LI const XML_Char *systemId, 13974543ef51SXin LI const XML_Char *publicId) { 13984543ef51SXin LI /* As for external_entity_loader() */ 13994543ef51SXin LI const char *text = "<?xml encoding='iso-8859-3'?>" 14004543ef51SXin LI "\xC3\xA9"; 14014543ef51SXin LI XML_Parser ext_parser; 14024543ef51SXin LI enum XML_Status status; 14034543ef51SXin LI 14044543ef51SXin LI UNUSED_P(base); 14054543ef51SXin LI UNUSED_P(systemId); 14064543ef51SXin LI UNUSED_P(publicId); 14074543ef51SXin LI ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 14084543ef51SXin LI if (ext_parser == NULL) 14094543ef51SXin LI return XML_STATUS_ERROR; 14104543ef51SXin LI if (! XML_SetEncoding(ext_parser, XCS("utf-8"))) { 14114543ef51SXin LI XML_ParserFree(ext_parser); 14124543ef51SXin LI return XML_STATUS_ERROR; 14134543ef51SXin LI } 14144543ef51SXin LI status 14154543ef51SXin LI = _XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE); 14164543ef51SXin LI XML_ParserFree(ext_parser); 14174543ef51SXin LI if (status == XML_STATUS_ERROR) 14184543ef51SXin LI return XML_STATUS_ERROR; 14194543ef51SXin LI return XML_STATUS_OK; 14204543ef51SXin LI } 14214543ef51SXin LI 14224543ef51SXin LI int XMLCALL 14234543ef51SXin LI external_entity_reallocator(XML_Parser parser, const XML_Char *context, 14244543ef51SXin LI const XML_Char *base, const XML_Char *systemId, 14254543ef51SXin LI const XML_Char *publicId) { 14264543ef51SXin LI const char *text = get_buffer_test_text; 14274543ef51SXin LI XML_Parser ext_parser; 14284543ef51SXin LI void *buffer; 14294543ef51SXin LI enum XML_Status status; 14304543ef51SXin LI 14314543ef51SXin LI UNUSED_P(base); 14324543ef51SXin LI UNUSED_P(systemId); 14334543ef51SXin LI UNUSED_P(publicId); 14344543ef51SXin LI ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 14354543ef51SXin LI if (ext_parser == NULL) 14364543ef51SXin LI fail("Could not create external entity parser"); 14374543ef51SXin LI 14384543ef51SXin LI g_reallocation_count = *(int *)XML_GetUserData(parser); 14394543ef51SXin LI buffer = XML_GetBuffer(ext_parser, 1536); 14404543ef51SXin LI if (buffer == NULL) 14414543ef51SXin LI fail("Buffer allocation failed"); 14424543ef51SXin LI assert(buffer != NULL); 14434543ef51SXin LI memcpy(buffer, text, strlen(text)); 14444543ef51SXin LI status = XML_ParseBuffer(ext_parser, (int)strlen(text), XML_FALSE); 14454543ef51SXin LI g_reallocation_count = -1; 14464543ef51SXin LI XML_ParserFree(ext_parser); 14474543ef51SXin LI return (status == XML_STATUS_OK) ? XML_STATUS_OK : XML_STATUS_ERROR; 14484543ef51SXin LI } 14494543ef51SXin LI 14504543ef51SXin LI int XMLCALL 14514543ef51SXin LI external_entity_alloc(XML_Parser parser, const XML_Char *context, 14524543ef51SXin LI const XML_Char *base, const XML_Char *systemId, 14534543ef51SXin LI const XML_Char *publicId) { 14544543ef51SXin LI const char *text = (const char *)XML_GetUserData(parser); 14554543ef51SXin LI XML_Parser ext_parser; 14564543ef51SXin LI int parse_res; 14574543ef51SXin LI 14584543ef51SXin LI UNUSED_P(base); 14594543ef51SXin LI UNUSED_P(systemId); 14604543ef51SXin LI UNUSED_P(publicId); 14614543ef51SXin LI ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 14624543ef51SXin LI if (ext_parser == NULL) 14634543ef51SXin LI return XML_STATUS_ERROR; 14644543ef51SXin LI parse_res 14654543ef51SXin LI = _XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE); 14664543ef51SXin LI XML_ParserFree(ext_parser); 14674543ef51SXin LI return parse_res; 14684543ef51SXin LI } 14694543ef51SXin LI 14704543ef51SXin LI int XMLCALL 14714543ef51SXin LI external_entity_parser_create_alloc_fail_handler(XML_Parser parser, 14724543ef51SXin LI const XML_Char *context, 14734543ef51SXin LI const XML_Char *base, 14744543ef51SXin LI const XML_Char *systemId, 14754543ef51SXin LI const XML_Char *publicId) { 14764543ef51SXin LI UNUSED_P(base); 14774543ef51SXin LI UNUSED_P(systemId); 14784543ef51SXin LI UNUSED_P(publicId); 14794543ef51SXin LI 14804543ef51SXin LI if (context != NULL) 14814543ef51SXin LI fail("Unexpected non-NULL context"); 14824543ef51SXin LI 14834543ef51SXin LI // The following number intends to fail the upcoming allocation in line 14844543ef51SXin LI // "parser->m_protocolEncodingName = copyString(encodingName, 14854543ef51SXin LI // &(parser->m_mem));" in function parserInit. 14864543ef51SXin LI g_allocation_count = 3; 14874543ef51SXin LI 14884543ef51SXin LI const XML_Char *const encodingName = XCS("UTF-8"); // needs something non-NULL 14894543ef51SXin LI const XML_Parser ext_parser 14904543ef51SXin LI = XML_ExternalEntityParserCreate(parser, context, encodingName); 14914543ef51SXin LI if (ext_parser != NULL) 14924543ef51SXin LI fail( 14934543ef51SXin LI "Call to XML_ExternalEntityParserCreate was expected to fail out-of-memory"); 14944543ef51SXin LI 14954543ef51SXin LI g_allocation_count = ALLOC_ALWAYS_SUCCEED; 14964543ef51SXin LI return XML_STATUS_ERROR; 14974543ef51SXin LI } 14984543ef51SXin LI 14994543ef51SXin LI #if XML_GE == 1 15004543ef51SXin LI int 15014543ef51SXin LI accounting_external_entity_ref_handler(XML_Parser parser, 15024543ef51SXin LI const XML_Char *context, 15034543ef51SXin LI const XML_Char *base, 15044543ef51SXin LI const XML_Char *systemId, 15054543ef51SXin LI const XML_Char *publicId) { 15064543ef51SXin LI UNUSED_P(base); 15074543ef51SXin LI UNUSED_P(publicId); 15084543ef51SXin LI 15094543ef51SXin LI const struct AccountingTestCase *const testCase 15104543ef51SXin LI = (const struct AccountingTestCase *)XML_GetUserData(parser); 15114543ef51SXin LI 15124543ef51SXin LI const char *externalText = NULL; 15134543ef51SXin LI if (xcstrcmp(systemId, XCS("first.ent")) == 0) { 15144543ef51SXin LI externalText = testCase->firstExternalText; 15154543ef51SXin LI } else if (xcstrcmp(systemId, XCS("second.ent")) == 0) { 15164543ef51SXin LI externalText = testCase->secondExternalText; 15174543ef51SXin LI } else { 15184543ef51SXin LI assert(! "systemId is neither \"first.ent\" nor \"second.ent\""); 15194543ef51SXin LI } 15204543ef51SXin LI assert(externalText); 15214543ef51SXin LI 15224543ef51SXin LI XML_Parser entParser = XML_ExternalEntityParserCreate(parser, context, 0); 15234543ef51SXin LI assert(entParser); 15244543ef51SXin LI 15254543ef51SXin LI const enum XML_Status status = _XML_Parse_SINGLE_BYTES( 15264543ef51SXin LI entParser, externalText, (int)strlen(externalText), XML_TRUE); 15274543ef51SXin LI 15284543ef51SXin LI XML_ParserFree(entParser); 15294543ef51SXin LI return status; 15304543ef51SXin LI } 15314543ef51SXin LI #endif /* XML_GE == 1 */ 15324543ef51SXin LI 15334543ef51SXin LI /* NotStandalone handlers */ 15344543ef51SXin LI 15354543ef51SXin LI int XMLCALL 15364543ef51SXin LI reject_not_standalone_handler(void *userData) { 15374543ef51SXin LI UNUSED_P(userData); 15384543ef51SXin LI return XML_STATUS_ERROR; 15394543ef51SXin LI } 15404543ef51SXin LI 15414543ef51SXin LI int XMLCALL 15424543ef51SXin LI accept_not_standalone_handler(void *userData) { 15434543ef51SXin LI UNUSED_P(userData); 15444543ef51SXin LI return XML_STATUS_OK; 15454543ef51SXin LI } 15464543ef51SXin LI 15474543ef51SXin LI /* Attribute List handlers */ 15484543ef51SXin LI void XMLCALL 15494543ef51SXin LI verify_attlist_decl_handler(void *userData, const XML_Char *element_name, 15504543ef51SXin LI const XML_Char *attr_name, 15514543ef51SXin LI const XML_Char *attr_type, 15524543ef51SXin LI const XML_Char *default_value, int is_required) { 15534543ef51SXin LI AttTest *at = (AttTest *)userData; 15544543ef51SXin LI 15554543ef51SXin LI if (xcstrcmp(element_name, at->element_name)) 15564543ef51SXin LI fail("Unexpected element name in attribute declaration"); 15574543ef51SXin LI if (xcstrcmp(attr_name, at->attr_name)) 15584543ef51SXin LI fail("Unexpected attribute name in attribute declaration"); 15594543ef51SXin LI if (xcstrcmp(attr_type, at->attr_type)) 15604543ef51SXin LI fail("Unexpected attribute type in attribute declaration"); 15614543ef51SXin LI if ((default_value == NULL && at->default_value != NULL) 15624543ef51SXin LI || (default_value != NULL && at->default_value == NULL) 15634543ef51SXin LI || (default_value != NULL && xcstrcmp(default_value, at->default_value))) 15644543ef51SXin LI fail("Unexpected default value in attribute declaration"); 15654543ef51SXin LI if (is_required != at->is_required) 15664543ef51SXin LI fail("Requirement mismatch in attribute declaration"); 15674543ef51SXin LI } 15684543ef51SXin LI 15694543ef51SXin LI /* Character Data handlers */ 15704543ef51SXin LI 15714543ef51SXin LI void XMLCALL 15724543ef51SXin LI clearing_aborting_character_handler(void *userData, const XML_Char *s, 15734543ef51SXin LI int len) { 15744543ef51SXin LI UNUSED_P(userData); 15754543ef51SXin LI UNUSED_P(s); 15764543ef51SXin LI UNUSED_P(len); 15774543ef51SXin LI XML_StopParser(g_parser, g_resumable); 15784543ef51SXin LI XML_SetCharacterDataHandler(g_parser, NULL); 15794543ef51SXin LI } 15804543ef51SXin LI 15814543ef51SXin LI void XMLCALL 15824543ef51SXin LI parser_stop_character_handler(void *userData, const XML_Char *s, int len) { 15834543ef51SXin LI UNUSED_P(userData); 15844543ef51SXin LI UNUSED_P(s); 15854543ef51SXin LI UNUSED_P(len); 15864543ef51SXin LI XML_ParsingStatus status; 15874543ef51SXin LI XML_GetParsingStatus(g_parser, &status); 15884543ef51SXin LI if (status.parsing == XML_FINISHED) { 15894543ef51SXin LI return; // the parser was stopped by a previous call to this handler. 15904543ef51SXin LI } 15914543ef51SXin LI XML_StopParser(g_parser, g_resumable); 15924543ef51SXin LI XML_SetCharacterDataHandler(g_parser, NULL); 15934543ef51SXin LI if (! g_resumable) { 15944543ef51SXin LI /* Check that aborting an aborted parser is faulted */ 15954543ef51SXin LI if (XML_StopParser(g_parser, XML_FALSE) != XML_STATUS_ERROR) 15964543ef51SXin LI fail("Aborting aborted parser not faulted"); 15974543ef51SXin LI if (XML_GetErrorCode(g_parser) != XML_ERROR_FINISHED) 15984543ef51SXin LI xml_failure(g_parser); 15994543ef51SXin LI } else if (g_abortable) { 16004543ef51SXin LI /* Check that aborting a suspended parser works */ 16014543ef51SXin LI if (XML_StopParser(g_parser, XML_FALSE) == XML_STATUS_ERROR) 16024543ef51SXin LI xml_failure(g_parser); 16034543ef51SXin LI } else { 16044543ef51SXin LI /* Check that suspending a suspended parser works */ 16054543ef51SXin LI if (XML_StopParser(g_parser, XML_TRUE) != XML_STATUS_ERROR) 16064543ef51SXin LI fail("Suspending suspended parser not faulted"); 16074543ef51SXin LI if (XML_GetErrorCode(g_parser) != XML_ERROR_SUSPENDED) 16084543ef51SXin LI xml_failure(g_parser); 16094543ef51SXin LI } 16104543ef51SXin LI } 16114543ef51SXin LI 16124543ef51SXin LI void XMLCALL 16134543ef51SXin LI cr_cdata_handler(void *userData, const XML_Char *s, int len) { 16144543ef51SXin LI int *pfound = (int *)userData; 16154543ef51SXin LI 16164543ef51SXin LI /* Internal processing turns the CR into a newline for the 16174543ef51SXin LI * character data handler, but not for the default handler 16184543ef51SXin LI */ 16194543ef51SXin LI if (len == 1 && (*s == XCS('\n') || *s == XCS('\r'))) 16204543ef51SXin LI *pfound = 1; 16214543ef51SXin LI } 16224543ef51SXin LI 16234543ef51SXin LI void XMLCALL 16244543ef51SXin LI rsqb_handler(void *userData, const XML_Char *s, int len) { 16254543ef51SXin LI int *pfound = (int *)userData; 16264543ef51SXin LI 16274543ef51SXin LI if (len == 1 && *s == XCS(']')) 16284543ef51SXin LI *pfound = 1; 16294543ef51SXin LI } 16304543ef51SXin LI 16314543ef51SXin LI void XMLCALL 16324543ef51SXin LI byte_character_handler(void *userData, const XML_Char *s, int len) { 16334543ef51SXin LI #if XML_CONTEXT_BYTES > 0 16344543ef51SXin LI int offset, size; 16354543ef51SXin LI const char *buffer; 16364543ef51SXin LI ByteTestData *data = (ByteTestData *)userData; 16374543ef51SXin LI 16384543ef51SXin LI UNUSED_P(s); 16394543ef51SXin LI buffer = XML_GetInputContext(g_parser, &offset, &size); 16404543ef51SXin LI if (buffer == NULL) 16414543ef51SXin LI fail("Failed to get context buffer"); 16424543ef51SXin LI if (offset != data->start_element_len) 16434543ef51SXin LI fail("Context offset in unexpected position"); 16444543ef51SXin LI if (len != data->cdata_len) 16454543ef51SXin LI fail("CDATA length reported incorrectly"); 16464543ef51SXin LI if (size != data->total_string_len) 16474543ef51SXin LI fail("Context size is not full buffer"); 16484543ef51SXin LI if (XML_GetCurrentByteIndex(g_parser) != offset) 16494543ef51SXin LI fail("Character byte index incorrect"); 16504543ef51SXin LI if (XML_GetCurrentByteCount(g_parser) != len) 16514543ef51SXin LI fail("Character byte count incorrect"); 16524543ef51SXin LI #else 16534543ef51SXin LI UNUSED_P(s); 16544543ef51SXin LI UNUSED_P(userData); 16554543ef51SXin LI UNUSED_P(len); 16564543ef51SXin LI #endif 16574543ef51SXin LI } 16584543ef51SXin LI 16594543ef51SXin LI void XMLCALL 16604543ef51SXin LI ext2_accumulate_characters(void *userData, const XML_Char *s, int len) { 16614543ef51SXin LI ExtTest2 *test_data = (ExtTest2 *)userData; 16624543ef51SXin LI accumulate_characters(test_data->storage, s, len); 16634543ef51SXin LI } 16644543ef51SXin LI 16654543ef51SXin LI /* Handlers that record their function name and int arg. */ 16664543ef51SXin LI 16674543ef51SXin LI static void 16684543ef51SXin LI record_call(struct handler_record_list *const rec, const char *funcname, 16694543ef51SXin LI const int arg) { 16704543ef51SXin LI const int max_entries = sizeof(rec->entries) / sizeof(rec->entries[0]); 16714543ef51SXin LI assert_true(rec->count < max_entries); 16724543ef51SXin LI struct handler_record_entry *const e = &rec->entries[rec->count++]; 16734543ef51SXin LI e->name = funcname; 16744543ef51SXin LI e->arg = arg; 16754543ef51SXin LI } 16764543ef51SXin LI 16774543ef51SXin LI void XMLCALL 16784543ef51SXin LI record_default_handler(void *userData, const XML_Char *s, int len) { 16794543ef51SXin LI UNUSED_P(s); 16804543ef51SXin LI record_call((struct handler_record_list *)userData, __func__, len); 16814543ef51SXin LI } 16824543ef51SXin LI 16834543ef51SXin LI void XMLCALL 16844543ef51SXin LI record_cdata_handler(void *userData, const XML_Char *s, int len) { 16854543ef51SXin LI UNUSED_P(s); 16864543ef51SXin LI record_call((struct handler_record_list *)userData, __func__, len); 16874543ef51SXin LI XML_DefaultCurrent(g_parser); 16884543ef51SXin LI } 16894543ef51SXin LI 16904543ef51SXin LI void XMLCALL 16914543ef51SXin LI record_cdata_nodefault_handler(void *userData, const XML_Char *s, int len) { 16924543ef51SXin LI UNUSED_P(s); 16934543ef51SXin LI record_call((struct handler_record_list *)userData, __func__, len); 16944543ef51SXin LI } 16954543ef51SXin LI 16964543ef51SXin LI void XMLCALL 16974543ef51SXin LI record_skip_handler(void *userData, const XML_Char *entityName, 16984543ef51SXin LI int is_parameter_entity) { 16994543ef51SXin LI UNUSED_P(entityName); 17004543ef51SXin LI record_call((struct handler_record_list *)userData, __func__, 17014543ef51SXin LI is_parameter_entity); 17024543ef51SXin LI } 17034543ef51SXin LI 17044543ef51SXin LI void XMLCALL 17054543ef51SXin LI record_element_start_handler(void *userData, const XML_Char *name, 17064543ef51SXin LI const XML_Char **atts) { 17074543ef51SXin LI UNUSED_P(atts); 17084543ef51SXin LI CharData_AppendXMLChars((CharData *)userData, name, (int)xcstrlen(name)); 17094543ef51SXin LI } 17104543ef51SXin LI 17114543ef51SXin LI void XMLCALL 17124543ef51SXin LI record_element_end_handler(void *userData, const XML_Char *name) { 17134543ef51SXin LI CharData *storage = (CharData *)userData; 17144543ef51SXin LI 17154543ef51SXin LI CharData_AppendXMLChars(storage, XCS("/"), 1); 17164543ef51SXin LI CharData_AppendXMLChars(storage, name, -1); 17174543ef51SXin LI } 17184543ef51SXin LI 17194543ef51SXin LI const struct handler_record_entry * 17204543ef51SXin LI _handler_record_get(const struct handler_record_list *storage, int index, 17214543ef51SXin LI const char *file, int line) { 17224543ef51SXin LI if (storage->count <= index) { 17234543ef51SXin LI _fail(file, line, "too few handler calls"); 17244543ef51SXin LI } 17254543ef51SXin LI return &storage->entries[index]; 17264543ef51SXin LI } 17274543ef51SXin LI 17284543ef51SXin LI /* Entity Declaration Handlers */ 17294543ef51SXin LI static const XML_Char *entity_name_to_match = NULL; 17304543ef51SXin LI static const XML_Char *entity_value_to_match = NULL; 17314543ef51SXin LI static int entity_match_flag = ENTITY_MATCH_NOT_FOUND; 17324543ef51SXin LI 17334543ef51SXin LI void XMLCALL 17344543ef51SXin LI param_entity_match_handler(void *userData, const XML_Char *entityName, 17354543ef51SXin LI int is_parameter_entity, const XML_Char *value, 17364543ef51SXin LI int value_length, const XML_Char *base, 17374543ef51SXin LI const XML_Char *systemId, const XML_Char *publicId, 17384543ef51SXin LI const XML_Char *notationName) { 17394543ef51SXin LI UNUSED_P(userData); 17404543ef51SXin LI UNUSED_P(base); 17414543ef51SXin LI UNUSED_P(systemId); 17424543ef51SXin LI UNUSED_P(publicId); 17434543ef51SXin LI UNUSED_P(notationName); 17444543ef51SXin LI if (! is_parameter_entity || entity_name_to_match == NULL 17454543ef51SXin LI || entity_value_to_match == NULL) { 17464543ef51SXin LI return; 17474543ef51SXin LI } 17484543ef51SXin LI if (! xcstrcmp(entityName, entity_name_to_match)) { 17494543ef51SXin LI /* The cast here is safe because we control the horizontal and 17504543ef51SXin LI * the vertical, and we therefore know our strings are never 17514543ef51SXin LI * going to overflow an int. 17524543ef51SXin LI */ 17534543ef51SXin LI if (value_length != (int)xcstrlen(entity_value_to_match) 17544543ef51SXin LI || xcstrncmp(value, entity_value_to_match, value_length)) { 17554543ef51SXin LI entity_match_flag = ENTITY_MATCH_FAIL; 17564543ef51SXin LI } else { 17574543ef51SXin LI entity_match_flag = ENTITY_MATCH_SUCCESS; 17584543ef51SXin LI } 17594543ef51SXin LI } 17604543ef51SXin LI /* Else leave the match flag alone */ 17614543ef51SXin LI } 17624543ef51SXin LI 17634543ef51SXin LI void 17644543ef51SXin LI param_entity_match_init(const XML_Char *name, const XML_Char *value) { 17654543ef51SXin LI entity_name_to_match = name; 17664543ef51SXin LI entity_value_to_match = value; 17674543ef51SXin LI entity_match_flag = ENTITY_MATCH_NOT_FOUND; 17684543ef51SXin LI } 17694543ef51SXin LI 17704543ef51SXin LI int 17714543ef51SXin LI get_param_entity_match_flag(void) { 17724543ef51SXin LI return entity_match_flag; 17734543ef51SXin LI } 17744543ef51SXin LI 17754543ef51SXin LI /* Misc handlers */ 17764543ef51SXin LI 17774543ef51SXin LI void XMLCALL 17784543ef51SXin LI xml_decl_handler(void *userData, const XML_Char *version, 17794543ef51SXin LI const XML_Char *encoding, int standalone) { 17804543ef51SXin LI UNUSED_P(version); 17814543ef51SXin LI UNUSED_P(encoding); 17824543ef51SXin LI if (userData != g_handler_data) 17834543ef51SXin LI fail("User data (xml decl) not correctly set"); 17844543ef51SXin LI if (standalone != -1) 17854543ef51SXin LI fail("Standalone not flagged as not present in XML decl"); 17864543ef51SXin LI g_xdecl_count++; 17874543ef51SXin LI } 17884543ef51SXin LI 17894543ef51SXin LI void XMLCALL 17904543ef51SXin LI param_check_skip_handler(void *userData, const XML_Char *entityName, 17914543ef51SXin LI int is_parameter_entity) { 17924543ef51SXin LI UNUSED_P(entityName); 17934543ef51SXin LI UNUSED_P(is_parameter_entity); 17944543ef51SXin LI if (userData != g_handler_data) 17954543ef51SXin LI fail("User data (skip) not correctly set"); 17964543ef51SXin LI g_skip_count++; 17974543ef51SXin LI } 17984543ef51SXin LI 17994543ef51SXin LI void XMLCALL 18004543ef51SXin LI data_check_comment_handler(void *userData, const XML_Char *data) { 18014543ef51SXin LI UNUSED_P(data); 18024543ef51SXin LI /* Check that the userData passed through is what we expect */ 18034543ef51SXin LI if (userData != g_handler_data) 18044543ef51SXin LI fail("User data (parser) not correctly set"); 18054543ef51SXin LI /* Check that the user data in the parser is appropriate */ 18064543ef51SXin LI if (XML_GetUserData(userData) != (void *)1) 18074543ef51SXin LI fail("User data in parser not correctly set"); 18084543ef51SXin LI g_comment_count++; 18094543ef51SXin LI } 18104543ef51SXin LI 18114543ef51SXin LI void XMLCALL 18124543ef51SXin LI selective_aborting_default_handler(void *userData, const XML_Char *s, int len) { 18134543ef51SXin LI const XML_Char trigger_char = *(const XML_Char *)userData; 18144543ef51SXin LI 18154543ef51SXin LI int found = 0; 18164543ef51SXin LI for (int i = 0; i < len; ++i) { 18174543ef51SXin LI if (s[i] == trigger_char) { 18184543ef51SXin LI found = 1; 18194543ef51SXin LI break; 18204543ef51SXin LI } 18214543ef51SXin LI } 18224543ef51SXin LI 18234543ef51SXin LI if (found) { 18244543ef51SXin LI XML_StopParser(g_parser, g_resumable); 18254543ef51SXin LI XML_SetDefaultHandler(g_parser, NULL); 18264543ef51SXin LI } 18274543ef51SXin LI } 18284543ef51SXin LI 18294543ef51SXin LI void XMLCALL 18304543ef51SXin LI suspending_comment_handler(void *userData, const XML_Char *data) { 18314543ef51SXin LI UNUSED_P(data); 18324543ef51SXin LI XML_Parser parser = (XML_Parser)userData; 18334543ef51SXin LI XML_StopParser(parser, XML_TRUE); 18344543ef51SXin LI } 18354543ef51SXin LI 18364543ef51SXin LI void XMLCALL 18374543ef51SXin LI element_decl_suspender(void *userData, const XML_Char *name, 18384543ef51SXin LI XML_Content *model) { 18394543ef51SXin LI UNUSED_P(userData); 18404543ef51SXin LI UNUSED_P(name); 18414543ef51SXin LI XML_StopParser(g_parser, XML_TRUE); 18424543ef51SXin LI XML_FreeContentModel(g_parser, model); 18434543ef51SXin LI } 18444543ef51SXin LI 18454543ef51SXin LI void XMLCALL 18464543ef51SXin LI accumulate_pi_characters(void *userData, const XML_Char *target, 18474543ef51SXin LI const XML_Char *data) { 18484543ef51SXin LI CharData *storage = (CharData *)userData; 18494543ef51SXin LI 18504543ef51SXin LI CharData_AppendXMLChars(storage, target, -1); 18514543ef51SXin LI CharData_AppendXMLChars(storage, XCS(": "), 2); 18524543ef51SXin LI CharData_AppendXMLChars(storage, data, -1); 18534543ef51SXin LI CharData_AppendXMLChars(storage, XCS("\n"), 1); 18544543ef51SXin LI } 18554543ef51SXin LI 18564543ef51SXin LI void XMLCALL 18574543ef51SXin LI accumulate_comment(void *userData, const XML_Char *data) { 18584543ef51SXin LI CharData *storage = (CharData *)userData; 18594543ef51SXin LI 18604543ef51SXin LI CharData_AppendXMLChars(storage, data, -1); 18614543ef51SXin LI } 18624543ef51SXin LI 18634543ef51SXin LI void XMLCALL 18644543ef51SXin LI accumulate_entity_decl(void *userData, const XML_Char *entityName, 18654543ef51SXin LI int is_parameter_entity, const XML_Char *value, 18664543ef51SXin LI int value_length, const XML_Char *base, 18674543ef51SXin LI const XML_Char *systemId, const XML_Char *publicId, 18684543ef51SXin LI const XML_Char *notationName) { 18694543ef51SXin LI CharData *storage = (CharData *)userData; 18704543ef51SXin LI 18714543ef51SXin LI UNUSED_P(is_parameter_entity); 18724543ef51SXin LI UNUSED_P(base); 18734543ef51SXin LI UNUSED_P(systemId); 18744543ef51SXin LI UNUSED_P(publicId); 18754543ef51SXin LI UNUSED_P(notationName); 18764543ef51SXin LI CharData_AppendXMLChars(storage, entityName, -1); 18774543ef51SXin LI CharData_AppendXMLChars(storage, XCS("="), 1); 18784543ef51SXin LI if (value == NULL) 18794543ef51SXin LI CharData_AppendXMLChars(storage, XCS("(null)"), -1); 18804543ef51SXin LI else 18814543ef51SXin LI CharData_AppendXMLChars(storage, value, value_length); 18824543ef51SXin LI CharData_AppendXMLChars(storage, XCS("\n"), 1); 18834543ef51SXin LI } 18844543ef51SXin LI 18854543ef51SXin LI void XMLCALL 18864543ef51SXin LI accumulate_start_element(void *userData, const XML_Char *name, 18874543ef51SXin LI const XML_Char **atts) { 18884543ef51SXin LI CharData *const storage = (CharData *)userData; 18894543ef51SXin LI CharData_AppendXMLChars(storage, XCS("("), 1); 18904543ef51SXin LI CharData_AppendXMLChars(storage, name, -1); 18914543ef51SXin LI 18924543ef51SXin LI if ((atts != NULL) && (atts[0] != NULL)) { 18934543ef51SXin LI CharData_AppendXMLChars(storage, XCS("("), 1); 18944543ef51SXin LI while (atts[0] != NULL) { 18954543ef51SXin LI CharData_AppendXMLChars(storage, atts[0], -1); 18964543ef51SXin LI CharData_AppendXMLChars(storage, XCS("="), 1); 18974543ef51SXin LI CharData_AppendXMLChars(storage, atts[1], -1); 18984543ef51SXin LI atts += 2; 18994543ef51SXin LI if (atts[0] != NULL) { 19004543ef51SXin LI CharData_AppendXMLChars(storage, XCS(","), 1); 19014543ef51SXin LI } 19024543ef51SXin LI } 19034543ef51SXin LI CharData_AppendXMLChars(storage, XCS(")"), 1); 19044543ef51SXin LI } 19054543ef51SXin LI 19064543ef51SXin LI CharData_AppendXMLChars(storage, XCS(")\n"), 2); 19074543ef51SXin LI } 19084543ef51SXin LI 19094543ef51SXin LI void XMLCALL 1910*908f215eSXin LI accumulate_characters(void *userData, const XML_Char *s, int len) { 1911*908f215eSXin LI CharData *const storage = (CharData *)userData; 1912*908f215eSXin LI CharData_AppendXMLChars(storage, s, len); 1913*908f215eSXin LI } 1914*908f215eSXin LI 1915*908f215eSXin LI void XMLCALL 1916*908f215eSXin LI accumulate_attribute(void *userData, const XML_Char *name, 1917*908f215eSXin LI const XML_Char **atts) { 1918*908f215eSXin LI CharData *const storage = (CharData *)userData; 1919*908f215eSXin LI UNUSED_P(name); 1920*908f215eSXin LI /* Check there are attributes to deal with */ 1921*908f215eSXin LI if (atts == NULL) 1922*908f215eSXin LI return; 1923*908f215eSXin LI 1924*908f215eSXin LI while (storage->count < 0 && atts[0] != NULL) { 1925*908f215eSXin LI /* "accumulate" the value of the first attribute we see */ 1926*908f215eSXin LI CharData_AppendXMLChars(storage, atts[1], -1); 1927*908f215eSXin LI atts += 2; 1928*908f215eSXin LI } 1929*908f215eSXin LI } 1930*908f215eSXin LI 1931*908f215eSXin LI void XMLCALL 1932*908f215eSXin LI ext_accumulate_characters(void *userData, const XML_Char *s, int len) { 1933*908f215eSXin LI ExtTest *const test_data = (ExtTest *)userData; 1934*908f215eSXin LI accumulate_characters(test_data->storage, s, len); 1935*908f215eSXin LI } 1936*908f215eSXin LI 1937*908f215eSXin LI void XMLCALL 19384543ef51SXin LI checking_default_handler(void *userData, const XML_Char *s, int len) { 19394543ef51SXin LI DefaultCheck *data = (DefaultCheck *)userData; 19404543ef51SXin LI int i; 19414543ef51SXin LI 19424543ef51SXin LI for (i = 0; data[i].expected != NULL; i++) { 19434543ef51SXin LI if (data[i].expectedLen == len 19444543ef51SXin LI && ! memcmp(data[i].expected, s, len * sizeof(XML_Char))) { 19454543ef51SXin LI data[i].seen = XML_TRUE; 19464543ef51SXin LI break; 19474543ef51SXin LI } 19484543ef51SXin LI } 19494543ef51SXin LI } 19504543ef51SXin LI 19514543ef51SXin LI void XMLCALL 19524543ef51SXin LI accumulate_and_suspend_comment_handler(void *userData, const XML_Char *data) { 19534543ef51SXin LI ParserPlusStorage *const parserPlusStorage = (ParserPlusStorage *)userData; 19544543ef51SXin LI accumulate_comment(parserPlusStorage->storage, data); 19554543ef51SXin LI XML_StopParser(parserPlusStorage->parser, XML_TRUE); 19564543ef51SXin LI } 1957