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