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