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