1bd8f1dc3Sbluhm /* XML handler functions for the Expat test suite 2bd8f1dc3Sbluhm __ __ _ 3bd8f1dc3Sbluhm ___\ \/ /_ __ __ _| |_ 4bd8f1dc3Sbluhm / _ \\ /| '_ \ / _` | __| 5bd8f1dc3Sbluhm | __// \| |_) | (_| | |_ 6bd8f1dc3Sbluhm \___/_/\_\ .__/ \__,_|\__| 7bd8f1dc3Sbluhm |_| XML parser 8bd8f1dc3Sbluhm 9bd8f1dc3Sbluhm Copyright (c) 2001-2006 Fred L. Drake, Jr. <fdrake@users.sourceforge.net> 10bd8f1dc3Sbluhm Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net> 11bd8f1dc3Sbluhm Copyright (c) 2005-2007 Steven Solie <steven@solie.ca> 12bd8f1dc3Sbluhm Copyright (c) 2005-2012 Karl Waclawek <karl@waclawek.net> 13bd8f1dc3Sbluhm Copyright (c) 2016-2024 Sebastian Pipping <sebastian@pipping.org> 14bd8f1dc3Sbluhm Copyright (c) 2017-2022 Rhodri James <rhodri@wildebeest.org.uk> 15bd8f1dc3Sbluhm Copyright (c) 2017 Joe Orton <jorton@redhat.com> 16bd8f1dc3Sbluhm Copyright (c) 2017 José Gutiérrez de la Concha <jose@zeroc.com> 17bd8f1dc3Sbluhm Copyright (c) 2018 Marco Maggi <marco.maggi-ipsu@poste.it> 18bd8f1dc3Sbluhm Copyright (c) 2019 David Loffredo <loffredo@steptools.com> 19bd8f1dc3Sbluhm Copyright (c) 2020 Tim Gates <tim.gates@iress.com> 20bd8f1dc3Sbluhm Copyright (c) 2021 Donghee Na <donghee.na@python.org> 21bd8f1dc3Sbluhm Copyright (c) 2023-2024 Sony Corporation / Snild Dolkow <snild@sony.com> 22bd8f1dc3Sbluhm Licensed under the MIT license: 23bd8f1dc3Sbluhm 24bd8f1dc3Sbluhm Permission is hereby granted, free of charge, to any person obtaining 25bd8f1dc3Sbluhm a copy of this software and associated documentation files (the 26bd8f1dc3Sbluhm "Software"), to deal in the Software without restriction, including 27bd8f1dc3Sbluhm without limitation the rights to use, copy, modify, merge, publish, 28bd8f1dc3Sbluhm distribute, sublicense, and/or sell copies of the Software, and to permit 29bd8f1dc3Sbluhm persons to whom the Software is furnished to do so, subject to the 30bd8f1dc3Sbluhm following conditions: 31bd8f1dc3Sbluhm 32bd8f1dc3Sbluhm The above copyright notice and this permission notice shall be included 33bd8f1dc3Sbluhm in all copies or substantial portions of the Software. 34bd8f1dc3Sbluhm 35bd8f1dc3Sbluhm THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 36bd8f1dc3Sbluhm EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 37bd8f1dc3Sbluhm MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 38bd8f1dc3Sbluhm NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 39bd8f1dc3Sbluhm DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 40bd8f1dc3Sbluhm OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 41bd8f1dc3Sbluhm USE OR OTHER DEALINGS IN THE SOFTWARE. 42bd8f1dc3Sbluhm */ 43bd8f1dc3Sbluhm 44bd8f1dc3Sbluhm #if defined(NDEBUG) 45bd8f1dc3Sbluhm # undef NDEBUG /* because test suite relies on assert(...) at the moment */ 46bd8f1dc3Sbluhm #endif 47bd8f1dc3Sbluhm 48bd8f1dc3Sbluhm #include <stdio.h> 49bd8f1dc3Sbluhm #include <string.h> 50bd8f1dc3Sbluhm #include <assert.h> 51bd8f1dc3Sbluhm 52bd8f1dc3Sbluhm #include "expat_config.h" 53bd8f1dc3Sbluhm 54bd8f1dc3Sbluhm #include "expat.h" 55bd8f1dc3Sbluhm #include "internal.h" 56bd8f1dc3Sbluhm #include "chardata.h" 57bd8f1dc3Sbluhm #include "structdata.h" 58bd8f1dc3Sbluhm #include "common.h" 59bd8f1dc3Sbluhm #include "handlers.h" 60bd8f1dc3Sbluhm 61bd8f1dc3Sbluhm /* Global variables for user parameter settings tests */ 62bd8f1dc3Sbluhm /* Variable holding the expected handler userData */ 63bd8f1dc3Sbluhm const void *g_handler_data = NULL; 64bd8f1dc3Sbluhm /* Count of the number of times the comment handler has been invoked */ 65bd8f1dc3Sbluhm int g_comment_count = 0; 66bd8f1dc3Sbluhm /* Count of the number of skipped entities */ 67bd8f1dc3Sbluhm int g_skip_count = 0; 68bd8f1dc3Sbluhm /* Count of the number of times the XML declaration handler is invoked */ 69bd8f1dc3Sbluhm int g_xdecl_count = 0; 70bd8f1dc3Sbluhm 71bd8f1dc3Sbluhm /* Start/End Element Handlers */ 72bd8f1dc3Sbluhm 73bd8f1dc3Sbluhm void XMLCALL 74bd8f1dc3Sbluhm start_element_event_handler(void *userData, const XML_Char *name, 75bd8f1dc3Sbluhm const XML_Char **atts) { 76bd8f1dc3Sbluhm UNUSED_P(atts); 77bd8f1dc3Sbluhm CharData_AppendXMLChars((CharData *)userData, name, -1); 78bd8f1dc3Sbluhm } 79bd8f1dc3Sbluhm 80bd8f1dc3Sbluhm void XMLCALL 81bd8f1dc3Sbluhm end_element_event_handler(void *userData, const XML_Char *name) { 82bd8f1dc3Sbluhm CharData *storage = (CharData *)userData; 83bd8f1dc3Sbluhm CharData_AppendXMLChars(storage, XCS("/"), 1); 84bd8f1dc3Sbluhm CharData_AppendXMLChars(storage, name, -1); 85bd8f1dc3Sbluhm } 86bd8f1dc3Sbluhm 87bd8f1dc3Sbluhm void XMLCALL 88bd8f1dc3Sbluhm start_element_event_handler2(void *userData, const XML_Char *name, 89bd8f1dc3Sbluhm const XML_Char **attr) { 90bd8f1dc3Sbluhm StructData *storage = (StructData *)userData; 91bd8f1dc3Sbluhm UNUSED_P(attr); 92bd8f1dc3Sbluhm StructData_AddItem(storage, name, XML_GetCurrentColumnNumber(g_parser), 93bd8f1dc3Sbluhm XML_GetCurrentLineNumber(g_parser), STRUCT_START_TAG); 94bd8f1dc3Sbluhm } 95bd8f1dc3Sbluhm 96bd8f1dc3Sbluhm void XMLCALL 97bd8f1dc3Sbluhm end_element_event_handler2(void *userData, const XML_Char *name) { 98bd8f1dc3Sbluhm StructData *storage = (StructData *)userData; 99bd8f1dc3Sbluhm StructData_AddItem(storage, name, XML_GetCurrentColumnNumber(g_parser), 100bd8f1dc3Sbluhm XML_GetCurrentLineNumber(g_parser), STRUCT_END_TAG); 101bd8f1dc3Sbluhm } 102bd8f1dc3Sbluhm 103bd8f1dc3Sbluhm void XMLCALL 104bd8f1dc3Sbluhm counting_start_element_handler(void *userData, const XML_Char *name, 105bd8f1dc3Sbluhm const XML_Char **atts) { 106*aa071e6eSbluhm ParserAndElementInfo *const parserAndElementInfos 107*aa071e6eSbluhm = (ParserAndElementInfo *)userData; 108*aa071e6eSbluhm ElementInfo *info = parserAndElementInfos->info; 109bd8f1dc3Sbluhm AttrInfo *attr; 110bd8f1dc3Sbluhm int count, id, i; 111bd8f1dc3Sbluhm 112bd8f1dc3Sbluhm while (info->name != NULL) { 113bd8f1dc3Sbluhm if (! xcstrcmp(name, info->name)) 114bd8f1dc3Sbluhm break; 115bd8f1dc3Sbluhm info++; 116bd8f1dc3Sbluhm } 117bd8f1dc3Sbluhm if (info->name == NULL) 118bd8f1dc3Sbluhm fail("Element not recognised"); 119bd8f1dc3Sbluhm /* The attribute count is twice what you might expect. It is a 120bd8f1dc3Sbluhm * count of items in atts, an array which contains alternating 121bd8f1dc3Sbluhm * attribute names and attribute values. For the naive user this 122bd8f1dc3Sbluhm * is possibly a little unexpected, but it is what the 123bd8f1dc3Sbluhm * documentation in expat.h tells us to expect. 124bd8f1dc3Sbluhm */ 125*aa071e6eSbluhm count = XML_GetSpecifiedAttributeCount(parserAndElementInfos->parser); 126bd8f1dc3Sbluhm if (info->attr_count * 2 != count) { 127bd8f1dc3Sbluhm fail("Not got expected attribute count"); 128bd8f1dc3Sbluhm return; 129bd8f1dc3Sbluhm } 130*aa071e6eSbluhm id = XML_GetIdAttributeIndex(parserAndElementInfos->parser); 131bd8f1dc3Sbluhm if (id == -1 && info->id_name != NULL) { 132bd8f1dc3Sbluhm fail("ID not present"); 133bd8f1dc3Sbluhm return; 134bd8f1dc3Sbluhm } 135bd8f1dc3Sbluhm if (id != -1 && xcstrcmp(atts[id], info->id_name)) { 136bd8f1dc3Sbluhm fail("ID does not have the correct name"); 137bd8f1dc3Sbluhm return; 138bd8f1dc3Sbluhm } 139bd8f1dc3Sbluhm for (i = 0; i < info->attr_count; i++) { 140bd8f1dc3Sbluhm attr = info->attributes; 141bd8f1dc3Sbluhm while (attr->name != NULL) { 142bd8f1dc3Sbluhm if (! xcstrcmp(atts[0], attr->name)) 143bd8f1dc3Sbluhm break; 144bd8f1dc3Sbluhm attr++; 145bd8f1dc3Sbluhm } 146bd8f1dc3Sbluhm if (attr->name == NULL) { 147bd8f1dc3Sbluhm fail("Attribute not recognised"); 148bd8f1dc3Sbluhm return; 149bd8f1dc3Sbluhm } 150bd8f1dc3Sbluhm if (xcstrcmp(atts[1], attr->value)) { 151bd8f1dc3Sbluhm fail("Attribute has wrong value"); 152bd8f1dc3Sbluhm return; 153bd8f1dc3Sbluhm } 154bd8f1dc3Sbluhm /* Remember, two entries in atts per attribute (see above) */ 155bd8f1dc3Sbluhm atts += 2; 156bd8f1dc3Sbluhm } 157bd8f1dc3Sbluhm } 158bd8f1dc3Sbluhm 159bd8f1dc3Sbluhm void XMLCALL 160bd8f1dc3Sbluhm suspending_end_handler(void *userData, const XML_Char *s) { 161bd8f1dc3Sbluhm UNUSED_P(s); 162bd8f1dc3Sbluhm XML_StopParser((XML_Parser)userData, 1); 163bd8f1dc3Sbluhm } 164bd8f1dc3Sbluhm 165bd8f1dc3Sbluhm void XMLCALL 166bd8f1dc3Sbluhm start_element_suspender(void *userData, const XML_Char *name, 167bd8f1dc3Sbluhm const XML_Char **atts) { 168bd8f1dc3Sbluhm UNUSED_P(userData); 169bd8f1dc3Sbluhm UNUSED_P(atts); 170bd8f1dc3Sbluhm if (! xcstrcmp(name, XCS("suspend"))) 171bd8f1dc3Sbluhm XML_StopParser(g_parser, XML_TRUE); 172bd8f1dc3Sbluhm if (! xcstrcmp(name, XCS("abort"))) 173bd8f1dc3Sbluhm XML_StopParser(g_parser, XML_FALSE); 174bd8f1dc3Sbluhm } 175bd8f1dc3Sbluhm 176bd8f1dc3Sbluhm /* Check that an element name and attribute name match the expected values. 177bd8f1dc3Sbluhm The expected values are passed as an array reference of string pointers 178bd8f1dc3Sbluhm provided as the userData argument; the first is the expected 179bd8f1dc3Sbluhm element name, and the second is the expected attribute name. 180bd8f1dc3Sbluhm */ 181bd8f1dc3Sbluhm int g_triplet_start_flag = XML_FALSE; 182bd8f1dc3Sbluhm int g_triplet_end_flag = XML_FALSE; 183bd8f1dc3Sbluhm 184bd8f1dc3Sbluhm void XMLCALL 185bd8f1dc3Sbluhm triplet_start_checker(void *userData, const XML_Char *name, 186bd8f1dc3Sbluhm const XML_Char **atts) { 187bd8f1dc3Sbluhm XML_Char **elemstr = (XML_Char **)userData; 188bd8f1dc3Sbluhm char buffer[1024]; 189bd8f1dc3Sbluhm if (xcstrcmp(elemstr[0], name) != 0) { 190bd8f1dc3Sbluhm snprintf(buffer, sizeof(buffer), 191bd8f1dc3Sbluhm "unexpected start string: '%" XML_FMT_STR "'", name); 192bd8f1dc3Sbluhm fail(buffer); 193bd8f1dc3Sbluhm } 194bd8f1dc3Sbluhm if (xcstrcmp(elemstr[1], atts[0]) != 0) { 195bd8f1dc3Sbluhm snprintf(buffer, sizeof(buffer), 196bd8f1dc3Sbluhm "unexpected attribute string: '%" XML_FMT_STR "'", atts[0]); 197bd8f1dc3Sbluhm fail(buffer); 198bd8f1dc3Sbluhm } 199bd8f1dc3Sbluhm g_triplet_start_flag = XML_TRUE; 200bd8f1dc3Sbluhm } 201bd8f1dc3Sbluhm 202bd8f1dc3Sbluhm /* Check that the element name passed to the end-element handler matches 203bd8f1dc3Sbluhm the expected value. The expected value is passed as the first element 204bd8f1dc3Sbluhm in an array of strings passed as the userData argument. 205bd8f1dc3Sbluhm */ 206bd8f1dc3Sbluhm void XMLCALL 207bd8f1dc3Sbluhm triplet_end_checker(void *userData, const XML_Char *name) { 208bd8f1dc3Sbluhm XML_Char **elemstr = (XML_Char **)userData; 209bd8f1dc3Sbluhm if (xcstrcmp(elemstr[0], name) != 0) { 210bd8f1dc3Sbluhm char buffer[1024]; 211bd8f1dc3Sbluhm snprintf(buffer, sizeof(buffer), 212bd8f1dc3Sbluhm "unexpected end string: '%" XML_FMT_STR "'", name); 213bd8f1dc3Sbluhm fail(buffer); 214bd8f1dc3Sbluhm } 215bd8f1dc3Sbluhm g_triplet_end_flag = XML_TRUE; 216bd8f1dc3Sbluhm } 217bd8f1dc3Sbluhm 218bd8f1dc3Sbluhm void XMLCALL 219bd8f1dc3Sbluhm overwrite_start_checker(void *userData, const XML_Char *name, 220bd8f1dc3Sbluhm const XML_Char **atts) { 221bd8f1dc3Sbluhm CharData *storage = (CharData *)userData; 222bd8f1dc3Sbluhm CharData_AppendXMLChars(storage, XCS("start "), 6); 223bd8f1dc3Sbluhm CharData_AppendXMLChars(storage, name, -1); 224bd8f1dc3Sbluhm while (*atts != NULL) { 225bd8f1dc3Sbluhm CharData_AppendXMLChars(storage, XCS("\nattribute "), 11); 226bd8f1dc3Sbluhm CharData_AppendXMLChars(storage, *atts, -1); 227bd8f1dc3Sbluhm atts += 2; 228bd8f1dc3Sbluhm } 229bd8f1dc3Sbluhm CharData_AppendXMLChars(storage, XCS("\n"), 1); 230bd8f1dc3Sbluhm } 231bd8f1dc3Sbluhm 232bd8f1dc3Sbluhm void XMLCALL 233bd8f1dc3Sbluhm overwrite_end_checker(void *userData, const XML_Char *name) { 234bd8f1dc3Sbluhm CharData *storage = (CharData *)userData; 235bd8f1dc3Sbluhm CharData_AppendXMLChars(storage, XCS("end "), 4); 236bd8f1dc3Sbluhm CharData_AppendXMLChars(storage, name, -1); 237bd8f1dc3Sbluhm CharData_AppendXMLChars(storage, XCS("\n"), 1); 238bd8f1dc3Sbluhm } 239bd8f1dc3Sbluhm 240bd8f1dc3Sbluhm void XMLCALL 241bd8f1dc3Sbluhm start_element_fail(void *userData, const XML_Char *name, 242bd8f1dc3Sbluhm const XML_Char **atts) { 243bd8f1dc3Sbluhm UNUSED_P(userData); 244bd8f1dc3Sbluhm UNUSED_P(name); 245bd8f1dc3Sbluhm UNUSED_P(atts); 246bd8f1dc3Sbluhm 247bd8f1dc3Sbluhm /* We should never get here. */ 248bd8f1dc3Sbluhm fail("should never reach start_element_fail()"); 249bd8f1dc3Sbluhm } 250bd8f1dc3Sbluhm 251bd8f1dc3Sbluhm void XMLCALL 252bd8f1dc3Sbluhm start_ns_clearing_start_element(void *userData, const XML_Char *prefix, 253bd8f1dc3Sbluhm const XML_Char *uri) { 254bd8f1dc3Sbluhm UNUSED_P(prefix); 255bd8f1dc3Sbluhm UNUSED_P(uri); 256bd8f1dc3Sbluhm XML_SetStartElementHandler((XML_Parser)userData, NULL); 257bd8f1dc3Sbluhm } 258bd8f1dc3Sbluhm 259bd8f1dc3Sbluhm void XMLCALL 260bd8f1dc3Sbluhm start_element_issue_240(void *userData, const XML_Char *name, 261bd8f1dc3Sbluhm const XML_Char **atts) { 262bd8f1dc3Sbluhm DataIssue240 *mydata = (DataIssue240 *)userData; 263bd8f1dc3Sbluhm UNUSED_P(name); 264bd8f1dc3Sbluhm UNUSED_P(atts); 265bd8f1dc3Sbluhm mydata->deep++; 266bd8f1dc3Sbluhm } 267bd8f1dc3Sbluhm 268bd8f1dc3Sbluhm void XMLCALL 269bd8f1dc3Sbluhm end_element_issue_240(void *userData, const XML_Char *name) { 270bd8f1dc3Sbluhm DataIssue240 *mydata = (DataIssue240 *)userData; 271bd8f1dc3Sbluhm 272bd8f1dc3Sbluhm UNUSED_P(name); 273bd8f1dc3Sbluhm mydata->deep--; 274bd8f1dc3Sbluhm if (mydata->deep == 0) { 275bd8f1dc3Sbluhm XML_StopParser(mydata->parser, 0); 276bd8f1dc3Sbluhm } 277bd8f1dc3Sbluhm } 278bd8f1dc3Sbluhm 279bd8f1dc3Sbluhm /* Text encoding handlers */ 280bd8f1dc3Sbluhm 281bd8f1dc3Sbluhm int XMLCALL 282bd8f1dc3Sbluhm UnknownEncodingHandler(void *data, const XML_Char *encoding, 283bd8f1dc3Sbluhm XML_Encoding *info) { 284bd8f1dc3Sbluhm UNUSED_P(data); 285bd8f1dc3Sbluhm if (xcstrcmp(encoding, XCS("unsupported-encoding")) == 0) { 286bd8f1dc3Sbluhm int i; 287bd8f1dc3Sbluhm for (i = 0; i < 256; ++i) 288bd8f1dc3Sbluhm info->map[i] = i; 289bd8f1dc3Sbluhm info->data = NULL; 290bd8f1dc3Sbluhm info->convert = NULL; 291bd8f1dc3Sbluhm info->release = NULL; 292bd8f1dc3Sbluhm return XML_STATUS_OK; 293bd8f1dc3Sbluhm } 294bd8f1dc3Sbluhm return XML_STATUS_ERROR; 295bd8f1dc3Sbluhm } 296bd8f1dc3Sbluhm 297bd8f1dc3Sbluhm static void 298bd8f1dc3Sbluhm dummy_release(void *data) { 299bd8f1dc3Sbluhm UNUSED_P(data); 300bd8f1dc3Sbluhm } 301bd8f1dc3Sbluhm 302bd8f1dc3Sbluhm int XMLCALL 303bd8f1dc3Sbluhm UnrecognisedEncodingHandler(void *data, const XML_Char *encoding, 304bd8f1dc3Sbluhm XML_Encoding *info) { 305bd8f1dc3Sbluhm UNUSED_P(data); 306bd8f1dc3Sbluhm UNUSED_P(encoding); 307bd8f1dc3Sbluhm info->data = NULL; 308bd8f1dc3Sbluhm info->convert = NULL; 309bd8f1dc3Sbluhm info->release = dummy_release; 310bd8f1dc3Sbluhm return XML_STATUS_ERROR; 311bd8f1dc3Sbluhm } 312bd8f1dc3Sbluhm 313bd8f1dc3Sbluhm int XMLCALL 314bd8f1dc3Sbluhm unknown_released_encoding_handler(void *data, const XML_Char *encoding, 315bd8f1dc3Sbluhm XML_Encoding *info) { 316bd8f1dc3Sbluhm UNUSED_P(data); 317bd8f1dc3Sbluhm if (! xcstrcmp(encoding, XCS("unsupported-encoding"))) { 318bd8f1dc3Sbluhm int i; 319bd8f1dc3Sbluhm 320bd8f1dc3Sbluhm for (i = 0; i < 256; i++) 321bd8f1dc3Sbluhm info->map[i] = i; 322bd8f1dc3Sbluhm info->data = NULL; 323bd8f1dc3Sbluhm info->convert = NULL; 324bd8f1dc3Sbluhm info->release = dummy_release; 325bd8f1dc3Sbluhm return XML_STATUS_OK; 326bd8f1dc3Sbluhm } 327bd8f1dc3Sbluhm return XML_STATUS_ERROR; 328bd8f1dc3Sbluhm } 329bd8f1dc3Sbluhm 330bd8f1dc3Sbluhm static int XMLCALL 331bd8f1dc3Sbluhm failing_converter(void *data, const char *s) { 332bd8f1dc3Sbluhm UNUSED_P(data); 333bd8f1dc3Sbluhm UNUSED_P(s); 334bd8f1dc3Sbluhm /* Always claim to have failed */ 335bd8f1dc3Sbluhm return -1; 336bd8f1dc3Sbluhm } 337bd8f1dc3Sbluhm 338bd8f1dc3Sbluhm static int XMLCALL 339bd8f1dc3Sbluhm prefix_converter(void *data, const char *s) { 340bd8f1dc3Sbluhm UNUSED_P(data); 341bd8f1dc3Sbluhm /* If the first byte is 0xff, raise an error */ 342bd8f1dc3Sbluhm if (s[0] == (char)-1) 343bd8f1dc3Sbluhm return -1; 344bd8f1dc3Sbluhm /* Just add the low bits of the first byte to the second */ 345bd8f1dc3Sbluhm return (s[1] + (s[0] & 0x7f)) & 0x01ff; 346bd8f1dc3Sbluhm } 347bd8f1dc3Sbluhm 348bd8f1dc3Sbluhm int XMLCALL 349bd8f1dc3Sbluhm MiscEncodingHandler(void *data, const XML_Char *encoding, XML_Encoding *info) { 350bd8f1dc3Sbluhm int i; 351bd8f1dc3Sbluhm int high_map = -2; /* Assume a 2-byte sequence */ 352bd8f1dc3Sbluhm 353bd8f1dc3Sbluhm if (! xcstrcmp(encoding, XCS("invalid-9")) 354bd8f1dc3Sbluhm || ! xcstrcmp(encoding, XCS("ascii-like")) 355bd8f1dc3Sbluhm || ! xcstrcmp(encoding, XCS("invalid-len")) 356bd8f1dc3Sbluhm || ! xcstrcmp(encoding, XCS("invalid-a")) 357bd8f1dc3Sbluhm || ! xcstrcmp(encoding, XCS("invalid-surrogate")) 358bd8f1dc3Sbluhm || ! xcstrcmp(encoding, XCS("invalid-high"))) 359bd8f1dc3Sbluhm high_map = -1; 360bd8f1dc3Sbluhm 361bd8f1dc3Sbluhm for (i = 0; i < 128; ++i) 362bd8f1dc3Sbluhm info->map[i] = i; 363bd8f1dc3Sbluhm for (; i < 256; ++i) 364bd8f1dc3Sbluhm info->map[i] = high_map; 365bd8f1dc3Sbluhm 366bd8f1dc3Sbluhm /* If required, put an invalid value in the ASCII entries */ 367bd8f1dc3Sbluhm if (! xcstrcmp(encoding, XCS("invalid-9"))) 368bd8f1dc3Sbluhm info->map[9] = 5; 369bd8f1dc3Sbluhm /* If required, have a top-bit set character starts a 5-byte sequence */ 370bd8f1dc3Sbluhm if (! xcstrcmp(encoding, XCS("invalid-len"))) 371bd8f1dc3Sbluhm info->map[0x81] = -5; 372bd8f1dc3Sbluhm /* If required, make a top-bit set character a valid ASCII character */ 373bd8f1dc3Sbluhm if (! xcstrcmp(encoding, XCS("invalid-a"))) 374bd8f1dc3Sbluhm info->map[0x82] = 'a'; 375bd8f1dc3Sbluhm /* If required, give a top-bit set character a forbidden value, 376bd8f1dc3Sbluhm * what would otherwise be the first of a surrogate pair. 377bd8f1dc3Sbluhm */ 378bd8f1dc3Sbluhm if (! xcstrcmp(encoding, XCS("invalid-surrogate"))) 379bd8f1dc3Sbluhm info->map[0x83] = 0xd801; 380bd8f1dc3Sbluhm /* If required, give a top-bit set character too high a value */ 381bd8f1dc3Sbluhm if (! xcstrcmp(encoding, XCS("invalid-high"))) 382bd8f1dc3Sbluhm info->map[0x84] = 0x010101; 383bd8f1dc3Sbluhm 384bd8f1dc3Sbluhm info->data = data; 385bd8f1dc3Sbluhm info->release = NULL; 386bd8f1dc3Sbluhm if (! xcstrcmp(encoding, XCS("failing-conv"))) 387bd8f1dc3Sbluhm info->convert = failing_converter; 388bd8f1dc3Sbluhm else if (! xcstrcmp(encoding, XCS("prefix-conv"))) 389bd8f1dc3Sbluhm info->convert = prefix_converter; 390bd8f1dc3Sbluhm else 391bd8f1dc3Sbluhm info->convert = NULL; 392bd8f1dc3Sbluhm return XML_STATUS_OK; 393bd8f1dc3Sbluhm } 394bd8f1dc3Sbluhm 395bd8f1dc3Sbluhm int XMLCALL 396bd8f1dc3Sbluhm long_encoding_handler(void *userData, const XML_Char *encoding, 397bd8f1dc3Sbluhm XML_Encoding *info) { 398bd8f1dc3Sbluhm int i; 399bd8f1dc3Sbluhm 400bd8f1dc3Sbluhm UNUSED_P(userData); 401bd8f1dc3Sbluhm UNUSED_P(encoding); 402bd8f1dc3Sbluhm for (i = 0; i < 256; i++) 403bd8f1dc3Sbluhm info->map[i] = i; 404bd8f1dc3Sbluhm info->data = NULL; 405bd8f1dc3Sbluhm info->convert = NULL; 406bd8f1dc3Sbluhm info->release = NULL; 407bd8f1dc3Sbluhm return XML_STATUS_OK; 408bd8f1dc3Sbluhm } 409bd8f1dc3Sbluhm 410bd8f1dc3Sbluhm /* External Entity Handlers */ 411bd8f1dc3Sbluhm 412bd8f1dc3Sbluhm int XMLCALL 413bd8f1dc3Sbluhm external_entity_optioner(XML_Parser parser, const XML_Char *context, 414bd8f1dc3Sbluhm const XML_Char *base, const XML_Char *systemId, 415bd8f1dc3Sbluhm const XML_Char *publicId) { 416bd8f1dc3Sbluhm ExtOption *options = (ExtOption *)XML_GetUserData(parser); 417bd8f1dc3Sbluhm XML_Parser ext_parser; 418bd8f1dc3Sbluhm 419bd8f1dc3Sbluhm UNUSED_P(base); 420bd8f1dc3Sbluhm UNUSED_P(publicId); 421bd8f1dc3Sbluhm while (options->parse_text != NULL) { 422bd8f1dc3Sbluhm if (! xcstrcmp(systemId, options->system_id)) { 423bd8f1dc3Sbluhm enum XML_Status rc; 424bd8f1dc3Sbluhm ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 425bd8f1dc3Sbluhm if (ext_parser == NULL) 426bd8f1dc3Sbluhm return XML_STATUS_ERROR; 427bd8f1dc3Sbluhm rc = _XML_Parse_SINGLE_BYTES(ext_parser, options->parse_text, 428bd8f1dc3Sbluhm (int)strlen(options->parse_text), XML_TRUE); 429bd8f1dc3Sbluhm XML_ParserFree(ext_parser); 430bd8f1dc3Sbluhm return rc; 431bd8f1dc3Sbluhm } 432bd8f1dc3Sbluhm options++; 433bd8f1dc3Sbluhm } 434bd8f1dc3Sbluhm fail("No suitable option found"); 435bd8f1dc3Sbluhm return XML_STATUS_ERROR; 436bd8f1dc3Sbluhm } 437bd8f1dc3Sbluhm 438bd8f1dc3Sbluhm int XMLCALL 439bd8f1dc3Sbluhm external_entity_loader(XML_Parser parser, const XML_Char *context, 440bd8f1dc3Sbluhm const XML_Char *base, const XML_Char *systemId, 441bd8f1dc3Sbluhm const XML_Char *publicId) { 442bd8f1dc3Sbluhm ExtTest *test_data = (ExtTest *)XML_GetUserData(parser); 443bd8f1dc3Sbluhm XML_Parser extparser; 444bd8f1dc3Sbluhm 445bd8f1dc3Sbluhm UNUSED_P(base); 446bd8f1dc3Sbluhm UNUSED_P(systemId); 447bd8f1dc3Sbluhm UNUSED_P(publicId); 448bd8f1dc3Sbluhm extparser = XML_ExternalEntityParserCreate(parser, context, NULL); 449bd8f1dc3Sbluhm if (extparser == NULL) 450bd8f1dc3Sbluhm fail("Could not create external entity parser."); 451bd8f1dc3Sbluhm if (test_data->encoding != NULL) { 452bd8f1dc3Sbluhm if (! XML_SetEncoding(extparser, test_data->encoding)) 453bd8f1dc3Sbluhm fail("XML_SetEncoding() ignored for external entity"); 454bd8f1dc3Sbluhm } 455bd8f1dc3Sbluhm if (_XML_Parse_SINGLE_BYTES(extparser, test_data->parse_text, 456bd8f1dc3Sbluhm (int)strlen(test_data->parse_text), XML_TRUE) 457bd8f1dc3Sbluhm == XML_STATUS_ERROR) { 458bd8f1dc3Sbluhm xml_failure(extparser); 459bd8f1dc3Sbluhm return XML_STATUS_ERROR; 460bd8f1dc3Sbluhm } 461bd8f1dc3Sbluhm XML_ParserFree(extparser); 462bd8f1dc3Sbluhm return XML_STATUS_OK; 463bd8f1dc3Sbluhm } 464bd8f1dc3Sbluhm 465bd8f1dc3Sbluhm int XMLCALL 466bd8f1dc3Sbluhm external_entity_faulter(XML_Parser parser, const XML_Char *context, 467bd8f1dc3Sbluhm const XML_Char *base, const XML_Char *systemId, 468bd8f1dc3Sbluhm const XML_Char *publicId) { 469bd8f1dc3Sbluhm XML_Parser ext_parser; 470bd8f1dc3Sbluhm ExtFaults *fault = (ExtFaults *)XML_GetUserData(parser); 471bd8f1dc3Sbluhm 472bd8f1dc3Sbluhm UNUSED_P(base); 473bd8f1dc3Sbluhm UNUSED_P(systemId); 474bd8f1dc3Sbluhm UNUSED_P(publicId); 475bd8f1dc3Sbluhm ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 476bd8f1dc3Sbluhm if (ext_parser == NULL) 477bd8f1dc3Sbluhm fail("Could not create external entity parser"); 478bd8f1dc3Sbluhm if (fault->encoding != NULL) { 479bd8f1dc3Sbluhm if (! XML_SetEncoding(ext_parser, fault->encoding)) 480bd8f1dc3Sbluhm fail("XML_SetEncoding failed"); 481bd8f1dc3Sbluhm } 482bd8f1dc3Sbluhm if (_XML_Parse_SINGLE_BYTES(ext_parser, fault->parse_text, 483bd8f1dc3Sbluhm (int)strlen(fault->parse_text), XML_TRUE) 484bd8f1dc3Sbluhm != XML_STATUS_ERROR) 485bd8f1dc3Sbluhm fail(fault->fail_text); 486bd8f1dc3Sbluhm if (XML_GetErrorCode(ext_parser) != fault->error) 487bd8f1dc3Sbluhm xml_failure(ext_parser); 488bd8f1dc3Sbluhm 489bd8f1dc3Sbluhm XML_ParserFree(ext_parser); 490bd8f1dc3Sbluhm return XML_STATUS_ERROR; 491bd8f1dc3Sbluhm } 492bd8f1dc3Sbluhm 493bd8f1dc3Sbluhm int XMLCALL 494bd8f1dc3Sbluhm external_entity_null_loader(XML_Parser parser, const XML_Char *context, 495bd8f1dc3Sbluhm const XML_Char *base, const XML_Char *systemId, 496bd8f1dc3Sbluhm const XML_Char *publicId) { 497bd8f1dc3Sbluhm UNUSED_P(parser); 498bd8f1dc3Sbluhm UNUSED_P(context); 499bd8f1dc3Sbluhm UNUSED_P(base); 500bd8f1dc3Sbluhm UNUSED_P(systemId); 501bd8f1dc3Sbluhm UNUSED_P(publicId); 502bd8f1dc3Sbluhm return XML_STATUS_OK; 503bd8f1dc3Sbluhm } 504bd8f1dc3Sbluhm 505bd8f1dc3Sbluhm int XMLCALL 506bd8f1dc3Sbluhm external_entity_resetter(XML_Parser parser, const XML_Char *context, 507bd8f1dc3Sbluhm const XML_Char *base, const XML_Char *systemId, 508bd8f1dc3Sbluhm const XML_Char *publicId) { 509bd8f1dc3Sbluhm const char *text = "<!ELEMENT doc (#PCDATA)*>"; 510bd8f1dc3Sbluhm XML_Parser ext_parser; 511bd8f1dc3Sbluhm XML_ParsingStatus status; 512bd8f1dc3Sbluhm 513bd8f1dc3Sbluhm UNUSED_P(base); 514bd8f1dc3Sbluhm UNUSED_P(systemId); 515bd8f1dc3Sbluhm UNUSED_P(publicId); 516bd8f1dc3Sbluhm ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 517bd8f1dc3Sbluhm if (ext_parser == NULL) 518bd8f1dc3Sbluhm fail("Could not create external entity parser"); 519bd8f1dc3Sbluhm XML_GetParsingStatus(ext_parser, &status); 520bd8f1dc3Sbluhm if (status.parsing != XML_INITIALIZED) { 521bd8f1dc3Sbluhm fail("Parsing status is not INITIALIZED"); 522bd8f1dc3Sbluhm return XML_STATUS_ERROR; 523bd8f1dc3Sbluhm } 524bd8f1dc3Sbluhm if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE) 525bd8f1dc3Sbluhm == XML_STATUS_ERROR) { 526bd8f1dc3Sbluhm xml_failure(parser); 527bd8f1dc3Sbluhm return XML_STATUS_ERROR; 528bd8f1dc3Sbluhm } 529bd8f1dc3Sbluhm XML_GetParsingStatus(ext_parser, &status); 530bd8f1dc3Sbluhm if (status.parsing != XML_FINISHED) { 531bd8f1dc3Sbluhm fail("Parsing status is not FINISHED"); 532bd8f1dc3Sbluhm return XML_STATUS_ERROR; 533bd8f1dc3Sbluhm } 534bd8f1dc3Sbluhm /* Check we can't parse here */ 535bd8f1dc3Sbluhm if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE) 536bd8f1dc3Sbluhm != XML_STATUS_ERROR) 537bd8f1dc3Sbluhm fail("Parsing when finished not faulted"); 538bd8f1dc3Sbluhm if (XML_GetErrorCode(ext_parser) != XML_ERROR_FINISHED) 539bd8f1dc3Sbluhm fail("Parsing when finished faulted with wrong code"); 540bd8f1dc3Sbluhm XML_ParserReset(ext_parser, NULL); 541bd8f1dc3Sbluhm XML_GetParsingStatus(ext_parser, &status); 542bd8f1dc3Sbluhm if (status.parsing != XML_FINISHED) { 543bd8f1dc3Sbluhm fail("Parsing status not still FINISHED"); 544bd8f1dc3Sbluhm return XML_STATUS_ERROR; 545bd8f1dc3Sbluhm } 546bd8f1dc3Sbluhm XML_ParserFree(ext_parser); 547bd8f1dc3Sbluhm return XML_STATUS_OK; 548bd8f1dc3Sbluhm } 549bd8f1dc3Sbluhm 550bd8f1dc3Sbluhm void XMLCALL 551bd8f1dc3Sbluhm entity_suspending_decl_handler(void *userData, const XML_Char *name, 552bd8f1dc3Sbluhm XML_Content *model) { 553bd8f1dc3Sbluhm XML_Parser ext_parser = (XML_Parser)userData; 554bd8f1dc3Sbluhm 555bd8f1dc3Sbluhm UNUSED_P(name); 556bd8f1dc3Sbluhm if (XML_StopParser(ext_parser, XML_TRUE) != XML_STATUS_ERROR) 557bd8f1dc3Sbluhm fail("Attempting to suspend a subordinate parser not faulted"); 558bd8f1dc3Sbluhm if (XML_GetErrorCode(ext_parser) != XML_ERROR_SUSPEND_PE) 559bd8f1dc3Sbluhm fail("Suspending subordinate parser get wrong code"); 560bd8f1dc3Sbluhm XML_SetElementDeclHandler(ext_parser, NULL); 561bd8f1dc3Sbluhm XML_FreeContentModel(g_parser, model); 562bd8f1dc3Sbluhm } 563bd8f1dc3Sbluhm 564bd8f1dc3Sbluhm int XMLCALL 565bd8f1dc3Sbluhm external_entity_suspender(XML_Parser parser, const XML_Char *context, 566bd8f1dc3Sbluhm const XML_Char *base, const XML_Char *systemId, 567bd8f1dc3Sbluhm const XML_Char *publicId) { 568bd8f1dc3Sbluhm const char *text = "<!ELEMENT doc (#PCDATA)*>"; 569bd8f1dc3Sbluhm XML_Parser ext_parser; 570bd8f1dc3Sbluhm 571bd8f1dc3Sbluhm UNUSED_P(base); 572bd8f1dc3Sbluhm UNUSED_P(systemId); 573bd8f1dc3Sbluhm UNUSED_P(publicId); 574bd8f1dc3Sbluhm ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 575bd8f1dc3Sbluhm if (ext_parser == NULL) 576bd8f1dc3Sbluhm fail("Could not create external entity parser"); 577bd8f1dc3Sbluhm XML_SetElementDeclHandler(ext_parser, entity_suspending_decl_handler); 578bd8f1dc3Sbluhm XML_SetUserData(ext_parser, ext_parser); 579bd8f1dc3Sbluhm if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE) 580bd8f1dc3Sbluhm == XML_STATUS_ERROR) { 581bd8f1dc3Sbluhm xml_failure(ext_parser); 582bd8f1dc3Sbluhm return XML_STATUS_ERROR; 583bd8f1dc3Sbluhm } 584bd8f1dc3Sbluhm XML_ParserFree(ext_parser); 585bd8f1dc3Sbluhm return XML_STATUS_OK; 586bd8f1dc3Sbluhm } 587bd8f1dc3Sbluhm 588bd8f1dc3Sbluhm void XMLCALL 589bd8f1dc3Sbluhm entity_suspending_xdecl_handler(void *userData, const XML_Char *version, 590bd8f1dc3Sbluhm const XML_Char *encoding, int standalone) { 591bd8f1dc3Sbluhm XML_Parser ext_parser = (XML_Parser)userData; 592bd8f1dc3Sbluhm 593bd8f1dc3Sbluhm UNUSED_P(version); 594bd8f1dc3Sbluhm UNUSED_P(encoding); 595bd8f1dc3Sbluhm UNUSED_P(standalone); 596bd8f1dc3Sbluhm XML_StopParser(ext_parser, g_resumable); 597bd8f1dc3Sbluhm XML_SetXmlDeclHandler(ext_parser, NULL); 598bd8f1dc3Sbluhm } 599bd8f1dc3Sbluhm 600bd8f1dc3Sbluhm int XMLCALL 601bd8f1dc3Sbluhm external_entity_suspend_xmldecl(XML_Parser parser, const XML_Char *context, 602bd8f1dc3Sbluhm const XML_Char *base, const XML_Char *systemId, 603bd8f1dc3Sbluhm const XML_Char *publicId) { 604bd8f1dc3Sbluhm const char *text = "<?xml version='1.0' encoding='us-ascii'?>"; 605bd8f1dc3Sbluhm XML_Parser ext_parser; 606bd8f1dc3Sbluhm XML_ParsingStatus status; 607bd8f1dc3Sbluhm enum XML_Status rc; 608bd8f1dc3Sbluhm 609bd8f1dc3Sbluhm UNUSED_P(base); 610bd8f1dc3Sbluhm UNUSED_P(systemId); 611bd8f1dc3Sbluhm UNUSED_P(publicId); 612bd8f1dc3Sbluhm ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 613bd8f1dc3Sbluhm if (ext_parser == NULL) 614bd8f1dc3Sbluhm fail("Could not create external entity parser"); 615bd8f1dc3Sbluhm XML_SetXmlDeclHandler(ext_parser, entity_suspending_xdecl_handler); 616bd8f1dc3Sbluhm XML_SetUserData(ext_parser, ext_parser); 617bd8f1dc3Sbluhm rc = _XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE); 618bd8f1dc3Sbluhm XML_GetParsingStatus(ext_parser, &status); 619bd8f1dc3Sbluhm if (g_resumable) { 620bd8f1dc3Sbluhm if (rc == XML_STATUS_ERROR) 621bd8f1dc3Sbluhm xml_failure(ext_parser); 622bd8f1dc3Sbluhm if (status.parsing != XML_SUSPENDED) 623bd8f1dc3Sbluhm fail("Ext Parsing status not SUSPENDED"); 624bd8f1dc3Sbluhm } else { 625bd8f1dc3Sbluhm if (rc != XML_STATUS_ERROR) 626bd8f1dc3Sbluhm fail("Ext parsing not aborted"); 627bd8f1dc3Sbluhm if (XML_GetErrorCode(ext_parser) != XML_ERROR_ABORTED) 628bd8f1dc3Sbluhm xml_failure(ext_parser); 629bd8f1dc3Sbluhm if (status.parsing != XML_FINISHED) 630bd8f1dc3Sbluhm fail("Ext Parsing status not FINISHED"); 631bd8f1dc3Sbluhm } 632bd8f1dc3Sbluhm 633bd8f1dc3Sbluhm XML_ParserFree(ext_parser); 634bd8f1dc3Sbluhm return XML_STATUS_OK; 635bd8f1dc3Sbluhm } 636bd8f1dc3Sbluhm 637bd8f1dc3Sbluhm int XMLCALL 638bd8f1dc3Sbluhm external_entity_suspending_faulter(XML_Parser parser, const XML_Char *context, 639bd8f1dc3Sbluhm const XML_Char *base, 640bd8f1dc3Sbluhm const XML_Char *systemId, 641bd8f1dc3Sbluhm const XML_Char *publicId) { 642bd8f1dc3Sbluhm XML_Parser ext_parser; 643bd8f1dc3Sbluhm ExtFaults *fault = (ExtFaults *)XML_GetUserData(parser); 644bd8f1dc3Sbluhm void *buffer; 645bd8f1dc3Sbluhm int parse_len = (int)strlen(fault->parse_text); 646bd8f1dc3Sbluhm 647bd8f1dc3Sbluhm UNUSED_P(base); 648bd8f1dc3Sbluhm UNUSED_P(systemId); 649bd8f1dc3Sbluhm UNUSED_P(publicId); 650bd8f1dc3Sbluhm ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 651bd8f1dc3Sbluhm if (ext_parser == NULL) 652bd8f1dc3Sbluhm fail("Could not create external entity parser"); 653bd8f1dc3Sbluhm XML_SetXmlDeclHandler(ext_parser, entity_suspending_xdecl_handler); 654bd8f1dc3Sbluhm XML_SetUserData(ext_parser, ext_parser); 655bd8f1dc3Sbluhm g_resumable = XML_TRUE; 656bd8f1dc3Sbluhm buffer = XML_GetBuffer(ext_parser, parse_len); 657bd8f1dc3Sbluhm if (buffer == NULL) 658bd8f1dc3Sbluhm fail("Could not allocate parse buffer"); 659bd8f1dc3Sbluhm assert(buffer != NULL); 660bd8f1dc3Sbluhm memcpy(buffer, fault->parse_text, parse_len); 661bd8f1dc3Sbluhm if (XML_ParseBuffer(ext_parser, parse_len, XML_FALSE) != XML_STATUS_SUSPENDED) 662bd8f1dc3Sbluhm fail("XML declaration did not suspend"); 663bd8f1dc3Sbluhm if (XML_ResumeParser(ext_parser) != XML_STATUS_OK) 664bd8f1dc3Sbluhm xml_failure(ext_parser); 665bd8f1dc3Sbluhm if (XML_ParseBuffer(ext_parser, 0, XML_TRUE) != XML_STATUS_ERROR) 666bd8f1dc3Sbluhm fail(fault->fail_text); 667bd8f1dc3Sbluhm if (XML_GetErrorCode(ext_parser) != fault->error) 668bd8f1dc3Sbluhm xml_failure(ext_parser); 669bd8f1dc3Sbluhm 670bd8f1dc3Sbluhm XML_ParserFree(ext_parser); 671bd8f1dc3Sbluhm return XML_STATUS_ERROR; 672bd8f1dc3Sbluhm } 673bd8f1dc3Sbluhm 674bd8f1dc3Sbluhm int XMLCALL 675bd8f1dc3Sbluhm external_entity_failer__if_not_xml_ge(XML_Parser parser, 676bd8f1dc3Sbluhm const XML_Char *context, 677bd8f1dc3Sbluhm const XML_Char *base, 678bd8f1dc3Sbluhm const XML_Char *systemId, 679bd8f1dc3Sbluhm const XML_Char *publicId) { 680bd8f1dc3Sbluhm UNUSED_P(parser); 681bd8f1dc3Sbluhm UNUSED_P(context); 682bd8f1dc3Sbluhm UNUSED_P(base); 683bd8f1dc3Sbluhm UNUSED_P(systemId); 684bd8f1dc3Sbluhm UNUSED_P(publicId); 685bd8f1dc3Sbluhm #if XML_GE == 0 686bd8f1dc3Sbluhm fail( 687bd8f1dc3Sbluhm "Function external_entity_suspending_failer was called despite XML_GE==0."); 688bd8f1dc3Sbluhm #endif 689bd8f1dc3Sbluhm return XML_STATUS_OK; 690bd8f1dc3Sbluhm } 691bd8f1dc3Sbluhm 692bd8f1dc3Sbluhm int XMLCALL 693bd8f1dc3Sbluhm external_entity_cr_catcher(XML_Parser parser, const XML_Char *context, 694bd8f1dc3Sbluhm const XML_Char *base, const XML_Char *systemId, 695bd8f1dc3Sbluhm const XML_Char *publicId) { 696bd8f1dc3Sbluhm const char *text = "\r"; 697bd8f1dc3Sbluhm XML_Parser ext_parser; 698bd8f1dc3Sbluhm 699bd8f1dc3Sbluhm UNUSED_P(base); 700bd8f1dc3Sbluhm UNUSED_P(systemId); 701bd8f1dc3Sbluhm UNUSED_P(publicId); 702bd8f1dc3Sbluhm ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 703bd8f1dc3Sbluhm if (ext_parser == NULL) 704bd8f1dc3Sbluhm fail("Could not create external entity parser"); 705bd8f1dc3Sbluhm XML_SetCharacterDataHandler(ext_parser, cr_cdata_handler); 706bd8f1dc3Sbluhm if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE) 707bd8f1dc3Sbluhm == XML_STATUS_ERROR) 708bd8f1dc3Sbluhm xml_failure(ext_parser); 709bd8f1dc3Sbluhm XML_ParserFree(ext_parser); 710bd8f1dc3Sbluhm return XML_STATUS_OK; 711bd8f1dc3Sbluhm } 712bd8f1dc3Sbluhm 713bd8f1dc3Sbluhm int XMLCALL 714bd8f1dc3Sbluhm external_entity_bad_cr_catcher(XML_Parser parser, const XML_Char *context, 715bd8f1dc3Sbluhm const XML_Char *base, const XML_Char *systemId, 716bd8f1dc3Sbluhm const XML_Char *publicId) { 717bd8f1dc3Sbluhm const char *text = "<tag>\r"; 718bd8f1dc3Sbluhm XML_Parser ext_parser; 719bd8f1dc3Sbluhm 720bd8f1dc3Sbluhm UNUSED_P(base); 721bd8f1dc3Sbluhm UNUSED_P(systemId); 722bd8f1dc3Sbluhm UNUSED_P(publicId); 723bd8f1dc3Sbluhm ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 724bd8f1dc3Sbluhm if (ext_parser == NULL) 725bd8f1dc3Sbluhm fail("Could not create external entity parser"); 726bd8f1dc3Sbluhm XML_SetCharacterDataHandler(ext_parser, cr_cdata_handler); 727bd8f1dc3Sbluhm if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE) 728bd8f1dc3Sbluhm == XML_STATUS_OK) 729bd8f1dc3Sbluhm fail("Async entity error not caught"); 730bd8f1dc3Sbluhm if (XML_GetErrorCode(ext_parser) != XML_ERROR_ASYNC_ENTITY) 731bd8f1dc3Sbluhm xml_failure(ext_parser); 732bd8f1dc3Sbluhm XML_ParserFree(ext_parser); 733bd8f1dc3Sbluhm return XML_STATUS_OK; 734bd8f1dc3Sbluhm } 735bd8f1dc3Sbluhm 736bd8f1dc3Sbluhm int XMLCALL 737bd8f1dc3Sbluhm external_entity_rsqb_catcher(XML_Parser parser, const XML_Char *context, 738bd8f1dc3Sbluhm const XML_Char *base, const XML_Char *systemId, 739bd8f1dc3Sbluhm const XML_Char *publicId) { 740bd8f1dc3Sbluhm const char *text = "<tag>]"; 741bd8f1dc3Sbluhm XML_Parser ext_parser; 742bd8f1dc3Sbluhm 743bd8f1dc3Sbluhm UNUSED_P(base); 744bd8f1dc3Sbluhm UNUSED_P(systemId); 745bd8f1dc3Sbluhm UNUSED_P(publicId); 746bd8f1dc3Sbluhm ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 747bd8f1dc3Sbluhm if (ext_parser == NULL) 748bd8f1dc3Sbluhm fail("Could not create external entity parser"); 749bd8f1dc3Sbluhm XML_SetCharacterDataHandler(ext_parser, rsqb_handler); 750bd8f1dc3Sbluhm if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE) 751bd8f1dc3Sbluhm != XML_STATUS_ERROR) 752bd8f1dc3Sbluhm fail("Async entity error not caught"); 753bd8f1dc3Sbluhm if (XML_GetErrorCode(ext_parser) != XML_ERROR_ASYNC_ENTITY) 754bd8f1dc3Sbluhm xml_failure(ext_parser); 755bd8f1dc3Sbluhm XML_ParserFree(ext_parser); 756bd8f1dc3Sbluhm return XML_STATUS_OK; 757bd8f1dc3Sbluhm } 758bd8f1dc3Sbluhm 759bd8f1dc3Sbluhm int XMLCALL 760bd8f1dc3Sbluhm external_entity_good_cdata_ascii(XML_Parser parser, const XML_Char *context, 761bd8f1dc3Sbluhm const XML_Char *base, const XML_Char *systemId, 762bd8f1dc3Sbluhm const XML_Char *publicId) { 763bd8f1dc3Sbluhm const char *text = "<a><![CDATA[<greeting>Hello, world!</greeting>]]></a>"; 764bd8f1dc3Sbluhm const XML_Char *expected = XCS("<greeting>Hello, world!</greeting>"); 765bd8f1dc3Sbluhm CharData storage; 766bd8f1dc3Sbluhm XML_Parser ext_parser; 767bd8f1dc3Sbluhm 768bd8f1dc3Sbluhm UNUSED_P(base); 769bd8f1dc3Sbluhm UNUSED_P(systemId); 770bd8f1dc3Sbluhm UNUSED_P(publicId); 771bd8f1dc3Sbluhm CharData_Init(&storage); 772bd8f1dc3Sbluhm ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 773bd8f1dc3Sbluhm if (ext_parser == NULL) 774bd8f1dc3Sbluhm fail("Could not create external entity parser"); 775bd8f1dc3Sbluhm XML_SetUserData(ext_parser, &storage); 776bd8f1dc3Sbluhm XML_SetCharacterDataHandler(ext_parser, accumulate_characters); 777bd8f1dc3Sbluhm 778bd8f1dc3Sbluhm if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE) 779bd8f1dc3Sbluhm == XML_STATUS_ERROR) 780bd8f1dc3Sbluhm xml_failure(ext_parser); 781bd8f1dc3Sbluhm CharData_CheckXMLChars(&storage, expected); 782bd8f1dc3Sbluhm 783bd8f1dc3Sbluhm XML_ParserFree(ext_parser); 784bd8f1dc3Sbluhm return XML_STATUS_OK; 785bd8f1dc3Sbluhm } 786bd8f1dc3Sbluhm 787bd8f1dc3Sbluhm int XMLCALL 788bd8f1dc3Sbluhm external_entity_param_checker(XML_Parser parser, const XML_Char *context, 789bd8f1dc3Sbluhm const XML_Char *base, const XML_Char *systemId, 790bd8f1dc3Sbluhm const XML_Char *publicId) { 791bd8f1dc3Sbluhm const char *text = "<!-- Subordinate parser -->\n" 792bd8f1dc3Sbluhm "<!ELEMENT doc (#PCDATA)*>"; 793bd8f1dc3Sbluhm XML_Parser ext_parser; 794bd8f1dc3Sbluhm 795bd8f1dc3Sbluhm UNUSED_P(base); 796bd8f1dc3Sbluhm UNUSED_P(systemId); 797bd8f1dc3Sbluhm UNUSED_P(publicId); 798bd8f1dc3Sbluhm ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 799bd8f1dc3Sbluhm if (ext_parser == NULL) 800bd8f1dc3Sbluhm fail("Could not create external entity parser"); 801bd8f1dc3Sbluhm g_handler_data = ext_parser; 802bd8f1dc3Sbluhm if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE) 803bd8f1dc3Sbluhm == XML_STATUS_ERROR) { 804bd8f1dc3Sbluhm xml_failure(parser); 805bd8f1dc3Sbluhm return XML_STATUS_ERROR; 806bd8f1dc3Sbluhm } 807bd8f1dc3Sbluhm g_handler_data = parser; 808bd8f1dc3Sbluhm XML_ParserFree(ext_parser); 809bd8f1dc3Sbluhm return XML_STATUS_OK; 810bd8f1dc3Sbluhm } 811bd8f1dc3Sbluhm 812bd8f1dc3Sbluhm int XMLCALL 813bd8f1dc3Sbluhm external_entity_ref_param_checker(XML_Parser parameter, const XML_Char *context, 814bd8f1dc3Sbluhm const XML_Char *base, 815bd8f1dc3Sbluhm const XML_Char *systemId, 816bd8f1dc3Sbluhm const XML_Char *publicId) { 817bd8f1dc3Sbluhm const char *text = "<!ELEMENT doc (#PCDATA)*>"; 818bd8f1dc3Sbluhm XML_Parser ext_parser; 819bd8f1dc3Sbluhm 820bd8f1dc3Sbluhm UNUSED_P(base); 821bd8f1dc3Sbluhm UNUSED_P(systemId); 822bd8f1dc3Sbluhm UNUSED_P(publicId); 823bd8f1dc3Sbluhm if ((void *)parameter != g_handler_data) 824bd8f1dc3Sbluhm fail("External entity ref handler parameter not correct"); 825bd8f1dc3Sbluhm 826bd8f1dc3Sbluhm /* Here we use the global 'parser' variable */ 827bd8f1dc3Sbluhm ext_parser = XML_ExternalEntityParserCreate(g_parser, context, NULL); 828bd8f1dc3Sbluhm if (ext_parser == NULL) 829bd8f1dc3Sbluhm fail("Could not create external entity parser"); 830bd8f1dc3Sbluhm if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE) 831bd8f1dc3Sbluhm == XML_STATUS_ERROR) 832bd8f1dc3Sbluhm xml_failure(ext_parser); 833bd8f1dc3Sbluhm 834bd8f1dc3Sbluhm XML_ParserFree(ext_parser); 835bd8f1dc3Sbluhm return XML_STATUS_OK; 836bd8f1dc3Sbluhm } 837bd8f1dc3Sbluhm 838bd8f1dc3Sbluhm int XMLCALL 839bd8f1dc3Sbluhm external_entity_param(XML_Parser parser, const XML_Char *context, 840bd8f1dc3Sbluhm const XML_Char *base, const XML_Char *systemId, 841bd8f1dc3Sbluhm const XML_Char *publicId) { 842bd8f1dc3Sbluhm const char *text1 = "<!ELEMENT doc EMPTY>\n" 843bd8f1dc3Sbluhm "<!ENTITY % e1 SYSTEM '004-2.ent'>\n" 844bd8f1dc3Sbluhm "<!ENTITY % e2 '%e1;'>\n" 845bd8f1dc3Sbluhm "%e1;\n"; 846bd8f1dc3Sbluhm const char *text2 = "<!ELEMENT el EMPTY>\n" 847bd8f1dc3Sbluhm "<el/>\n"; 848bd8f1dc3Sbluhm XML_Parser ext_parser; 849bd8f1dc3Sbluhm 850bd8f1dc3Sbluhm UNUSED_P(base); 851bd8f1dc3Sbluhm UNUSED_P(publicId); 852bd8f1dc3Sbluhm if (systemId == NULL) 853bd8f1dc3Sbluhm return XML_STATUS_OK; 854bd8f1dc3Sbluhm 855bd8f1dc3Sbluhm ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 856bd8f1dc3Sbluhm if (ext_parser == NULL) 857bd8f1dc3Sbluhm fail("Could not create external entity parser"); 858bd8f1dc3Sbluhm 859bd8f1dc3Sbluhm if (! xcstrcmp(systemId, XCS("004-1.ent"))) { 860bd8f1dc3Sbluhm if (_XML_Parse_SINGLE_BYTES(ext_parser, text1, (int)strlen(text1), XML_TRUE) 861bd8f1dc3Sbluhm != XML_STATUS_ERROR) 862bd8f1dc3Sbluhm fail("Inner DTD with invalid tag not rejected"); 863bd8f1dc3Sbluhm if (XML_GetErrorCode(ext_parser) != XML_ERROR_EXTERNAL_ENTITY_HANDLING) 864bd8f1dc3Sbluhm xml_failure(ext_parser); 865bd8f1dc3Sbluhm } else if (! xcstrcmp(systemId, XCS("004-2.ent"))) { 866bd8f1dc3Sbluhm if (_XML_Parse_SINGLE_BYTES(ext_parser, text2, (int)strlen(text2), XML_TRUE) 867bd8f1dc3Sbluhm != XML_STATUS_ERROR) 868bd8f1dc3Sbluhm fail("Invalid tag in external param not rejected"); 869bd8f1dc3Sbluhm if (XML_GetErrorCode(ext_parser) != XML_ERROR_SYNTAX) 870bd8f1dc3Sbluhm xml_failure(ext_parser); 871bd8f1dc3Sbluhm } else { 872bd8f1dc3Sbluhm fail("Unknown system ID"); 873bd8f1dc3Sbluhm } 874bd8f1dc3Sbluhm 875bd8f1dc3Sbluhm XML_ParserFree(ext_parser); 876bd8f1dc3Sbluhm return XML_STATUS_ERROR; 877bd8f1dc3Sbluhm } 878bd8f1dc3Sbluhm 879bd8f1dc3Sbluhm int XMLCALL 880bd8f1dc3Sbluhm external_entity_load_ignore(XML_Parser parser, const XML_Char *context, 881bd8f1dc3Sbluhm const XML_Char *base, const XML_Char *systemId, 882bd8f1dc3Sbluhm const XML_Char *publicId) { 883bd8f1dc3Sbluhm const char *text = "<![IGNORE[<!ELEMENT e (#PCDATA)*>]]>"; 884bd8f1dc3Sbluhm XML_Parser ext_parser; 885bd8f1dc3Sbluhm 886bd8f1dc3Sbluhm UNUSED_P(base); 887bd8f1dc3Sbluhm UNUSED_P(systemId); 888bd8f1dc3Sbluhm UNUSED_P(publicId); 889bd8f1dc3Sbluhm ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 890bd8f1dc3Sbluhm if (ext_parser == NULL) 891bd8f1dc3Sbluhm fail("Could not create external entity parser"); 892bd8f1dc3Sbluhm if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE) 893bd8f1dc3Sbluhm == XML_STATUS_ERROR) 894bd8f1dc3Sbluhm xml_failure(parser); 895bd8f1dc3Sbluhm 896bd8f1dc3Sbluhm XML_ParserFree(ext_parser); 897bd8f1dc3Sbluhm return XML_STATUS_OK; 898bd8f1dc3Sbluhm } 899bd8f1dc3Sbluhm 900bd8f1dc3Sbluhm int XMLCALL 901bd8f1dc3Sbluhm external_entity_load_ignore_utf16(XML_Parser parser, const XML_Char *context, 902bd8f1dc3Sbluhm const XML_Char *base, 903bd8f1dc3Sbluhm const XML_Char *systemId, 904bd8f1dc3Sbluhm const XML_Char *publicId) { 905bd8f1dc3Sbluhm const char text[] = 906bd8f1dc3Sbluhm /* <![IGNORE[<!ELEMENT e (#PCDATA)*>]]> */ 907bd8f1dc3Sbluhm "<\0!\0[\0I\0G\0N\0O\0R\0E\0[\0" 908bd8f1dc3Sbluhm "<\0!\0E\0L\0E\0M\0E\0N\0T\0 \0e\0 \0" 909bd8f1dc3Sbluhm "(\0#\0P\0C\0D\0A\0T\0A\0)\0*\0>\0]\0]\0>\0"; 910bd8f1dc3Sbluhm XML_Parser ext_parser; 911bd8f1dc3Sbluhm 912bd8f1dc3Sbluhm UNUSED_P(base); 913bd8f1dc3Sbluhm UNUSED_P(systemId); 914bd8f1dc3Sbluhm UNUSED_P(publicId); 915bd8f1dc3Sbluhm ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 916bd8f1dc3Sbluhm if (ext_parser == NULL) 917bd8f1dc3Sbluhm fail("Could not create external entity parser"); 918bd8f1dc3Sbluhm if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)sizeof(text) - 1, XML_TRUE) 919bd8f1dc3Sbluhm == XML_STATUS_ERROR) 920bd8f1dc3Sbluhm xml_failure(parser); 921bd8f1dc3Sbluhm 922bd8f1dc3Sbluhm XML_ParserFree(ext_parser); 923bd8f1dc3Sbluhm return XML_STATUS_OK; 924bd8f1dc3Sbluhm } 925bd8f1dc3Sbluhm 926bd8f1dc3Sbluhm int XMLCALL 927bd8f1dc3Sbluhm external_entity_load_ignore_utf16_be(XML_Parser parser, const XML_Char *context, 928bd8f1dc3Sbluhm const XML_Char *base, 929bd8f1dc3Sbluhm const XML_Char *systemId, 930bd8f1dc3Sbluhm const XML_Char *publicId) { 931bd8f1dc3Sbluhm const char text[] = 932bd8f1dc3Sbluhm /* <![IGNORE[<!ELEMENT e (#PCDATA)*>]]> */ 933bd8f1dc3Sbluhm "\0<\0!\0[\0I\0G\0N\0O\0R\0E\0[" 934bd8f1dc3Sbluhm "\0<\0!\0E\0L\0E\0M\0E\0N\0T\0 \0e\0 " 935bd8f1dc3Sbluhm "\0(\0#\0P\0C\0D\0A\0T\0A\0)\0*\0>\0]\0]\0>"; 936bd8f1dc3Sbluhm XML_Parser ext_parser; 937bd8f1dc3Sbluhm 938bd8f1dc3Sbluhm UNUSED_P(base); 939bd8f1dc3Sbluhm UNUSED_P(systemId); 940bd8f1dc3Sbluhm UNUSED_P(publicId); 941bd8f1dc3Sbluhm ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 942bd8f1dc3Sbluhm if (ext_parser == NULL) 943bd8f1dc3Sbluhm fail("Could not create external entity parser"); 944bd8f1dc3Sbluhm if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)sizeof(text) - 1, XML_TRUE) 945bd8f1dc3Sbluhm == XML_STATUS_ERROR) 946bd8f1dc3Sbluhm xml_failure(parser); 947bd8f1dc3Sbluhm 948bd8f1dc3Sbluhm XML_ParserFree(ext_parser); 949bd8f1dc3Sbluhm return XML_STATUS_OK; 950bd8f1dc3Sbluhm } 951bd8f1dc3Sbluhm 952bd8f1dc3Sbluhm int XMLCALL 953bd8f1dc3Sbluhm external_entity_valuer(XML_Parser parser, const XML_Char *context, 954bd8f1dc3Sbluhm const XML_Char *base, const XML_Char *systemId, 955bd8f1dc3Sbluhm const XML_Char *publicId) { 956bd8f1dc3Sbluhm const char *text1 = "<!ELEMENT doc EMPTY>\n" 957bd8f1dc3Sbluhm "<!ENTITY % e1 SYSTEM '004-2.ent'>\n" 958bd8f1dc3Sbluhm "<!ENTITY % e2 '%e1;'>\n" 959bd8f1dc3Sbluhm "%e1;\n"; 960bd8f1dc3Sbluhm XML_Parser ext_parser; 961bd8f1dc3Sbluhm 962bd8f1dc3Sbluhm UNUSED_P(base); 963bd8f1dc3Sbluhm UNUSED_P(publicId); 964bd8f1dc3Sbluhm if (systemId == NULL) 965bd8f1dc3Sbluhm return XML_STATUS_OK; 966bd8f1dc3Sbluhm ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 967bd8f1dc3Sbluhm if (ext_parser == NULL) 968bd8f1dc3Sbluhm fail("Could not create external entity parser"); 969bd8f1dc3Sbluhm if (! xcstrcmp(systemId, XCS("004-1.ent"))) { 970bd8f1dc3Sbluhm if (_XML_Parse_SINGLE_BYTES(ext_parser, text1, (int)strlen(text1), XML_TRUE) 971bd8f1dc3Sbluhm == XML_STATUS_ERROR) 972bd8f1dc3Sbluhm xml_failure(ext_parser); 973bd8f1dc3Sbluhm } else if (! xcstrcmp(systemId, XCS("004-2.ent"))) { 974bd8f1dc3Sbluhm ExtFaults *fault = (ExtFaults *)XML_GetUserData(parser); 975bd8f1dc3Sbluhm enum XML_Status status; 976bd8f1dc3Sbluhm enum XML_Error error; 977bd8f1dc3Sbluhm 978bd8f1dc3Sbluhm status = _XML_Parse_SINGLE_BYTES(ext_parser, fault->parse_text, 979bd8f1dc3Sbluhm (int)strlen(fault->parse_text), XML_TRUE); 980bd8f1dc3Sbluhm if (fault->error == XML_ERROR_NONE) { 981bd8f1dc3Sbluhm if (status == XML_STATUS_ERROR) 982bd8f1dc3Sbluhm xml_failure(ext_parser); 983bd8f1dc3Sbluhm } else { 984bd8f1dc3Sbluhm if (status != XML_STATUS_ERROR) 985bd8f1dc3Sbluhm fail(fault->fail_text); 986bd8f1dc3Sbluhm error = XML_GetErrorCode(ext_parser); 987bd8f1dc3Sbluhm if (error != fault->error 988bd8f1dc3Sbluhm && (fault->error != XML_ERROR_XML_DECL 989bd8f1dc3Sbluhm || error != XML_ERROR_TEXT_DECL)) 990bd8f1dc3Sbluhm xml_failure(ext_parser); 991bd8f1dc3Sbluhm } 992bd8f1dc3Sbluhm } 993bd8f1dc3Sbluhm 994bd8f1dc3Sbluhm XML_ParserFree(ext_parser); 995bd8f1dc3Sbluhm return XML_STATUS_OK; 996bd8f1dc3Sbluhm } 997bd8f1dc3Sbluhm 998bd8f1dc3Sbluhm int XMLCALL 999bd8f1dc3Sbluhm external_entity_not_standalone(XML_Parser parser, const XML_Char *context, 1000bd8f1dc3Sbluhm const XML_Char *base, const XML_Char *systemId, 1001bd8f1dc3Sbluhm const XML_Char *publicId) { 1002bd8f1dc3Sbluhm const char *text1 = "<!ELEMENT doc EMPTY>\n" 1003bd8f1dc3Sbluhm "<!ENTITY % e1 SYSTEM 'bar'>\n" 1004bd8f1dc3Sbluhm "%e1;\n"; 1005bd8f1dc3Sbluhm const char *text2 = "<!ATTLIST doc a1 CDATA 'value'>"; 1006bd8f1dc3Sbluhm XML_Parser ext_parser; 1007bd8f1dc3Sbluhm 1008bd8f1dc3Sbluhm UNUSED_P(base); 1009bd8f1dc3Sbluhm UNUSED_P(publicId); 1010bd8f1dc3Sbluhm if (systemId == NULL) 1011bd8f1dc3Sbluhm return XML_STATUS_OK; 1012bd8f1dc3Sbluhm ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 1013bd8f1dc3Sbluhm if (ext_parser == NULL) 1014bd8f1dc3Sbluhm fail("Could not create external entity parser"); 1015bd8f1dc3Sbluhm if (! xcstrcmp(systemId, XCS("foo"))) { 1016bd8f1dc3Sbluhm XML_SetNotStandaloneHandler(ext_parser, reject_not_standalone_handler); 1017bd8f1dc3Sbluhm if (_XML_Parse_SINGLE_BYTES(ext_parser, text1, (int)strlen(text1), XML_TRUE) 1018bd8f1dc3Sbluhm != XML_STATUS_ERROR) 1019bd8f1dc3Sbluhm fail("Expected not standalone rejection"); 1020bd8f1dc3Sbluhm if (XML_GetErrorCode(ext_parser) != XML_ERROR_NOT_STANDALONE) 1021bd8f1dc3Sbluhm xml_failure(ext_parser); 1022bd8f1dc3Sbluhm XML_SetNotStandaloneHandler(ext_parser, NULL); 1023bd8f1dc3Sbluhm XML_ParserFree(ext_parser); 1024bd8f1dc3Sbluhm return XML_STATUS_ERROR; 1025bd8f1dc3Sbluhm } else if (! xcstrcmp(systemId, XCS("bar"))) { 1026bd8f1dc3Sbluhm if (_XML_Parse_SINGLE_BYTES(ext_parser, text2, (int)strlen(text2), XML_TRUE) 1027bd8f1dc3Sbluhm == XML_STATUS_ERROR) 1028bd8f1dc3Sbluhm xml_failure(ext_parser); 1029bd8f1dc3Sbluhm } 1030bd8f1dc3Sbluhm 1031bd8f1dc3Sbluhm XML_ParserFree(ext_parser); 1032bd8f1dc3Sbluhm return XML_STATUS_OK; 1033bd8f1dc3Sbluhm } 1034bd8f1dc3Sbluhm 1035bd8f1dc3Sbluhm int XMLCALL 1036bd8f1dc3Sbluhm external_entity_value_aborter(XML_Parser parser, const XML_Char *context, 1037bd8f1dc3Sbluhm const XML_Char *base, const XML_Char *systemId, 1038bd8f1dc3Sbluhm const XML_Char *publicId) { 1039bd8f1dc3Sbluhm const char *text1 = "<!ELEMENT doc EMPTY>\n" 1040bd8f1dc3Sbluhm "<!ENTITY % e1 SYSTEM '004-2.ent'>\n" 1041bd8f1dc3Sbluhm "<!ENTITY % e2 '%e1;'>\n" 1042bd8f1dc3Sbluhm "%e1;\n"; 1043bd8f1dc3Sbluhm const char *text2 = "<?xml version='1.0' encoding='utf-8'?>"; 1044bd8f1dc3Sbluhm XML_Parser ext_parser; 1045bd8f1dc3Sbluhm 1046bd8f1dc3Sbluhm UNUSED_P(base); 1047bd8f1dc3Sbluhm UNUSED_P(publicId); 1048bd8f1dc3Sbluhm if (systemId == NULL) 1049bd8f1dc3Sbluhm return XML_STATUS_OK; 1050bd8f1dc3Sbluhm ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 1051bd8f1dc3Sbluhm if (ext_parser == NULL) 1052bd8f1dc3Sbluhm fail("Could not create external entity parser"); 1053bd8f1dc3Sbluhm if (! xcstrcmp(systemId, XCS("004-1.ent"))) { 1054bd8f1dc3Sbluhm if (_XML_Parse_SINGLE_BYTES(ext_parser, text1, (int)strlen(text1), XML_TRUE) 1055bd8f1dc3Sbluhm == XML_STATUS_ERROR) 1056bd8f1dc3Sbluhm xml_failure(ext_parser); 1057bd8f1dc3Sbluhm } 1058bd8f1dc3Sbluhm if (! xcstrcmp(systemId, XCS("004-2.ent"))) { 1059bd8f1dc3Sbluhm XML_SetXmlDeclHandler(ext_parser, entity_suspending_xdecl_handler); 1060bd8f1dc3Sbluhm XML_SetUserData(ext_parser, ext_parser); 1061bd8f1dc3Sbluhm if (_XML_Parse_SINGLE_BYTES(ext_parser, text2, (int)strlen(text2), XML_TRUE) 1062bd8f1dc3Sbluhm != XML_STATUS_ERROR) 1063bd8f1dc3Sbluhm fail("Aborted parse not faulted"); 1064bd8f1dc3Sbluhm if (XML_GetErrorCode(ext_parser) != XML_ERROR_ABORTED) 1065bd8f1dc3Sbluhm xml_failure(ext_parser); 1066bd8f1dc3Sbluhm } 1067bd8f1dc3Sbluhm 1068bd8f1dc3Sbluhm XML_ParserFree(ext_parser); 1069bd8f1dc3Sbluhm return XML_STATUS_OK; 1070bd8f1dc3Sbluhm } 1071bd8f1dc3Sbluhm 1072bd8f1dc3Sbluhm int XMLCALL 1073bd8f1dc3Sbluhm external_entity_public(XML_Parser parser, const XML_Char *context, 1074bd8f1dc3Sbluhm const XML_Char *base, const XML_Char *systemId, 1075bd8f1dc3Sbluhm const XML_Char *publicId) { 1076bd8f1dc3Sbluhm const char *text1 = (const char *)XML_GetUserData(parser); 1077bd8f1dc3Sbluhm const char *text2 = "<!ATTLIST doc a CDATA 'value'>"; 1078bd8f1dc3Sbluhm const char *text = NULL; 1079bd8f1dc3Sbluhm XML_Parser ext_parser; 1080bd8f1dc3Sbluhm int parse_res; 1081bd8f1dc3Sbluhm 1082bd8f1dc3Sbluhm UNUSED_P(base); 1083bd8f1dc3Sbluhm ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 1084bd8f1dc3Sbluhm if (ext_parser == NULL) 1085bd8f1dc3Sbluhm return XML_STATUS_ERROR; 1086bd8f1dc3Sbluhm if (systemId != NULL && ! xcstrcmp(systemId, XCS("http://example.org/"))) { 1087bd8f1dc3Sbluhm text = text1; 1088bd8f1dc3Sbluhm } else if (publicId != NULL && ! xcstrcmp(publicId, XCS("foo"))) { 1089bd8f1dc3Sbluhm text = text2; 1090bd8f1dc3Sbluhm } else 1091bd8f1dc3Sbluhm fail("Unexpected parameters to external entity parser"); 1092bd8f1dc3Sbluhm assert(text != NULL); 1093bd8f1dc3Sbluhm parse_res 1094bd8f1dc3Sbluhm = _XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE); 1095bd8f1dc3Sbluhm XML_ParserFree(ext_parser); 1096bd8f1dc3Sbluhm return parse_res; 1097bd8f1dc3Sbluhm } 1098bd8f1dc3Sbluhm 1099bd8f1dc3Sbluhm int XMLCALL 1100bd8f1dc3Sbluhm external_entity_devaluer(XML_Parser parser, const XML_Char *context, 1101bd8f1dc3Sbluhm const XML_Char *base, const XML_Char *systemId, 1102bd8f1dc3Sbluhm const XML_Char *publicId) { 1103bd8f1dc3Sbluhm const char *text = "<!ELEMENT doc EMPTY>\n" 1104bd8f1dc3Sbluhm "<!ENTITY % e1 SYSTEM 'bar'>\n" 1105bd8f1dc3Sbluhm "%e1;\n"; 1106bd8f1dc3Sbluhm XML_Parser ext_parser; 1107bd8f1dc3Sbluhm int clear_handler_flag = (XML_GetUserData(parser) != NULL); 1108bd8f1dc3Sbluhm 1109bd8f1dc3Sbluhm UNUSED_P(base); 1110bd8f1dc3Sbluhm UNUSED_P(publicId); 1111bd8f1dc3Sbluhm if (systemId == NULL || ! xcstrcmp(systemId, XCS("bar"))) 1112bd8f1dc3Sbluhm return XML_STATUS_OK; 1113bd8f1dc3Sbluhm if (xcstrcmp(systemId, XCS("foo"))) 1114bd8f1dc3Sbluhm fail("Unexpected system ID"); 1115bd8f1dc3Sbluhm ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 1116bd8f1dc3Sbluhm if (ext_parser == NULL) 1117bd8f1dc3Sbluhm fail("Could note create external entity parser"); 1118bd8f1dc3Sbluhm if (clear_handler_flag) 1119bd8f1dc3Sbluhm XML_SetExternalEntityRefHandler(ext_parser, NULL); 1120bd8f1dc3Sbluhm if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE) 1121bd8f1dc3Sbluhm == XML_STATUS_ERROR) 1122bd8f1dc3Sbluhm xml_failure(ext_parser); 1123bd8f1dc3Sbluhm 1124bd8f1dc3Sbluhm XML_ParserFree(ext_parser); 1125bd8f1dc3Sbluhm return XML_STATUS_OK; 1126bd8f1dc3Sbluhm } 1127bd8f1dc3Sbluhm 1128bd8f1dc3Sbluhm int XMLCALL 1129bd8f1dc3Sbluhm external_entity_oneshot_loader(XML_Parser parser, const XML_Char *context, 1130bd8f1dc3Sbluhm const XML_Char *base, const XML_Char *systemId, 1131bd8f1dc3Sbluhm const XML_Char *publicId) { 1132bd8f1dc3Sbluhm ExtHdlrData *test_data = (ExtHdlrData *)XML_GetUserData(parser); 1133bd8f1dc3Sbluhm XML_Parser ext_parser; 1134bd8f1dc3Sbluhm 1135bd8f1dc3Sbluhm UNUSED_P(base); 1136bd8f1dc3Sbluhm UNUSED_P(systemId); 1137bd8f1dc3Sbluhm UNUSED_P(publicId); 1138bd8f1dc3Sbluhm ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 1139bd8f1dc3Sbluhm if (ext_parser == NULL) 1140bd8f1dc3Sbluhm fail("Could not create external entity parser."); 1141bd8f1dc3Sbluhm /* Use the requested entity parser for further externals */ 1142bd8f1dc3Sbluhm XML_SetExternalEntityRefHandler(ext_parser, test_data->handler); 1143bd8f1dc3Sbluhm if (_XML_Parse_SINGLE_BYTES(ext_parser, test_data->parse_text, 1144bd8f1dc3Sbluhm (int)strlen(test_data->parse_text), XML_TRUE) 1145bd8f1dc3Sbluhm == XML_STATUS_ERROR) { 1146bd8f1dc3Sbluhm xml_failure(ext_parser); 1147bd8f1dc3Sbluhm } 1148bd8f1dc3Sbluhm 1149bd8f1dc3Sbluhm XML_ParserFree(ext_parser); 1150bd8f1dc3Sbluhm return XML_STATUS_OK; 1151bd8f1dc3Sbluhm } 1152bd8f1dc3Sbluhm 1153bd8f1dc3Sbluhm int XMLCALL 1154bd8f1dc3Sbluhm external_entity_loader2(XML_Parser parser, const XML_Char *context, 1155bd8f1dc3Sbluhm const XML_Char *base, const XML_Char *systemId, 1156bd8f1dc3Sbluhm const XML_Char *publicId) { 1157bd8f1dc3Sbluhm ExtTest2 *test_data = (ExtTest2 *)XML_GetUserData(parser); 1158bd8f1dc3Sbluhm XML_Parser extparser; 1159bd8f1dc3Sbluhm 1160bd8f1dc3Sbluhm UNUSED_P(base); 1161bd8f1dc3Sbluhm UNUSED_P(systemId); 1162bd8f1dc3Sbluhm UNUSED_P(publicId); 1163bd8f1dc3Sbluhm extparser = XML_ExternalEntityParserCreate(parser, context, NULL); 1164bd8f1dc3Sbluhm if (extparser == NULL) 1165bd8f1dc3Sbluhm fail("Coulr not create external entity parser"); 1166bd8f1dc3Sbluhm if (test_data->encoding != NULL) { 1167bd8f1dc3Sbluhm if (! XML_SetEncoding(extparser, test_data->encoding)) 1168bd8f1dc3Sbluhm fail("XML_SetEncoding() ignored for external entity"); 1169bd8f1dc3Sbluhm } 1170bd8f1dc3Sbluhm if (_XML_Parse_SINGLE_BYTES(extparser, test_data->parse_text, 1171bd8f1dc3Sbluhm test_data->parse_len, XML_TRUE) 1172bd8f1dc3Sbluhm == XML_STATUS_ERROR) { 1173bd8f1dc3Sbluhm xml_failure(extparser); 1174bd8f1dc3Sbluhm } 1175bd8f1dc3Sbluhm 1176bd8f1dc3Sbluhm XML_ParserFree(extparser); 1177bd8f1dc3Sbluhm return XML_STATUS_OK; 1178bd8f1dc3Sbluhm } 1179bd8f1dc3Sbluhm 1180bd8f1dc3Sbluhm int XMLCALL 1181bd8f1dc3Sbluhm external_entity_faulter2(XML_Parser parser, const XML_Char *context, 1182bd8f1dc3Sbluhm const XML_Char *base, const XML_Char *systemId, 1183bd8f1dc3Sbluhm const XML_Char *publicId) { 1184bd8f1dc3Sbluhm ExtFaults2 *test_data = (ExtFaults2 *)XML_GetUserData(parser); 1185bd8f1dc3Sbluhm XML_Parser extparser; 1186bd8f1dc3Sbluhm 1187bd8f1dc3Sbluhm UNUSED_P(base); 1188bd8f1dc3Sbluhm UNUSED_P(systemId); 1189bd8f1dc3Sbluhm UNUSED_P(publicId); 1190bd8f1dc3Sbluhm extparser = XML_ExternalEntityParserCreate(parser, context, NULL); 1191bd8f1dc3Sbluhm if (extparser == NULL) 1192bd8f1dc3Sbluhm fail("Could not create external entity parser"); 1193bd8f1dc3Sbluhm if (test_data->encoding != NULL) { 1194bd8f1dc3Sbluhm if (! XML_SetEncoding(extparser, test_data->encoding)) 1195bd8f1dc3Sbluhm fail("XML_SetEncoding() ignored for external entity"); 1196bd8f1dc3Sbluhm } 1197bd8f1dc3Sbluhm if (_XML_Parse_SINGLE_BYTES(extparser, test_data->parse_text, 1198bd8f1dc3Sbluhm test_data->parse_len, XML_TRUE) 1199bd8f1dc3Sbluhm != XML_STATUS_ERROR) 1200bd8f1dc3Sbluhm fail(test_data->fail_text); 1201bd8f1dc3Sbluhm if (XML_GetErrorCode(extparser) != test_data->error) 1202bd8f1dc3Sbluhm xml_failure(extparser); 1203bd8f1dc3Sbluhm 1204bd8f1dc3Sbluhm XML_ParserFree(extparser); 1205bd8f1dc3Sbluhm return XML_STATUS_ERROR; 1206bd8f1dc3Sbluhm } 1207bd8f1dc3Sbluhm 1208bd8f1dc3Sbluhm int XMLCALL 1209bd8f1dc3Sbluhm external_entity_unfinished_attlist(XML_Parser parser, const XML_Char *context, 1210bd8f1dc3Sbluhm const XML_Char *base, 1211bd8f1dc3Sbluhm const XML_Char *systemId, 1212bd8f1dc3Sbluhm const XML_Char *publicId) { 1213bd8f1dc3Sbluhm const char *text = "<!ELEMENT barf ANY>\n" 1214bd8f1dc3Sbluhm "<!ATTLIST barf my_attr (blah|%blah;a|foo) #REQUIRED>\n" 1215bd8f1dc3Sbluhm "<!--COMMENT-->\n"; 1216bd8f1dc3Sbluhm XML_Parser ext_parser; 1217bd8f1dc3Sbluhm 1218bd8f1dc3Sbluhm UNUSED_P(base); 1219bd8f1dc3Sbluhm UNUSED_P(publicId); 1220bd8f1dc3Sbluhm if (systemId == NULL) 1221bd8f1dc3Sbluhm return XML_STATUS_OK; 1222bd8f1dc3Sbluhm 1223bd8f1dc3Sbluhm ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 1224bd8f1dc3Sbluhm if (ext_parser == NULL) 1225bd8f1dc3Sbluhm fail("Could not create external entity parser"); 1226bd8f1dc3Sbluhm 1227bd8f1dc3Sbluhm if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE) 1228bd8f1dc3Sbluhm == XML_STATUS_ERROR) 1229bd8f1dc3Sbluhm xml_failure(ext_parser); 1230bd8f1dc3Sbluhm 1231bd8f1dc3Sbluhm XML_ParserFree(ext_parser); 1232bd8f1dc3Sbluhm return XML_STATUS_OK; 1233bd8f1dc3Sbluhm } 1234bd8f1dc3Sbluhm 1235bd8f1dc3Sbluhm int XMLCALL 1236bd8f1dc3Sbluhm external_entity_handler(XML_Parser parser, const XML_Char *context, 1237bd8f1dc3Sbluhm const XML_Char *base, const XML_Char *systemId, 1238bd8f1dc3Sbluhm const XML_Char *publicId) { 1239bd8f1dc3Sbluhm void *user_data = XML_GetUserData(parser); 1240bd8f1dc3Sbluhm const char *text; 1241bd8f1dc3Sbluhm XML_Parser p2; 1242bd8f1dc3Sbluhm 1243bd8f1dc3Sbluhm UNUSED_P(base); 1244bd8f1dc3Sbluhm UNUSED_P(systemId); 1245bd8f1dc3Sbluhm UNUSED_P(publicId); 1246bd8f1dc3Sbluhm if (user_data == NULL) 1247bd8f1dc3Sbluhm text = ("<!ELEMENT doc (e+)>\n" 1248bd8f1dc3Sbluhm "<!ATTLIST doc xmlns CDATA #IMPLIED>\n" 1249bd8f1dc3Sbluhm "<!ELEMENT e EMPTY>\n"); 1250bd8f1dc3Sbluhm else 1251bd8f1dc3Sbluhm text = ("<?xml version='1.0' encoding='us-ascii'?>" 1252bd8f1dc3Sbluhm "<e/>"); 1253bd8f1dc3Sbluhm 1254bd8f1dc3Sbluhm /* Set user data to any non-NULL value */ 1255bd8f1dc3Sbluhm XML_SetUserData(parser, parser); 1256bd8f1dc3Sbluhm p2 = XML_ExternalEntityParserCreate(parser, context, NULL); 1257bd8f1dc3Sbluhm if (_XML_Parse_SINGLE_BYTES(p2, text, (int)strlen(text), XML_TRUE) 1258bd8f1dc3Sbluhm == XML_STATUS_ERROR) { 1259bd8f1dc3Sbluhm xml_failure(p2); 1260bd8f1dc3Sbluhm return XML_STATUS_ERROR; 1261bd8f1dc3Sbluhm } 1262bd8f1dc3Sbluhm XML_ParserFree(p2); 1263bd8f1dc3Sbluhm return XML_STATUS_OK; 1264bd8f1dc3Sbluhm } 1265bd8f1dc3Sbluhm 1266bd8f1dc3Sbluhm int XMLCALL 1267bd8f1dc3Sbluhm external_entity_duff_loader(XML_Parser parser, const XML_Char *context, 1268bd8f1dc3Sbluhm const XML_Char *base, const XML_Char *systemId, 1269bd8f1dc3Sbluhm const XML_Char *publicId) { 1270bd8f1dc3Sbluhm XML_Parser new_parser; 1271bd8f1dc3Sbluhm unsigned int i; 1272bd8f1dc3Sbluhm const unsigned int max_alloc_count = 10; 1273bd8f1dc3Sbluhm 1274bd8f1dc3Sbluhm UNUSED_P(base); 1275bd8f1dc3Sbluhm UNUSED_P(systemId); 1276bd8f1dc3Sbluhm UNUSED_P(publicId); 1277bd8f1dc3Sbluhm /* Try a few different allocation levels */ 1278bd8f1dc3Sbluhm for (i = 0; i < max_alloc_count; i++) { 1279bd8f1dc3Sbluhm g_allocation_count = i; 1280bd8f1dc3Sbluhm new_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 1281bd8f1dc3Sbluhm if (new_parser != NULL) { 1282bd8f1dc3Sbluhm XML_ParserFree(new_parser); 1283bd8f1dc3Sbluhm break; 1284bd8f1dc3Sbluhm } 1285bd8f1dc3Sbluhm } 1286bd8f1dc3Sbluhm if (i == 0) 1287bd8f1dc3Sbluhm fail("External parser creation ignored failing allocator"); 1288bd8f1dc3Sbluhm else if (i == max_alloc_count) 1289bd8f1dc3Sbluhm fail("Extern parser not created with max allocation count"); 1290bd8f1dc3Sbluhm 1291bd8f1dc3Sbluhm /* Make sure other random allocation doesn't now fail */ 1292bd8f1dc3Sbluhm g_allocation_count = ALLOC_ALWAYS_SUCCEED; 1293bd8f1dc3Sbluhm 1294bd8f1dc3Sbluhm /* Make sure the failure code path is executed too */ 1295bd8f1dc3Sbluhm return XML_STATUS_ERROR; 1296bd8f1dc3Sbluhm } 1297bd8f1dc3Sbluhm 1298bd8f1dc3Sbluhm int XMLCALL 1299bd8f1dc3Sbluhm external_entity_dbl_handler(XML_Parser parser, const XML_Char *context, 1300bd8f1dc3Sbluhm const XML_Char *base, const XML_Char *systemId, 1301bd8f1dc3Sbluhm const XML_Char *publicId) { 1302bd8f1dc3Sbluhm int *pcallno = (int *)XML_GetUserData(parser); 1303bd8f1dc3Sbluhm int callno = *pcallno; 1304bd8f1dc3Sbluhm const char *text; 1305bd8f1dc3Sbluhm XML_Parser new_parser = NULL; 1306bd8f1dc3Sbluhm int i; 1307bd8f1dc3Sbluhm const int max_alloc_count = 20; 1308bd8f1dc3Sbluhm 1309bd8f1dc3Sbluhm UNUSED_P(base); 1310bd8f1dc3Sbluhm UNUSED_P(systemId); 1311bd8f1dc3Sbluhm UNUSED_P(publicId); 1312bd8f1dc3Sbluhm if (callno == 0) { 1313bd8f1dc3Sbluhm /* First time through, check how many calls to malloc occur */ 1314bd8f1dc3Sbluhm text = ("<!ELEMENT doc (e+)>\n" 1315bd8f1dc3Sbluhm "<!ATTLIST doc xmlns CDATA #IMPLIED>\n" 1316bd8f1dc3Sbluhm "<!ELEMENT e EMPTY>\n"); 1317bd8f1dc3Sbluhm g_allocation_count = 10000; 1318bd8f1dc3Sbluhm new_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 1319bd8f1dc3Sbluhm if (new_parser == NULL) { 1320bd8f1dc3Sbluhm fail("Unable to allocate first external parser"); 1321bd8f1dc3Sbluhm return XML_STATUS_ERROR; 1322bd8f1dc3Sbluhm } 1323bd8f1dc3Sbluhm /* Stash the number of calls in the user data */ 1324bd8f1dc3Sbluhm *pcallno = 10000 - g_allocation_count; 1325bd8f1dc3Sbluhm } else { 1326bd8f1dc3Sbluhm text = ("<?xml version='1.0' encoding='us-ascii'?>" 1327bd8f1dc3Sbluhm "<e/>"); 1328bd8f1dc3Sbluhm /* Try at varying levels to exercise more code paths */ 1329bd8f1dc3Sbluhm for (i = 0; i < max_alloc_count; i++) { 1330bd8f1dc3Sbluhm g_allocation_count = callno + i; 1331bd8f1dc3Sbluhm new_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 1332bd8f1dc3Sbluhm if (new_parser != NULL) 1333bd8f1dc3Sbluhm break; 1334bd8f1dc3Sbluhm } 1335bd8f1dc3Sbluhm if (i == 0) { 1336bd8f1dc3Sbluhm fail("Second external parser unexpectedly created"); 1337bd8f1dc3Sbluhm XML_ParserFree(new_parser); 1338bd8f1dc3Sbluhm return XML_STATUS_ERROR; 1339bd8f1dc3Sbluhm } else if (i == max_alloc_count) { 1340bd8f1dc3Sbluhm fail("Second external parser not created"); 1341bd8f1dc3Sbluhm return XML_STATUS_ERROR; 1342bd8f1dc3Sbluhm } 1343bd8f1dc3Sbluhm } 1344bd8f1dc3Sbluhm 1345bd8f1dc3Sbluhm g_allocation_count = ALLOC_ALWAYS_SUCCEED; 1346bd8f1dc3Sbluhm if (_XML_Parse_SINGLE_BYTES(new_parser, text, (int)strlen(text), XML_TRUE) 1347bd8f1dc3Sbluhm == XML_STATUS_ERROR) { 1348bd8f1dc3Sbluhm xml_failure(new_parser); 1349bd8f1dc3Sbluhm return XML_STATUS_ERROR; 1350bd8f1dc3Sbluhm } 1351bd8f1dc3Sbluhm XML_ParserFree(new_parser); 1352bd8f1dc3Sbluhm return XML_STATUS_OK; 1353bd8f1dc3Sbluhm } 1354bd8f1dc3Sbluhm 1355bd8f1dc3Sbluhm int XMLCALL 1356bd8f1dc3Sbluhm external_entity_dbl_handler_2(XML_Parser parser, const XML_Char *context, 1357bd8f1dc3Sbluhm const XML_Char *base, const XML_Char *systemId, 1358bd8f1dc3Sbluhm const XML_Char *publicId) { 1359bd8f1dc3Sbluhm int *pcallno = (int *)XML_GetUserData(parser); 1360bd8f1dc3Sbluhm int callno = *pcallno; 1361bd8f1dc3Sbluhm const char *text; 1362bd8f1dc3Sbluhm XML_Parser new_parser; 1363bd8f1dc3Sbluhm enum XML_Status rv; 1364bd8f1dc3Sbluhm 1365bd8f1dc3Sbluhm UNUSED_P(base); 1366bd8f1dc3Sbluhm UNUSED_P(systemId); 1367bd8f1dc3Sbluhm UNUSED_P(publicId); 1368bd8f1dc3Sbluhm if (callno == 0) { 1369bd8f1dc3Sbluhm /* Try different allocation levels for whole exercise */ 1370bd8f1dc3Sbluhm text = ("<!ELEMENT doc (e+)>\n" 1371bd8f1dc3Sbluhm "<!ATTLIST doc xmlns CDATA #IMPLIED>\n" 1372bd8f1dc3Sbluhm "<!ELEMENT e EMPTY>\n"); 1373bd8f1dc3Sbluhm *pcallno = 1; 1374bd8f1dc3Sbluhm new_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 1375bd8f1dc3Sbluhm if (new_parser == NULL) 1376bd8f1dc3Sbluhm return XML_STATUS_ERROR; 1377bd8f1dc3Sbluhm rv = _XML_Parse_SINGLE_BYTES(new_parser, text, (int)strlen(text), XML_TRUE); 1378bd8f1dc3Sbluhm } else { 1379bd8f1dc3Sbluhm /* Just run through once */ 1380bd8f1dc3Sbluhm text = ("<?xml version='1.0' encoding='us-ascii'?>" 1381bd8f1dc3Sbluhm "<e/>"); 1382bd8f1dc3Sbluhm new_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 1383bd8f1dc3Sbluhm if (new_parser == NULL) 1384bd8f1dc3Sbluhm return XML_STATUS_ERROR; 1385bd8f1dc3Sbluhm rv = _XML_Parse_SINGLE_BYTES(new_parser, text, (int)strlen(text), XML_TRUE); 1386bd8f1dc3Sbluhm } 1387bd8f1dc3Sbluhm XML_ParserFree(new_parser); 1388bd8f1dc3Sbluhm if (rv == XML_STATUS_ERROR) 1389bd8f1dc3Sbluhm return XML_STATUS_ERROR; 1390bd8f1dc3Sbluhm return XML_STATUS_OK; 1391bd8f1dc3Sbluhm } 1392bd8f1dc3Sbluhm 1393bd8f1dc3Sbluhm int XMLCALL 1394bd8f1dc3Sbluhm external_entity_alloc_set_encoding(XML_Parser parser, const XML_Char *context, 1395bd8f1dc3Sbluhm const XML_Char *base, 1396bd8f1dc3Sbluhm const XML_Char *systemId, 1397bd8f1dc3Sbluhm const XML_Char *publicId) { 1398bd8f1dc3Sbluhm /* As for external_entity_loader() */ 1399bd8f1dc3Sbluhm const char *text = "<?xml encoding='iso-8859-3'?>" 1400bd8f1dc3Sbluhm "\xC3\xA9"; 1401bd8f1dc3Sbluhm XML_Parser ext_parser; 1402bd8f1dc3Sbluhm enum XML_Status status; 1403bd8f1dc3Sbluhm 1404bd8f1dc3Sbluhm UNUSED_P(base); 1405bd8f1dc3Sbluhm UNUSED_P(systemId); 1406bd8f1dc3Sbluhm UNUSED_P(publicId); 1407bd8f1dc3Sbluhm ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 1408bd8f1dc3Sbluhm if (ext_parser == NULL) 1409bd8f1dc3Sbluhm return XML_STATUS_ERROR; 1410bd8f1dc3Sbluhm if (! XML_SetEncoding(ext_parser, XCS("utf-8"))) { 1411bd8f1dc3Sbluhm XML_ParserFree(ext_parser); 1412bd8f1dc3Sbluhm return XML_STATUS_ERROR; 1413bd8f1dc3Sbluhm } 1414bd8f1dc3Sbluhm status 1415bd8f1dc3Sbluhm = _XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE); 1416bd8f1dc3Sbluhm XML_ParserFree(ext_parser); 1417bd8f1dc3Sbluhm if (status == XML_STATUS_ERROR) 1418bd8f1dc3Sbluhm return XML_STATUS_ERROR; 1419bd8f1dc3Sbluhm return XML_STATUS_OK; 1420bd8f1dc3Sbluhm } 1421bd8f1dc3Sbluhm 1422bd8f1dc3Sbluhm int XMLCALL 1423bd8f1dc3Sbluhm external_entity_reallocator(XML_Parser parser, const XML_Char *context, 1424bd8f1dc3Sbluhm const XML_Char *base, const XML_Char *systemId, 1425bd8f1dc3Sbluhm const XML_Char *publicId) { 1426bd8f1dc3Sbluhm const char *text = get_buffer_test_text; 1427bd8f1dc3Sbluhm XML_Parser ext_parser; 1428bd8f1dc3Sbluhm void *buffer; 1429bd8f1dc3Sbluhm enum XML_Status status; 1430bd8f1dc3Sbluhm 1431bd8f1dc3Sbluhm UNUSED_P(base); 1432bd8f1dc3Sbluhm UNUSED_P(systemId); 1433bd8f1dc3Sbluhm UNUSED_P(publicId); 1434bd8f1dc3Sbluhm ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 1435bd8f1dc3Sbluhm if (ext_parser == NULL) 1436bd8f1dc3Sbluhm fail("Could not create external entity parser"); 1437bd8f1dc3Sbluhm 1438bd8f1dc3Sbluhm g_reallocation_count = *(int *)XML_GetUserData(parser); 1439bd8f1dc3Sbluhm buffer = XML_GetBuffer(ext_parser, 1536); 1440bd8f1dc3Sbluhm if (buffer == NULL) 1441bd8f1dc3Sbluhm fail("Buffer allocation failed"); 1442bd8f1dc3Sbluhm assert(buffer != NULL); 1443bd8f1dc3Sbluhm memcpy(buffer, text, strlen(text)); 1444bd8f1dc3Sbluhm status = XML_ParseBuffer(ext_parser, (int)strlen(text), XML_FALSE); 1445bd8f1dc3Sbluhm g_reallocation_count = -1; 1446bd8f1dc3Sbluhm XML_ParserFree(ext_parser); 1447bd8f1dc3Sbluhm return (status == XML_STATUS_OK) ? XML_STATUS_OK : XML_STATUS_ERROR; 1448bd8f1dc3Sbluhm } 1449bd8f1dc3Sbluhm 1450bd8f1dc3Sbluhm int XMLCALL 1451bd8f1dc3Sbluhm external_entity_alloc(XML_Parser parser, const XML_Char *context, 1452bd8f1dc3Sbluhm const XML_Char *base, const XML_Char *systemId, 1453bd8f1dc3Sbluhm const XML_Char *publicId) { 1454bd8f1dc3Sbluhm const char *text = (const char *)XML_GetUserData(parser); 1455bd8f1dc3Sbluhm XML_Parser ext_parser; 1456bd8f1dc3Sbluhm int parse_res; 1457bd8f1dc3Sbluhm 1458bd8f1dc3Sbluhm UNUSED_P(base); 1459bd8f1dc3Sbluhm UNUSED_P(systemId); 1460bd8f1dc3Sbluhm UNUSED_P(publicId); 1461bd8f1dc3Sbluhm ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 1462bd8f1dc3Sbluhm if (ext_parser == NULL) 1463bd8f1dc3Sbluhm return XML_STATUS_ERROR; 1464bd8f1dc3Sbluhm parse_res 1465bd8f1dc3Sbluhm = _XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE); 1466bd8f1dc3Sbluhm XML_ParserFree(ext_parser); 1467bd8f1dc3Sbluhm return parse_res; 1468bd8f1dc3Sbluhm } 1469bd8f1dc3Sbluhm 1470bd8f1dc3Sbluhm int XMLCALL 1471bd8f1dc3Sbluhm external_entity_parser_create_alloc_fail_handler(XML_Parser parser, 1472bd8f1dc3Sbluhm const XML_Char *context, 1473bd8f1dc3Sbluhm const XML_Char *base, 1474bd8f1dc3Sbluhm const XML_Char *systemId, 1475bd8f1dc3Sbluhm const XML_Char *publicId) { 1476bd8f1dc3Sbluhm UNUSED_P(base); 1477bd8f1dc3Sbluhm UNUSED_P(systemId); 1478bd8f1dc3Sbluhm UNUSED_P(publicId); 1479bd8f1dc3Sbluhm 1480bd8f1dc3Sbluhm if (context != NULL) 1481bd8f1dc3Sbluhm fail("Unexpected non-NULL context"); 1482bd8f1dc3Sbluhm 1483bd8f1dc3Sbluhm // The following number intends to fail the upcoming allocation in line 1484bd8f1dc3Sbluhm // "parser->m_protocolEncodingName = copyString(encodingName, 1485bd8f1dc3Sbluhm // &(parser->m_mem));" in function parserInit. 1486bd8f1dc3Sbluhm g_allocation_count = 3; 1487bd8f1dc3Sbluhm 1488bd8f1dc3Sbluhm const XML_Char *const encodingName = XCS("UTF-8"); // needs something non-NULL 1489bd8f1dc3Sbluhm const XML_Parser ext_parser 1490bd8f1dc3Sbluhm = XML_ExternalEntityParserCreate(parser, context, encodingName); 1491bd8f1dc3Sbluhm if (ext_parser != NULL) 1492bd8f1dc3Sbluhm fail( 1493bd8f1dc3Sbluhm "Call to XML_ExternalEntityParserCreate was expected to fail out-of-memory"); 1494bd8f1dc3Sbluhm 1495bd8f1dc3Sbluhm g_allocation_count = ALLOC_ALWAYS_SUCCEED; 1496bd8f1dc3Sbluhm return XML_STATUS_ERROR; 1497bd8f1dc3Sbluhm } 1498bd8f1dc3Sbluhm 1499bd8f1dc3Sbluhm #if XML_GE == 1 1500bd8f1dc3Sbluhm int 1501bd8f1dc3Sbluhm accounting_external_entity_ref_handler(XML_Parser parser, 1502bd8f1dc3Sbluhm const XML_Char *context, 1503bd8f1dc3Sbluhm const XML_Char *base, 1504bd8f1dc3Sbluhm const XML_Char *systemId, 1505bd8f1dc3Sbluhm const XML_Char *publicId) { 1506bd8f1dc3Sbluhm UNUSED_P(base); 1507bd8f1dc3Sbluhm UNUSED_P(publicId); 1508bd8f1dc3Sbluhm 1509bd8f1dc3Sbluhm const struct AccountingTestCase *const testCase 1510bd8f1dc3Sbluhm = (const struct AccountingTestCase *)XML_GetUserData(parser); 1511bd8f1dc3Sbluhm 1512bd8f1dc3Sbluhm const char *externalText = NULL; 1513bd8f1dc3Sbluhm if (xcstrcmp(systemId, XCS("first.ent")) == 0) { 1514bd8f1dc3Sbluhm externalText = testCase->firstExternalText; 1515bd8f1dc3Sbluhm } else if (xcstrcmp(systemId, XCS("second.ent")) == 0) { 1516bd8f1dc3Sbluhm externalText = testCase->secondExternalText; 1517bd8f1dc3Sbluhm } else { 1518bd8f1dc3Sbluhm assert(! "systemId is neither \"first.ent\" nor \"second.ent\""); 1519bd8f1dc3Sbluhm } 1520bd8f1dc3Sbluhm assert(externalText); 1521bd8f1dc3Sbluhm 1522bd8f1dc3Sbluhm XML_Parser entParser = XML_ExternalEntityParserCreate(parser, context, 0); 1523bd8f1dc3Sbluhm assert(entParser); 1524bd8f1dc3Sbluhm 1525bd8f1dc3Sbluhm const enum XML_Status status = _XML_Parse_SINGLE_BYTES( 1526bd8f1dc3Sbluhm entParser, externalText, (int)strlen(externalText), XML_TRUE); 1527bd8f1dc3Sbluhm 1528bd8f1dc3Sbluhm XML_ParserFree(entParser); 1529bd8f1dc3Sbluhm return status; 1530bd8f1dc3Sbluhm } 1531bd8f1dc3Sbluhm #endif /* XML_GE == 1 */ 1532bd8f1dc3Sbluhm 1533bd8f1dc3Sbluhm /* NotStandalone handlers */ 1534bd8f1dc3Sbluhm 1535bd8f1dc3Sbluhm int XMLCALL 1536bd8f1dc3Sbluhm reject_not_standalone_handler(void *userData) { 1537bd8f1dc3Sbluhm UNUSED_P(userData); 1538bd8f1dc3Sbluhm return XML_STATUS_ERROR; 1539bd8f1dc3Sbluhm } 1540bd8f1dc3Sbluhm 1541bd8f1dc3Sbluhm int XMLCALL 1542bd8f1dc3Sbluhm accept_not_standalone_handler(void *userData) { 1543bd8f1dc3Sbluhm UNUSED_P(userData); 1544bd8f1dc3Sbluhm return XML_STATUS_OK; 1545bd8f1dc3Sbluhm } 1546bd8f1dc3Sbluhm 1547bd8f1dc3Sbluhm /* Attribute List handlers */ 1548bd8f1dc3Sbluhm void XMLCALL 1549bd8f1dc3Sbluhm verify_attlist_decl_handler(void *userData, const XML_Char *element_name, 1550bd8f1dc3Sbluhm const XML_Char *attr_name, 1551bd8f1dc3Sbluhm const XML_Char *attr_type, 1552bd8f1dc3Sbluhm const XML_Char *default_value, int is_required) { 1553bd8f1dc3Sbluhm AttTest *at = (AttTest *)userData; 1554bd8f1dc3Sbluhm 1555bd8f1dc3Sbluhm if (xcstrcmp(element_name, at->element_name)) 1556bd8f1dc3Sbluhm fail("Unexpected element name in attribute declaration"); 1557bd8f1dc3Sbluhm if (xcstrcmp(attr_name, at->attr_name)) 1558bd8f1dc3Sbluhm fail("Unexpected attribute name in attribute declaration"); 1559bd8f1dc3Sbluhm if (xcstrcmp(attr_type, at->attr_type)) 1560bd8f1dc3Sbluhm fail("Unexpected attribute type in attribute declaration"); 1561bd8f1dc3Sbluhm if ((default_value == NULL && at->default_value != NULL) 1562bd8f1dc3Sbluhm || (default_value != NULL && at->default_value == NULL) 1563bd8f1dc3Sbluhm || (default_value != NULL && xcstrcmp(default_value, at->default_value))) 1564bd8f1dc3Sbluhm fail("Unexpected default value in attribute declaration"); 1565bd8f1dc3Sbluhm if (is_required != at->is_required) 1566bd8f1dc3Sbluhm fail("Requirement mismatch in attribute declaration"); 1567bd8f1dc3Sbluhm } 1568bd8f1dc3Sbluhm 1569bd8f1dc3Sbluhm /* Character Data handlers */ 1570bd8f1dc3Sbluhm 1571bd8f1dc3Sbluhm void XMLCALL 1572bd8f1dc3Sbluhm clearing_aborting_character_handler(void *userData, const XML_Char *s, 1573bd8f1dc3Sbluhm int len) { 1574bd8f1dc3Sbluhm UNUSED_P(userData); 1575bd8f1dc3Sbluhm UNUSED_P(s); 1576bd8f1dc3Sbluhm UNUSED_P(len); 1577bd8f1dc3Sbluhm XML_StopParser(g_parser, g_resumable); 1578bd8f1dc3Sbluhm XML_SetCharacterDataHandler(g_parser, NULL); 1579bd8f1dc3Sbluhm } 1580bd8f1dc3Sbluhm 1581bd8f1dc3Sbluhm void XMLCALL 1582bd8f1dc3Sbluhm parser_stop_character_handler(void *userData, const XML_Char *s, int len) { 1583bd8f1dc3Sbluhm UNUSED_P(userData); 1584bd8f1dc3Sbluhm UNUSED_P(s); 1585bd8f1dc3Sbluhm UNUSED_P(len); 1586bd8f1dc3Sbluhm XML_ParsingStatus status; 1587bd8f1dc3Sbluhm XML_GetParsingStatus(g_parser, &status); 1588bd8f1dc3Sbluhm if (status.parsing == XML_FINISHED) { 1589bd8f1dc3Sbluhm return; // the parser was stopped by a previous call to this handler. 1590bd8f1dc3Sbluhm } 1591bd8f1dc3Sbluhm XML_StopParser(g_parser, g_resumable); 1592bd8f1dc3Sbluhm XML_SetCharacterDataHandler(g_parser, NULL); 1593bd8f1dc3Sbluhm if (! g_resumable) { 1594bd8f1dc3Sbluhm /* Check that aborting an aborted parser is faulted */ 1595bd8f1dc3Sbluhm if (XML_StopParser(g_parser, XML_FALSE) != XML_STATUS_ERROR) 1596bd8f1dc3Sbluhm fail("Aborting aborted parser not faulted"); 1597bd8f1dc3Sbluhm if (XML_GetErrorCode(g_parser) != XML_ERROR_FINISHED) 1598bd8f1dc3Sbluhm xml_failure(g_parser); 1599bd8f1dc3Sbluhm } else if (g_abortable) { 1600bd8f1dc3Sbluhm /* Check that aborting a suspended parser works */ 1601bd8f1dc3Sbluhm if (XML_StopParser(g_parser, XML_FALSE) == XML_STATUS_ERROR) 1602bd8f1dc3Sbluhm xml_failure(g_parser); 1603bd8f1dc3Sbluhm } else { 1604bd8f1dc3Sbluhm /* Check that suspending a suspended parser works */ 1605bd8f1dc3Sbluhm if (XML_StopParser(g_parser, XML_TRUE) != XML_STATUS_ERROR) 1606bd8f1dc3Sbluhm fail("Suspending suspended parser not faulted"); 1607bd8f1dc3Sbluhm if (XML_GetErrorCode(g_parser) != XML_ERROR_SUSPENDED) 1608bd8f1dc3Sbluhm xml_failure(g_parser); 1609bd8f1dc3Sbluhm } 1610bd8f1dc3Sbluhm } 1611bd8f1dc3Sbluhm 1612bd8f1dc3Sbluhm void XMLCALL 1613bd8f1dc3Sbluhm cr_cdata_handler(void *userData, const XML_Char *s, int len) { 1614bd8f1dc3Sbluhm int *pfound = (int *)userData; 1615bd8f1dc3Sbluhm 1616bd8f1dc3Sbluhm /* Internal processing turns the CR into a newline for the 1617bd8f1dc3Sbluhm * character data handler, but not for the default handler 1618bd8f1dc3Sbluhm */ 1619bd8f1dc3Sbluhm if (len == 1 && (*s == XCS('\n') || *s == XCS('\r'))) 1620bd8f1dc3Sbluhm *pfound = 1; 1621bd8f1dc3Sbluhm } 1622bd8f1dc3Sbluhm 1623bd8f1dc3Sbluhm void XMLCALL 1624bd8f1dc3Sbluhm rsqb_handler(void *userData, const XML_Char *s, int len) { 1625bd8f1dc3Sbluhm int *pfound = (int *)userData; 1626bd8f1dc3Sbluhm 1627bd8f1dc3Sbluhm if (len == 1 && *s == XCS(']')) 1628bd8f1dc3Sbluhm *pfound = 1; 1629bd8f1dc3Sbluhm } 1630bd8f1dc3Sbluhm 1631bd8f1dc3Sbluhm void XMLCALL 1632bd8f1dc3Sbluhm byte_character_handler(void *userData, const XML_Char *s, int len) { 1633bd8f1dc3Sbluhm #if XML_CONTEXT_BYTES > 0 1634bd8f1dc3Sbluhm int offset, size; 1635bd8f1dc3Sbluhm const char *buffer; 1636bd8f1dc3Sbluhm ByteTestData *data = (ByteTestData *)userData; 1637bd8f1dc3Sbluhm 1638bd8f1dc3Sbluhm UNUSED_P(s); 1639bd8f1dc3Sbluhm buffer = XML_GetInputContext(g_parser, &offset, &size); 1640bd8f1dc3Sbluhm if (buffer == NULL) 1641bd8f1dc3Sbluhm fail("Failed to get context buffer"); 1642bd8f1dc3Sbluhm if (offset != data->start_element_len) 1643bd8f1dc3Sbluhm fail("Context offset in unexpected position"); 1644bd8f1dc3Sbluhm if (len != data->cdata_len) 1645bd8f1dc3Sbluhm fail("CDATA length reported incorrectly"); 1646bd8f1dc3Sbluhm if (size != data->total_string_len) 1647bd8f1dc3Sbluhm fail("Context size is not full buffer"); 1648bd8f1dc3Sbluhm if (XML_GetCurrentByteIndex(g_parser) != offset) 1649bd8f1dc3Sbluhm fail("Character byte index incorrect"); 1650bd8f1dc3Sbluhm if (XML_GetCurrentByteCount(g_parser) != len) 1651bd8f1dc3Sbluhm fail("Character byte count incorrect"); 1652bd8f1dc3Sbluhm #else 1653bd8f1dc3Sbluhm UNUSED_P(s); 1654bd8f1dc3Sbluhm UNUSED_P(userData); 1655bd8f1dc3Sbluhm UNUSED_P(len); 1656bd8f1dc3Sbluhm #endif 1657bd8f1dc3Sbluhm } 1658bd8f1dc3Sbluhm 1659bd8f1dc3Sbluhm void XMLCALL 1660bd8f1dc3Sbluhm ext2_accumulate_characters(void *userData, const XML_Char *s, int len) { 1661bd8f1dc3Sbluhm ExtTest2 *test_data = (ExtTest2 *)userData; 1662bd8f1dc3Sbluhm accumulate_characters(test_data->storage, s, len); 1663bd8f1dc3Sbluhm } 1664bd8f1dc3Sbluhm 1665bd8f1dc3Sbluhm /* Handlers that record their function name and int arg. */ 1666bd8f1dc3Sbluhm 1667bd8f1dc3Sbluhm static void 1668bd8f1dc3Sbluhm record_call(struct handler_record_list *const rec, const char *funcname, 1669bd8f1dc3Sbluhm const int arg) { 1670bd8f1dc3Sbluhm const int max_entries = sizeof(rec->entries) / sizeof(rec->entries[0]); 1671bd8f1dc3Sbluhm assert_true(rec->count < max_entries); 1672bd8f1dc3Sbluhm struct handler_record_entry *const e = &rec->entries[rec->count++]; 1673bd8f1dc3Sbluhm e->name = funcname; 1674bd8f1dc3Sbluhm e->arg = arg; 1675bd8f1dc3Sbluhm } 1676bd8f1dc3Sbluhm 1677bd8f1dc3Sbluhm void XMLCALL 1678bd8f1dc3Sbluhm record_default_handler(void *userData, const XML_Char *s, int len) { 1679bd8f1dc3Sbluhm UNUSED_P(s); 1680bd8f1dc3Sbluhm record_call((struct handler_record_list *)userData, __func__, len); 1681bd8f1dc3Sbluhm } 1682bd8f1dc3Sbluhm 1683bd8f1dc3Sbluhm void XMLCALL 1684bd8f1dc3Sbluhm record_cdata_handler(void *userData, const XML_Char *s, int len) { 1685bd8f1dc3Sbluhm UNUSED_P(s); 1686bd8f1dc3Sbluhm record_call((struct handler_record_list *)userData, __func__, len); 1687bd8f1dc3Sbluhm XML_DefaultCurrent(g_parser); 1688bd8f1dc3Sbluhm } 1689bd8f1dc3Sbluhm 1690bd8f1dc3Sbluhm void XMLCALL 1691bd8f1dc3Sbluhm record_cdata_nodefault_handler(void *userData, const XML_Char *s, int len) { 1692bd8f1dc3Sbluhm UNUSED_P(s); 1693bd8f1dc3Sbluhm record_call((struct handler_record_list *)userData, __func__, len); 1694bd8f1dc3Sbluhm } 1695bd8f1dc3Sbluhm 1696bd8f1dc3Sbluhm void XMLCALL 1697bd8f1dc3Sbluhm record_skip_handler(void *userData, const XML_Char *entityName, 1698bd8f1dc3Sbluhm int is_parameter_entity) { 1699bd8f1dc3Sbluhm UNUSED_P(entityName); 1700bd8f1dc3Sbluhm record_call((struct handler_record_list *)userData, __func__, 1701bd8f1dc3Sbluhm is_parameter_entity); 1702bd8f1dc3Sbluhm } 1703bd8f1dc3Sbluhm 1704bd8f1dc3Sbluhm void XMLCALL 1705bd8f1dc3Sbluhm record_element_start_handler(void *userData, const XML_Char *name, 1706bd8f1dc3Sbluhm const XML_Char **atts) { 1707bd8f1dc3Sbluhm UNUSED_P(atts); 1708bd8f1dc3Sbluhm CharData_AppendXMLChars((CharData *)userData, name, (int)xcstrlen(name)); 1709bd8f1dc3Sbluhm } 1710bd8f1dc3Sbluhm 1711bd8f1dc3Sbluhm void XMLCALL 1712bd8f1dc3Sbluhm record_element_end_handler(void *userData, const XML_Char *name) { 1713bd8f1dc3Sbluhm CharData *storage = (CharData *)userData; 1714bd8f1dc3Sbluhm 1715bd8f1dc3Sbluhm CharData_AppendXMLChars(storage, XCS("/"), 1); 1716bd8f1dc3Sbluhm CharData_AppendXMLChars(storage, name, -1); 1717bd8f1dc3Sbluhm } 1718bd8f1dc3Sbluhm 1719bd8f1dc3Sbluhm const struct handler_record_entry * 1720bd8f1dc3Sbluhm _handler_record_get(const struct handler_record_list *storage, int index, 1721bd8f1dc3Sbluhm const char *file, int line) { 1722bd8f1dc3Sbluhm if (storage->count <= index) { 1723bd8f1dc3Sbluhm _fail(file, line, "too few handler calls"); 1724bd8f1dc3Sbluhm } 1725bd8f1dc3Sbluhm return &storage->entries[index]; 1726bd8f1dc3Sbluhm } 1727bd8f1dc3Sbluhm 1728bd8f1dc3Sbluhm /* Entity Declaration Handlers */ 1729bd8f1dc3Sbluhm static const XML_Char *entity_name_to_match = NULL; 1730bd8f1dc3Sbluhm static const XML_Char *entity_value_to_match = NULL; 1731bd8f1dc3Sbluhm static int entity_match_flag = ENTITY_MATCH_NOT_FOUND; 1732bd8f1dc3Sbluhm 1733bd8f1dc3Sbluhm void XMLCALL 1734bd8f1dc3Sbluhm param_entity_match_handler(void *userData, const XML_Char *entityName, 1735bd8f1dc3Sbluhm int is_parameter_entity, const XML_Char *value, 1736bd8f1dc3Sbluhm int value_length, const XML_Char *base, 1737bd8f1dc3Sbluhm const XML_Char *systemId, const XML_Char *publicId, 1738bd8f1dc3Sbluhm const XML_Char *notationName) { 1739bd8f1dc3Sbluhm UNUSED_P(userData); 1740bd8f1dc3Sbluhm UNUSED_P(base); 1741bd8f1dc3Sbluhm UNUSED_P(systemId); 1742bd8f1dc3Sbluhm UNUSED_P(publicId); 1743bd8f1dc3Sbluhm UNUSED_P(notationName); 1744bd8f1dc3Sbluhm if (! is_parameter_entity || entity_name_to_match == NULL 1745bd8f1dc3Sbluhm || entity_value_to_match == NULL) { 1746bd8f1dc3Sbluhm return; 1747bd8f1dc3Sbluhm } 1748bd8f1dc3Sbluhm if (! xcstrcmp(entityName, entity_name_to_match)) { 1749bd8f1dc3Sbluhm /* The cast here is safe because we control the horizontal and 1750bd8f1dc3Sbluhm * the vertical, and we therefore know our strings are never 1751bd8f1dc3Sbluhm * going to overflow an int. 1752bd8f1dc3Sbluhm */ 1753bd8f1dc3Sbluhm if (value_length != (int)xcstrlen(entity_value_to_match) 1754bd8f1dc3Sbluhm || xcstrncmp(value, entity_value_to_match, value_length)) { 1755bd8f1dc3Sbluhm entity_match_flag = ENTITY_MATCH_FAIL; 1756bd8f1dc3Sbluhm } else { 1757bd8f1dc3Sbluhm entity_match_flag = ENTITY_MATCH_SUCCESS; 1758bd8f1dc3Sbluhm } 1759bd8f1dc3Sbluhm } 1760bd8f1dc3Sbluhm /* Else leave the match flag alone */ 1761bd8f1dc3Sbluhm } 1762bd8f1dc3Sbluhm 1763bd8f1dc3Sbluhm void 1764bd8f1dc3Sbluhm param_entity_match_init(const XML_Char *name, const XML_Char *value) { 1765bd8f1dc3Sbluhm entity_name_to_match = name; 1766bd8f1dc3Sbluhm entity_value_to_match = value; 1767bd8f1dc3Sbluhm entity_match_flag = ENTITY_MATCH_NOT_FOUND; 1768bd8f1dc3Sbluhm } 1769bd8f1dc3Sbluhm 1770bd8f1dc3Sbluhm int 1771bd8f1dc3Sbluhm get_param_entity_match_flag(void) { 1772bd8f1dc3Sbluhm return entity_match_flag; 1773bd8f1dc3Sbluhm } 1774bd8f1dc3Sbluhm 1775bd8f1dc3Sbluhm /* Misc handlers */ 1776bd8f1dc3Sbluhm 1777bd8f1dc3Sbluhm void XMLCALL 1778bd8f1dc3Sbluhm xml_decl_handler(void *userData, const XML_Char *version, 1779bd8f1dc3Sbluhm const XML_Char *encoding, int standalone) { 1780bd8f1dc3Sbluhm UNUSED_P(version); 1781bd8f1dc3Sbluhm UNUSED_P(encoding); 1782bd8f1dc3Sbluhm if (userData != g_handler_data) 1783bd8f1dc3Sbluhm fail("User data (xml decl) not correctly set"); 1784bd8f1dc3Sbluhm if (standalone != -1) 1785bd8f1dc3Sbluhm fail("Standalone not flagged as not present in XML decl"); 1786bd8f1dc3Sbluhm g_xdecl_count++; 1787bd8f1dc3Sbluhm } 1788bd8f1dc3Sbluhm 1789bd8f1dc3Sbluhm void XMLCALL 1790bd8f1dc3Sbluhm param_check_skip_handler(void *userData, const XML_Char *entityName, 1791bd8f1dc3Sbluhm int is_parameter_entity) { 1792bd8f1dc3Sbluhm UNUSED_P(entityName); 1793bd8f1dc3Sbluhm UNUSED_P(is_parameter_entity); 1794bd8f1dc3Sbluhm if (userData != g_handler_data) 1795bd8f1dc3Sbluhm fail("User data (skip) not correctly set"); 1796bd8f1dc3Sbluhm g_skip_count++; 1797bd8f1dc3Sbluhm } 1798bd8f1dc3Sbluhm 1799bd8f1dc3Sbluhm void XMLCALL 1800bd8f1dc3Sbluhm data_check_comment_handler(void *userData, const XML_Char *data) { 1801bd8f1dc3Sbluhm UNUSED_P(data); 1802bd8f1dc3Sbluhm /* Check that the userData passed through is what we expect */ 1803bd8f1dc3Sbluhm if (userData != g_handler_data) 1804bd8f1dc3Sbluhm fail("User data (parser) not correctly set"); 1805bd8f1dc3Sbluhm /* Check that the user data in the parser is appropriate */ 1806bd8f1dc3Sbluhm if (XML_GetUserData(userData) != (void *)1) 1807bd8f1dc3Sbluhm fail("User data in parser not correctly set"); 1808bd8f1dc3Sbluhm g_comment_count++; 1809bd8f1dc3Sbluhm } 1810bd8f1dc3Sbluhm 1811bd8f1dc3Sbluhm void XMLCALL 1812bd8f1dc3Sbluhm selective_aborting_default_handler(void *userData, const XML_Char *s, int len) { 1813bd8f1dc3Sbluhm const XML_Char trigger_char = *(const XML_Char *)userData; 1814bd8f1dc3Sbluhm 1815bd8f1dc3Sbluhm int found = 0; 1816bd8f1dc3Sbluhm for (int i = 0; i < len; ++i) { 1817bd8f1dc3Sbluhm if (s[i] == trigger_char) { 1818bd8f1dc3Sbluhm found = 1; 1819bd8f1dc3Sbluhm break; 1820bd8f1dc3Sbluhm } 1821bd8f1dc3Sbluhm } 1822bd8f1dc3Sbluhm 1823bd8f1dc3Sbluhm if (found) { 1824bd8f1dc3Sbluhm XML_StopParser(g_parser, g_resumable); 1825bd8f1dc3Sbluhm XML_SetDefaultHandler(g_parser, NULL); 1826bd8f1dc3Sbluhm } 1827bd8f1dc3Sbluhm } 1828bd8f1dc3Sbluhm 1829bd8f1dc3Sbluhm void XMLCALL 1830bd8f1dc3Sbluhm suspending_comment_handler(void *userData, const XML_Char *data) { 1831bd8f1dc3Sbluhm UNUSED_P(data); 1832bd8f1dc3Sbluhm XML_Parser parser = (XML_Parser)userData; 1833bd8f1dc3Sbluhm XML_StopParser(parser, XML_TRUE); 1834bd8f1dc3Sbluhm } 1835bd8f1dc3Sbluhm 1836bd8f1dc3Sbluhm void XMLCALL 1837bd8f1dc3Sbluhm element_decl_suspender(void *userData, const XML_Char *name, 1838bd8f1dc3Sbluhm XML_Content *model) { 1839bd8f1dc3Sbluhm UNUSED_P(userData); 1840bd8f1dc3Sbluhm UNUSED_P(name); 1841bd8f1dc3Sbluhm XML_StopParser(g_parser, XML_TRUE); 1842bd8f1dc3Sbluhm XML_FreeContentModel(g_parser, model); 1843bd8f1dc3Sbluhm } 1844bd8f1dc3Sbluhm 1845bd8f1dc3Sbluhm void XMLCALL 1846bd8f1dc3Sbluhm accumulate_pi_characters(void *userData, const XML_Char *target, 1847bd8f1dc3Sbluhm const XML_Char *data) { 1848bd8f1dc3Sbluhm CharData *storage = (CharData *)userData; 1849bd8f1dc3Sbluhm 1850bd8f1dc3Sbluhm CharData_AppendXMLChars(storage, target, -1); 1851bd8f1dc3Sbluhm CharData_AppendXMLChars(storage, XCS(": "), 2); 1852bd8f1dc3Sbluhm CharData_AppendXMLChars(storage, data, -1); 1853bd8f1dc3Sbluhm CharData_AppendXMLChars(storage, XCS("\n"), 1); 1854bd8f1dc3Sbluhm } 1855bd8f1dc3Sbluhm 1856bd8f1dc3Sbluhm void XMLCALL 1857bd8f1dc3Sbluhm accumulate_comment(void *userData, const XML_Char *data) { 1858bd8f1dc3Sbluhm CharData *storage = (CharData *)userData; 1859bd8f1dc3Sbluhm 1860bd8f1dc3Sbluhm CharData_AppendXMLChars(storage, data, -1); 1861bd8f1dc3Sbluhm } 1862bd8f1dc3Sbluhm 1863bd8f1dc3Sbluhm void XMLCALL 1864bd8f1dc3Sbluhm accumulate_entity_decl(void *userData, const XML_Char *entityName, 1865bd8f1dc3Sbluhm int is_parameter_entity, const XML_Char *value, 1866bd8f1dc3Sbluhm int value_length, const XML_Char *base, 1867bd8f1dc3Sbluhm const XML_Char *systemId, const XML_Char *publicId, 1868bd8f1dc3Sbluhm const XML_Char *notationName) { 1869bd8f1dc3Sbluhm CharData *storage = (CharData *)userData; 1870bd8f1dc3Sbluhm 1871bd8f1dc3Sbluhm UNUSED_P(is_parameter_entity); 1872bd8f1dc3Sbluhm UNUSED_P(base); 1873bd8f1dc3Sbluhm UNUSED_P(systemId); 1874bd8f1dc3Sbluhm UNUSED_P(publicId); 1875bd8f1dc3Sbluhm UNUSED_P(notationName); 1876bd8f1dc3Sbluhm CharData_AppendXMLChars(storage, entityName, -1); 1877bd8f1dc3Sbluhm CharData_AppendXMLChars(storage, XCS("="), 1); 1878bd8f1dc3Sbluhm if (value == NULL) 1879bd8f1dc3Sbluhm CharData_AppendXMLChars(storage, XCS("(null)"), -1); 1880bd8f1dc3Sbluhm else 1881bd8f1dc3Sbluhm CharData_AppendXMLChars(storage, value, value_length); 1882bd8f1dc3Sbluhm CharData_AppendXMLChars(storage, XCS("\n"), 1); 1883bd8f1dc3Sbluhm } 1884bd8f1dc3Sbluhm 1885bd8f1dc3Sbluhm void XMLCALL 1886bd8f1dc3Sbluhm accumulate_start_element(void *userData, const XML_Char *name, 1887bd8f1dc3Sbluhm const XML_Char **atts) { 1888bd8f1dc3Sbluhm CharData *const storage = (CharData *)userData; 1889bd8f1dc3Sbluhm CharData_AppendXMLChars(storage, XCS("("), 1); 1890bd8f1dc3Sbluhm CharData_AppendXMLChars(storage, name, -1); 1891bd8f1dc3Sbluhm 1892bd8f1dc3Sbluhm if ((atts != NULL) && (atts[0] != NULL)) { 1893bd8f1dc3Sbluhm CharData_AppendXMLChars(storage, XCS("("), 1); 1894bd8f1dc3Sbluhm while (atts[0] != NULL) { 1895bd8f1dc3Sbluhm CharData_AppendXMLChars(storage, atts[0], -1); 1896bd8f1dc3Sbluhm CharData_AppendXMLChars(storage, XCS("="), 1); 1897bd8f1dc3Sbluhm CharData_AppendXMLChars(storage, atts[1], -1); 1898bd8f1dc3Sbluhm atts += 2; 1899bd8f1dc3Sbluhm if (atts[0] != NULL) { 1900bd8f1dc3Sbluhm CharData_AppendXMLChars(storage, XCS(","), 1); 1901bd8f1dc3Sbluhm } 1902bd8f1dc3Sbluhm } 1903bd8f1dc3Sbluhm CharData_AppendXMLChars(storage, XCS(")"), 1); 1904bd8f1dc3Sbluhm } 1905bd8f1dc3Sbluhm 1906bd8f1dc3Sbluhm CharData_AppendXMLChars(storage, XCS(")\n"), 2); 1907bd8f1dc3Sbluhm } 1908bd8f1dc3Sbluhm 1909bd8f1dc3Sbluhm void XMLCALL 1910*aa071e6eSbluhm accumulate_characters(void *userData, const XML_Char *s, int len) { 1911*aa071e6eSbluhm CharData *const storage = (CharData *)userData; 1912*aa071e6eSbluhm CharData_AppendXMLChars(storage, s, len); 1913*aa071e6eSbluhm } 1914*aa071e6eSbluhm 1915*aa071e6eSbluhm void XMLCALL 1916*aa071e6eSbluhm accumulate_attribute(void *userData, const XML_Char *name, 1917*aa071e6eSbluhm const XML_Char **atts) { 1918*aa071e6eSbluhm CharData *const storage = (CharData *)userData; 1919*aa071e6eSbluhm UNUSED_P(name); 1920*aa071e6eSbluhm /* Check there are attributes to deal with */ 1921*aa071e6eSbluhm if (atts == NULL) 1922*aa071e6eSbluhm return; 1923*aa071e6eSbluhm 1924*aa071e6eSbluhm while (storage->count < 0 && atts[0] != NULL) { 1925*aa071e6eSbluhm /* "accumulate" the value of the first attribute we see */ 1926*aa071e6eSbluhm CharData_AppendXMLChars(storage, atts[1], -1); 1927*aa071e6eSbluhm atts += 2; 1928*aa071e6eSbluhm } 1929*aa071e6eSbluhm } 1930*aa071e6eSbluhm 1931*aa071e6eSbluhm void XMLCALL 1932*aa071e6eSbluhm ext_accumulate_characters(void *userData, const XML_Char *s, int len) { 1933*aa071e6eSbluhm ExtTest *const test_data = (ExtTest *)userData; 1934*aa071e6eSbluhm accumulate_characters(test_data->storage, s, len); 1935*aa071e6eSbluhm } 1936*aa071e6eSbluhm 1937*aa071e6eSbluhm void XMLCALL 1938bd8f1dc3Sbluhm checking_default_handler(void *userData, const XML_Char *s, int len) { 1939bd8f1dc3Sbluhm DefaultCheck *data = (DefaultCheck *)userData; 1940bd8f1dc3Sbluhm int i; 1941bd8f1dc3Sbluhm 1942bd8f1dc3Sbluhm for (i = 0; data[i].expected != NULL; i++) { 1943bd8f1dc3Sbluhm if (data[i].expectedLen == len 1944bd8f1dc3Sbluhm && ! memcmp(data[i].expected, s, len * sizeof(XML_Char))) { 1945bd8f1dc3Sbluhm data[i].seen = XML_TRUE; 1946bd8f1dc3Sbluhm break; 1947bd8f1dc3Sbluhm } 1948bd8f1dc3Sbluhm } 1949bd8f1dc3Sbluhm } 1950bd8f1dc3Sbluhm 1951bd8f1dc3Sbluhm void XMLCALL 1952bd8f1dc3Sbluhm accumulate_and_suspend_comment_handler(void *userData, const XML_Char *data) { 1953bd8f1dc3Sbluhm ParserPlusStorage *const parserPlusStorage = (ParserPlusStorage *)userData; 1954bd8f1dc3Sbluhm accumulate_comment(parserPlusStorage->storage, data); 1955bd8f1dc3Sbluhm XML_StopParser(parserPlusStorage->parser, XML_TRUE); 1956bd8f1dc3Sbluhm } 1957