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