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-2024 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, XML_GetCurrentColumnNumber(g_parser), 93 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, XML_GetCurrentColumnNumber(g_parser), 100 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)) { 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)) { 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"))) 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 = 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)) 1556 fail("Unexpected element name in attribute declaration"); 1557 if (xcstrcmp(attr_name, at->attr_name)) 1558 fail("Unexpected attribute name in attribute declaration"); 1559 if (xcstrcmp(attr_type, at->attr_type)) 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 && xcstrcmp(default_value, at->default_value))) 1564 fail("Unexpected default value in attribute declaration"); 1565 if (is_required != at->is_required) 1566 fail("Requirement mismatch in attribute declaration"); 1567 } 1568 1569 /* Character Data handlers */ 1570 1571 void XMLCALL 1572 clearing_aborting_character_handler(void *userData, const XML_Char *s, 1573 int len) { 1574 UNUSED_P(userData); 1575 UNUSED_P(s); 1576 UNUSED_P(len); 1577 XML_StopParser(g_parser, g_resumable); 1578 XML_SetCharacterDataHandler(g_parser, NULL); 1579 } 1580 1581 void XMLCALL 1582 parser_stop_character_handler(void *userData, const XML_Char *s, int len) { 1583 UNUSED_P(userData); 1584 UNUSED_P(s); 1585 UNUSED_P(len); 1586 XML_ParsingStatus status; 1587 XML_GetParsingStatus(g_parser, &status); 1588 if (status.parsing == XML_FINISHED) { 1589 return; // the parser was stopped by a previous call to this handler. 1590 } 1591 XML_StopParser(g_parser, g_resumable); 1592 XML_SetCharacterDataHandler(g_parser, NULL); 1593 if (! g_resumable) { 1594 /* Check that aborting an aborted parser is faulted */ 1595 if (XML_StopParser(g_parser, XML_FALSE) != XML_STATUS_ERROR) 1596 fail("Aborting aborted parser not faulted"); 1597 if (XML_GetErrorCode(g_parser) != XML_ERROR_FINISHED) 1598 xml_failure(g_parser); 1599 } else if (g_abortable) { 1600 /* Check that aborting a suspended parser works */ 1601 if (XML_StopParser(g_parser, XML_FALSE) == XML_STATUS_ERROR) 1602 xml_failure(g_parser); 1603 } else { 1604 /* Check that suspending a suspended parser works */ 1605 if (XML_StopParser(g_parser, XML_TRUE) != XML_STATUS_ERROR) 1606 fail("Suspending suspended parser not faulted"); 1607 if (XML_GetErrorCode(g_parser) != XML_ERROR_SUSPENDED) 1608 xml_failure(g_parser); 1609 } 1610 } 1611 1612 void XMLCALL 1613 cr_cdata_handler(void *userData, const XML_Char *s, int len) { 1614 int *pfound = (int *)userData; 1615 1616 /* Internal processing turns the CR into a newline for the 1617 * character data handler, but not for the default handler 1618 */ 1619 if (len == 1 && (*s == XCS('\n') || *s == XCS('\r'))) 1620 *pfound = 1; 1621 } 1622 1623 void XMLCALL 1624 rsqb_handler(void *userData, const XML_Char *s, int len) { 1625 int *pfound = (int *)userData; 1626 1627 if (len == 1 && *s == XCS(']')) 1628 *pfound = 1; 1629 } 1630 1631 void XMLCALL 1632 byte_character_handler(void *userData, const XML_Char *s, int len) { 1633 #if XML_CONTEXT_BYTES > 0 1634 int offset, size; 1635 const char *buffer; 1636 ByteTestData *data = (ByteTestData *)userData; 1637 1638 UNUSED_P(s); 1639 buffer = XML_GetInputContext(g_parser, &offset, &size); 1640 if (buffer == NULL) 1641 fail("Failed to get context buffer"); 1642 if (offset != data->start_element_len) 1643 fail("Context offset in unexpected position"); 1644 if (len != data->cdata_len) 1645 fail("CDATA length reported incorrectly"); 1646 if (size != data->total_string_len) 1647 fail("Context size is not full buffer"); 1648 if (XML_GetCurrentByteIndex(g_parser) != offset) 1649 fail("Character byte index incorrect"); 1650 if (XML_GetCurrentByteCount(g_parser) != len) 1651 fail("Character byte count incorrect"); 1652 #else 1653 UNUSED_P(s); 1654 UNUSED_P(userData); 1655 UNUSED_P(len); 1656 #endif 1657 } 1658 1659 void XMLCALL 1660 ext2_accumulate_characters(void *userData, const XML_Char *s, int len) { 1661 ExtTest2 *test_data = (ExtTest2 *)userData; 1662 accumulate_characters(test_data->storage, s, len); 1663 } 1664 1665 /* Handlers that record their function name and int arg. */ 1666 1667 static void 1668 record_call(struct handler_record_list *const rec, const char *funcname, 1669 const int arg) { 1670 const int max_entries = sizeof(rec->entries) / sizeof(rec->entries[0]); 1671 assert_true(rec->count < max_entries); 1672 struct handler_record_entry *const e = &rec->entries[rec->count++]; 1673 e->name = funcname; 1674 e->arg = arg; 1675 } 1676 1677 void XMLCALL 1678 record_default_handler(void *userData, const XML_Char *s, int len) { 1679 UNUSED_P(s); 1680 record_call((struct handler_record_list *)userData, __func__, len); 1681 } 1682 1683 void XMLCALL 1684 record_cdata_handler(void *userData, const XML_Char *s, int len) { 1685 UNUSED_P(s); 1686 record_call((struct handler_record_list *)userData, __func__, len); 1687 XML_DefaultCurrent(g_parser); 1688 } 1689 1690 void XMLCALL 1691 record_cdata_nodefault_handler(void *userData, const XML_Char *s, int len) { 1692 UNUSED_P(s); 1693 record_call((struct handler_record_list *)userData, __func__, len); 1694 } 1695 1696 void XMLCALL 1697 record_skip_handler(void *userData, const XML_Char *entityName, 1698 int is_parameter_entity) { 1699 UNUSED_P(entityName); 1700 record_call((struct handler_record_list *)userData, __func__, 1701 is_parameter_entity); 1702 } 1703 1704 void XMLCALL 1705 record_element_start_handler(void *userData, const XML_Char *name, 1706 const XML_Char **atts) { 1707 UNUSED_P(atts); 1708 CharData_AppendXMLChars((CharData *)userData, name, (int)xcstrlen(name)); 1709 } 1710 1711 void XMLCALL 1712 record_element_end_handler(void *userData, const XML_Char *name) { 1713 CharData *storage = (CharData *)userData; 1714 1715 CharData_AppendXMLChars(storage, XCS("/"), 1); 1716 CharData_AppendXMLChars(storage, name, -1); 1717 } 1718 1719 const struct handler_record_entry * 1720 _handler_record_get(const struct handler_record_list *storage, int index, 1721 const char *file, int line) { 1722 if (storage->count <= index) { 1723 _fail(file, line, "too few handler calls"); 1724 } 1725 return &storage->entries[index]; 1726 } 1727 1728 /* Entity Declaration Handlers */ 1729 static const XML_Char *entity_name_to_match = NULL; 1730 static const XML_Char *entity_value_to_match = NULL; 1731 static int entity_match_flag = ENTITY_MATCH_NOT_FOUND; 1732 1733 void XMLCALL 1734 param_entity_match_handler(void *userData, const XML_Char *entityName, 1735 int is_parameter_entity, const XML_Char *value, 1736 int value_length, const XML_Char *base, 1737 const XML_Char *systemId, const XML_Char *publicId, 1738 const XML_Char *notationName) { 1739 UNUSED_P(userData); 1740 UNUSED_P(base); 1741 UNUSED_P(systemId); 1742 UNUSED_P(publicId); 1743 UNUSED_P(notationName); 1744 if (! is_parameter_entity || entity_name_to_match == NULL 1745 || entity_value_to_match == NULL) { 1746 return; 1747 } 1748 if (! xcstrcmp(entityName, entity_name_to_match)) { 1749 /* The cast here is safe because we control the horizontal and 1750 * the vertical, and we therefore know our strings are never 1751 * going to overflow an int. 1752 */ 1753 if (value_length != (int)xcstrlen(entity_value_to_match) 1754 || xcstrncmp(value, entity_value_to_match, value_length)) { 1755 entity_match_flag = ENTITY_MATCH_FAIL; 1756 } else { 1757 entity_match_flag = ENTITY_MATCH_SUCCESS; 1758 } 1759 } 1760 /* Else leave the match flag alone */ 1761 } 1762 1763 void 1764 param_entity_match_init(const XML_Char *name, const XML_Char *value) { 1765 entity_name_to_match = name; 1766 entity_value_to_match = value; 1767 entity_match_flag = ENTITY_MATCH_NOT_FOUND; 1768 } 1769 1770 int 1771 get_param_entity_match_flag(void) { 1772 return entity_match_flag; 1773 } 1774 1775 /* Misc handlers */ 1776 1777 void XMLCALL 1778 xml_decl_handler(void *userData, const XML_Char *version, 1779 const XML_Char *encoding, int standalone) { 1780 UNUSED_P(version); 1781 UNUSED_P(encoding); 1782 if (userData != g_handler_data) 1783 fail("User data (xml decl) not correctly set"); 1784 if (standalone != -1) 1785 fail("Standalone not flagged as not present in XML decl"); 1786 g_xdecl_count++; 1787 } 1788 1789 void XMLCALL 1790 param_check_skip_handler(void *userData, const XML_Char *entityName, 1791 int is_parameter_entity) { 1792 UNUSED_P(entityName); 1793 UNUSED_P(is_parameter_entity); 1794 if (userData != g_handler_data) 1795 fail("User data (skip) not correctly set"); 1796 g_skip_count++; 1797 } 1798 1799 void XMLCALL 1800 data_check_comment_handler(void *userData, const XML_Char *data) { 1801 UNUSED_P(data); 1802 /* Check that the userData passed through is what we expect */ 1803 if (userData != g_handler_data) 1804 fail("User data (parser) not correctly set"); 1805 /* Check that the user data in the parser is appropriate */ 1806 if (XML_GetUserData(userData) != (void *)1) 1807 fail("User data in parser not correctly set"); 1808 g_comment_count++; 1809 } 1810 1811 void XMLCALL 1812 selective_aborting_default_handler(void *userData, const XML_Char *s, int len) { 1813 const XML_Char trigger_char = *(const XML_Char *)userData; 1814 1815 int found = 0; 1816 for (int i = 0; i < len; ++i) { 1817 if (s[i] == trigger_char) { 1818 found = 1; 1819 break; 1820 } 1821 } 1822 1823 if (found) { 1824 XML_StopParser(g_parser, g_resumable); 1825 XML_SetDefaultHandler(g_parser, NULL); 1826 } 1827 } 1828 1829 void XMLCALL 1830 suspending_comment_handler(void *userData, const XML_Char *data) { 1831 UNUSED_P(data); 1832 XML_Parser parser = (XML_Parser)userData; 1833 XML_StopParser(parser, XML_TRUE); 1834 } 1835 1836 void XMLCALL 1837 element_decl_suspender(void *userData, const XML_Char *name, 1838 XML_Content *model) { 1839 UNUSED_P(userData); 1840 UNUSED_P(name); 1841 XML_StopParser(g_parser, XML_TRUE); 1842 XML_FreeContentModel(g_parser, model); 1843 } 1844 1845 void XMLCALL 1846 accumulate_pi_characters(void *userData, const XML_Char *target, 1847 const XML_Char *data) { 1848 CharData *storage = (CharData *)userData; 1849 1850 CharData_AppendXMLChars(storage, target, -1); 1851 CharData_AppendXMLChars(storage, XCS(": "), 2); 1852 CharData_AppendXMLChars(storage, data, -1); 1853 CharData_AppendXMLChars(storage, XCS("\n"), 1); 1854 } 1855 1856 void XMLCALL 1857 accumulate_comment(void *userData, const XML_Char *data) { 1858 CharData *storage = (CharData *)userData; 1859 1860 CharData_AppendXMLChars(storage, data, -1); 1861 } 1862 1863 void XMLCALL 1864 accumulate_entity_decl(void *userData, const XML_Char *entityName, 1865 int is_parameter_entity, const XML_Char *value, 1866 int value_length, const XML_Char *base, 1867 const XML_Char *systemId, const XML_Char *publicId, 1868 const XML_Char *notationName) { 1869 CharData *storage = (CharData *)userData; 1870 1871 UNUSED_P(is_parameter_entity); 1872 UNUSED_P(base); 1873 UNUSED_P(systemId); 1874 UNUSED_P(publicId); 1875 UNUSED_P(notationName); 1876 CharData_AppendXMLChars(storage, entityName, -1); 1877 CharData_AppendXMLChars(storage, XCS("="), 1); 1878 if (value == NULL) 1879 CharData_AppendXMLChars(storage, XCS("(null)"), -1); 1880 else 1881 CharData_AppendXMLChars(storage, value, value_length); 1882 CharData_AppendXMLChars(storage, XCS("\n"), 1); 1883 } 1884 1885 void XMLCALL 1886 accumulate_start_element(void *userData, const XML_Char *name, 1887 const XML_Char **atts) { 1888 CharData *const storage = (CharData *)userData; 1889 CharData_AppendXMLChars(storage, XCS("("), 1); 1890 CharData_AppendXMLChars(storage, name, -1); 1891 1892 if ((atts != NULL) && (atts[0] != NULL)) { 1893 CharData_AppendXMLChars(storage, XCS("("), 1); 1894 while (atts[0] != NULL) { 1895 CharData_AppendXMLChars(storage, atts[0], -1); 1896 CharData_AppendXMLChars(storage, XCS("="), 1); 1897 CharData_AppendXMLChars(storage, atts[1], -1); 1898 atts += 2; 1899 if (atts[0] != NULL) { 1900 CharData_AppendXMLChars(storage, XCS(","), 1); 1901 } 1902 } 1903 CharData_AppendXMLChars(storage, XCS(")"), 1); 1904 } 1905 1906 CharData_AppendXMLChars(storage, XCS(")\n"), 2); 1907 } 1908 1909 void XMLCALL 1910 accumulate_characters(void *userData, const XML_Char *s, int len) { 1911 CharData *const storage = (CharData *)userData; 1912 CharData_AppendXMLChars(storage, s, len); 1913 } 1914 1915 void XMLCALL 1916 accumulate_attribute(void *userData, const XML_Char *name, 1917 const XML_Char **atts) { 1918 CharData *const storage = (CharData *)userData; 1919 UNUSED_P(name); 1920 /* Check there are attributes to deal with */ 1921 if (atts == NULL) 1922 return; 1923 1924 while (storage->count < 0 && atts[0] != NULL) { 1925 /* "accumulate" the value of the first attribute we see */ 1926 CharData_AppendXMLChars(storage, atts[1], -1); 1927 atts += 2; 1928 } 1929 } 1930 1931 void XMLCALL 1932 ext_accumulate_characters(void *userData, const XML_Char *s, int len) { 1933 ExtTest *const test_data = (ExtTest *)userData; 1934 accumulate_characters(test_data->storage, s, len); 1935 } 1936 1937 void XMLCALL 1938 checking_default_handler(void *userData, const XML_Char *s, int len) { 1939 DefaultCheck *data = (DefaultCheck *)userData; 1940 int i; 1941 1942 for (i = 0; data[i].expected != NULL; i++) { 1943 if (data[i].expectedLen == len 1944 && ! memcmp(data[i].expected, s, len * sizeof(XML_Char))) { 1945 data[i].seen = XML_TRUE; 1946 break; 1947 } 1948 } 1949 } 1950 1951 void XMLCALL 1952 accumulate_and_suspend_comment_handler(void *userData, const XML_Char *data) { 1953 ParserPlusStorage *const parserPlusStorage = (ParserPlusStorage *)userData; 1954 accumulate_comment(parserPlusStorage->storage, data); 1955 XML_StopParser(parserPlusStorage->parser, XML_TRUE); 1956 } 1957