1 /* Run the Expat test suite 2 __ __ _ 3 ___\ \/ /_ __ __ _| |_ 4 / _ \\ /| '_ \ / _` | __| 5 | __// \| |_) | (_| | |_ 6 \___/_/\_\ .__/ \__,_|\__| 7 |_| XML parser 8 9 Copyright (c) 1997-2000 Thai Open Source Software Center Ltd 10 Copyright (c) 2000-2017 Expat development team 11 Licensed under the MIT license: 12 13 Permission is hereby granted, free of charge, to any person obtaining 14 a copy of this software and associated documentation files (the 15 "Software"), to deal in the Software without restriction, including 16 without limitation the rights to use, copy, modify, merge, publish, 17 distribute, sublicense, and/or sell copies of the Software, and to permit 18 persons to whom the Software is furnished to do so, subject to the 19 following conditions: 20 21 The above copyright notice and this permission notice shall be included 22 in all copies or substantial portions of the Software. 23 24 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 27 NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 28 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 29 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 30 USE OR OTHER DEALINGS IN THE SOFTWARE. 31 */ 32 33 #if defined(NDEBUG) 34 # undef NDEBUG /* because test suite relies on assert(...) at the moment */ 35 #endif 36 37 #ifdef HAVE_EXPAT_CONFIG_H 38 # include <expat_config.h> 39 #endif 40 41 #include <assert.h> 42 #include <stdlib.h> 43 #include <stdio.h> 44 #include <string.h> 45 #include <stddef.h> /* ptrdiff_t */ 46 #include <ctype.h> 47 #include <limits.h> 48 49 50 #if defined(_WIN32) && defined(_MSC_VER) && (_MSC_VER < 1600) 51 /* For vs2003/7.1 up to vs2008/9.0; _MSC_VER 1600 is vs2010/10.0 */ 52 #if defined(_WIN64) 53 typedef __int64 intptr_t; 54 #else 55 typedef __int32 intptr_t; 56 #endif 57 typedef unsigned __int64 uint64_t; 58 #else 59 #include <stdint.h> /* intptr_t uint64_t */ 60 #endif 61 62 63 #if ! defined(__cplusplus) 64 # if defined(_MSC_VER) && (_MSC_VER <= 1700) 65 /* for vs2012/11.0/1700 and earlier Visual Studio compilers */ 66 # define bool int 67 # define false 0 68 # define true 1 69 # else 70 # include <stdbool.h> 71 # endif 72 #endif 73 74 75 #include "expat.h" 76 #include "chardata.h" 77 #include "structdata.h" 78 #include "internal.h" /* for UNUSED_P only */ 79 #include "minicheck.h" 80 #include "memcheck.h" 81 #include "siphash.h" 82 #include "ascii.h" /* for ASCII_xxx */ 83 84 #ifdef XML_LARGE_SIZE 85 # define XML_FMT_INT_MOD "ll" 86 #else 87 # define XML_FMT_INT_MOD "l" 88 #endif 89 90 #ifdef XML_UNICODE_WCHAR_T 91 # define XML_FMT_CHAR "lc" 92 # define XML_FMT_STR "ls" 93 # include <wchar.h> 94 # define xcstrlen(s) wcslen(s) 95 # define xcstrcmp(s, t) wcscmp((s), (t)) 96 # define xcstrncmp(s, t, n) wcsncmp((s), (t), (n)) 97 # define XCS(s) _XCS(s) 98 # define _XCS(s) L ## s 99 #else 100 # ifdef XML_UNICODE 101 # error "No support for UTF-16 character without wchar_t in tests" 102 # else 103 # define XML_FMT_CHAR "c" 104 # define XML_FMT_STR "s" 105 # define xcstrlen(s) strlen(s) 106 # define xcstrcmp(s, t) strcmp((s), (t)) 107 # define xcstrncmp(s, t, n) strncmp((s), (t), (n)) 108 # define XCS(s) s 109 # endif /* XML_UNICODE */ 110 #endif /* XML_UNICODE_WCHAR_T */ 111 112 113 static XML_Parser parser = NULL; 114 115 116 static void 117 basic_setup(void) 118 { 119 parser = XML_ParserCreate(NULL); 120 if (parser == NULL) 121 fail("Parser not created."); 122 } 123 124 static void 125 basic_teardown(void) 126 { 127 if (parser != NULL) { 128 XML_ParserFree(parser); 129 parser = NULL; 130 } 131 } 132 133 /* Generate a failure using the parser state to create an error message; 134 this should be used when the parser reports an error we weren't 135 expecting. 136 */ 137 static void 138 _xml_failure(XML_Parser parser, const char *file, int line) 139 { 140 char buffer[1024]; 141 enum XML_Error err = XML_GetErrorCode(parser); 142 sprintf(buffer, 143 " %d: %" XML_FMT_STR " (line %" 144 XML_FMT_INT_MOD "u, offset %" 145 XML_FMT_INT_MOD "u)\n reported from %s, line %d\n", 146 err, 147 XML_ErrorString(err), 148 XML_GetCurrentLineNumber(parser), 149 XML_GetCurrentColumnNumber(parser), 150 file, line); 151 _fail_unless(0, file, line, buffer); 152 } 153 154 static enum XML_Status 155 _XML_Parse_SINGLE_BYTES(XML_Parser parser, const char *s, int len, int isFinal) 156 { 157 enum XML_Status res = XML_STATUS_ERROR; 158 int offset = 0; 159 160 if (len == 0) { 161 return XML_Parse(parser, s, len, isFinal); 162 } 163 164 for (; offset < len; offset++) { 165 const int innerIsFinal = (offset == len - 1) && isFinal; 166 const char c = s[offset]; /* to help out-of-bounds detection */ 167 res = XML_Parse(parser, &c, sizeof(char), innerIsFinal); 168 if (res != XML_STATUS_OK) { 169 return res; 170 } 171 } 172 return res; 173 } 174 175 #define xml_failure(parser) _xml_failure((parser), __FILE__, __LINE__) 176 177 static void 178 _expect_failure(const char *text, enum XML_Error errorCode, const char *errorMessage, 179 const char *file, int lineno) 180 { 181 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_OK) 182 /* Hackish use of _fail_unless() macro, but let's us report 183 the right filename and line number. */ 184 _fail_unless(0, file, lineno, errorMessage); 185 if (XML_GetErrorCode(parser) != errorCode) 186 _xml_failure(parser, file, lineno); 187 } 188 189 #define expect_failure(text, errorCode, errorMessage) \ 190 _expect_failure((text), (errorCode), (errorMessage), \ 191 __FILE__, __LINE__) 192 193 /* Dummy handlers for when we need to set a handler to tickle a bug, 194 but it doesn't need to do anything. 195 */ 196 static unsigned long dummy_handler_flags = 0; 197 198 #define DUMMY_START_DOCTYPE_HANDLER_FLAG (1UL << 0) 199 #define DUMMY_END_DOCTYPE_HANDLER_FLAG (1UL << 1) 200 #define DUMMY_ENTITY_DECL_HANDLER_FLAG (1UL << 2) 201 #define DUMMY_NOTATION_DECL_HANDLER_FLAG (1UL << 3) 202 #define DUMMY_ELEMENT_DECL_HANDLER_FLAG (1UL << 4) 203 #define DUMMY_ATTLIST_DECL_HANDLER_FLAG (1UL << 5) 204 #define DUMMY_COMMENT_HANDLER_FLAG (1UL << 6) 205 #define DUMMY_PI_HANDLER_FLAG (1UL << 7) 206 #define DUMMY_START_ELEMENT_HANDLER_FLAG (1UL << 8) 207 #define DUMMY_START_CDATA_HANDLER_FLAG (1UL << 9) 208 #define DUMMY_END_CDATA_HANDLER_FLAG (1UL << 10) 209 #define DUMMY_UNPARSED_ENTITY_DECL_HANDLER_FLAG (1UL << 11) 210 #define DUMMY_START_NS_DECL_HANDLER_FLAG (1UL << 12) 211 #define DUMMY_END_NS_DECL_HANDLER_FLAG (1UL << 13) 212 #define DUMMY_START_DOCTYPE_DECL_HANDLER_FLAG (1UL << 14) 213 #define DUMMY_END_DOCTYPE_DECL_HANDLER_FLAG (1UL << 15) 214 #define DUMMY_SKIP_HANDLER_FLAG (1UL << 16) 215 #define DUMMY_DEFAULT_HANDLER_FLAG (1UL << 17) 216 217 218 static void XMLCALL 219 dummy_xdecl_handler(void *UNUSED_P(userData), 220 const XML_Char *UNUSED_P(version), 221 const XML_Char *UNUSED_P(encoding), 222 int UNUSED_P(standalone)) 223 {} 224 225 static void XMLCALL 226 dummy_start_doctype_handler(void *UNUSED_P(userData), 227 const XML_Char *UNUSED_P(doctypeName), 228 const XML_Char *UNUSED_P(sysid), 229 const XML_Char *UNUSED_P(pubid), 230 int UNUSED_P(has_internal_subset)) 231 { 232 dummy_handler_flags |= DUMMY_START_DOCTYPE_HANDLER_FLAG; 233 } 234 235 static void XMLCALL 236 dummy_end_doctype_handler(void *UNUSED_P(userData)) 237 { 238 dummy_handler_flags |= DUMMY_END_DOCTYPE_HANDLER_FLAG; 239 } 240 241 static void XMLCALL 242 dummy_entity_decl_handler(void *UNUSED_P(userData), 243 const XML_Char *UNUSED_P(entityName), 244 int UNUSED_P(is_parameter_entity), 245 const XML_Char *UNUSED_P(value), 246 int UNUSED_P(value_length), 247 const XML_Char *UNUSED_P(base), 248 const XML_Char *UNUSED_P(systemId), 249 const XML_Char *UNUSED_P(publicId), 250 const XML_Char *UNUSED_P(notationName)) 251 { 252 dummy_handler_flags |= DUMMY_ENTITY_DECL_HANDLER_FLAG; 253 } 254 255 static void XMLCALL 256 dummy_notation_decl_handler(void *UNUSED_P(userData), 257 const XML_Char *UNUSED_P(notationName), 258 const XML_Char *UNUSED_P(base), 259 const XML_Char *UNUSED_P(systemId), 260 const XML_Char *UNUSED_P(publicId)) 261 { 262 dummy_handler_flags |= DUMMY_NOTATION_DECL_HANDLER_FLAG; 263 } 264 265 static void XMLCALL 266 dummy_element_decl_handler(void *UNUSED_P(userData), 267 const XML_Char *UNUSED_P(name), 268 XML_Content *model) 269 { 270 /* The content model must be freed by the handler. Unfortunately 271 * we cannot pass the parser as the userData because this is used 272 * with other handlers that require other userData. 273 */ 274 XML_FreeContentModel(parser, model); 275 dummy_handler_flags |= DUMMY_ELEMENT_DECL_HANDLER_FLAG; 276 } 277 278 static void XMLCALL 279 dummy_attlist_decl_handler(void *UNUSED_P(userData), 280 const XML_Char *UNUSED_P(elname), 281 const XML_Char *UNUSED_P(attname), 282 const XML_Char *UNUSED_P(att_type), 283 const XML_Char *UNUSED_P(dflt), 284 int UNUSED_P(isrequired)) 285 { 286 dummy_handler_flags |= DUMMY_ATTLIST_DECL_HANDLER_FLAG; 287 } 288 289 static void XMLCALL 290 dummy_comment_handler(void *UNUSED_P(userData), const XML_Char *UNUSED_P(data)) 291 { 292 dummy_handler_flags |= DUMMY_COMMENT_HANDLER_FLAG; 293 } 294 295 static void XMLCALL 296 dummy_pi_handler(void *UNUSED_P(userData), const XML_Char *UNUSED_P(target), const XML_Char *UNUSED_P(data)) 297 { 298 dummy_handler_flags |= DUMMY_PI_HANDLER_FLAG; 299 } 300 301 static void XMLCALL 302 dummy_start_element(void *UNUSED_P(userData), 303 const XML_Char *UNUSED_P(name), const XML_Char **UNUSED_P(atts)) 304 { 305 dummy_handler_flags |= DUMMY_START_ELEMENT_HANDLER_FLAG; 306 } 307 308 static void XMLCALL 309 dummy_end_element(void *UNUSED_P(userData), const XML_Char *UNUSED_P(name)) 310 {} 311 312 static void XMLCALL 313 dummy_start_cdata_handler(void *UNUSED_P(userData)) 314 { 315 dummy_handler_flags |= DUMMY_START_CDATA_HANDLER_FLAG; 316 } 317 318 static void XMLCALL 319 dummy_end_cdata_handler(void *UNUSED_P(userData)) 320 { 321 dummy_handler_flags |= DUMMY_END_CDATA_HANDLER_FLAG; 322 } 323 324 static void XMLCALL 325 dummy_cdata_handler(void *UNUSED_P(userData), 326 const XML_Char *UNUSED_P(s), 327 int UNUSED_P(len)) 328 {} 329 330 static void XMLCALL 331 dummy_start_namespace_decl_handler(void *UNUSED_P(userData), 332 const XML_Char *UNUSED_P(prefix), 333 const XML_Char *UNUSED_P(uri)) 334 { 335 dummy_handler_flags |= DUMMY_START_NS_DECL_HANDLER_FLAG; 336 } 337 338 static void XMLCALL 339 dummy_end_namespace_decl_handler(void *UNUSED_P(userData), 340 const XML_Char *UNUSED_P(prefix)) 341 { 342 dummy_handler_flags |= DUMMY_END_NS_DECL_HANDLER_FLAG; 343 } 344 345 /* This handler is obsolete, but while the code exists we should 346 * ensure that dealing with the handler is covered by tests. 347 */ 348 static void XMLCALL 349 dummy_unparsed_entity_decl_handler(void *UNUSED_P(userData), 350 const XML_Char *UNUSED_P(entityName), 351 const XML_Char *UNUSED_P(base), 352 const XML_Char *UNUSED_P(systemId), 353 const XML_Char *UNUSED_P(publicId), 354 const XML_Char *UNUSED_P(notationName)) 355 { 356 dummy_handler_flags |= DUMMY_UNPARSED_ENTITY_DECL_HANDLER_FLAG; 357 } 358 359 static void XMLCALL 360 dummy_default_handler(void *UNUSED_P(userData), 361 const XML_Char *UNUSED_P(s), 362 int UNUSED_P(len)) 363 {} 364 365 static void XMLCALL 366 dummy_start_doctype_decl_handler(void *UNUSED_P(userData), 367 const XML_Char *UNUSED_P(doctypeName), 368 const XML_Char *UNUSED_P(sysid), 369 const XML_Char *UNUSED_P(pubid), 370 int UNUSED_P(has_internal_subset)) 371 { 372 dummy_handler_flags |= DUMMY_START_DOCTYPE_DECL_HANDLER_FLAG; 373 } 374 375 static void XMLCALL 376 dummy_end_doctype_decl_handler(void *UNUSED_P(userData)) 377 { 378 dummy_handler_flags |= DUMMY_END_DOCTYPE_DECL_HANDLER_FLAG; 379 } 380 381 static void XMLCALL 382 dummy_skip_handler(void *UNUSED_P(userData), 383 const XML_Char *UNUSED_P(entityName), 384 int UNUSED_P(is_parameter_entity)) 385 { 386 dummy_handler_flags |= DUMMY_SKIP_HANDLER_FLAG; 387 } 388 389 /* Useful external entity handler */ 390 typedef struct ExtOption { 391 const XML_Char *system_id; 392 const char *parse_text; 393 } ExtOption; 394 395 static int XMLCALL 396 external_entity_optioner(XML_Parser parser, 397 const XML_Char *context, 398 const XML_Char *UNUSED_P(base), 399 const XML_Char *systemId, 400 const XML_Char *UNUSED_P(publicId)) 401 { 402 ExtOption *options = (ExtOption *)XML_GetUserData(parser); 403 XML_Parser ext_parser; 404 405 while (options->parse_text != NULL) { 406 if (!xcstrcmp(systemId, options->system_id)) { 407 enum XML_Status rc; 408 ext_parser = 409 XML_ExternalEntityParserCreate(parser, context, NULL); 410 if (ext_parser == NULL) 411 return XML_STATUS_ERROR; 412 rc = _XML_Parse_SINGLE_BYTES(ext_parser, options->parse_text, 413 (int)strlen(options->parse_text), 414 XML_TRUE); 415 XML_ParserFree(ext_parser); 416 return rc; 417 } 418 options++; 419 } 420 fail("No suitable option found"); 421 return XML_STATUS_ERROR; 422 } 423 424 /* 425 * Parameter entity evaluation support. 426 */ 427 #define ENTITY_MATCH_FAIL (-1) 428 #define ENTITY_MATCH_NOT_FOUND (0) 429 #define ENTITY_MATCH_SUCCESS (1) 430 static const XML_Char *entity_name_to_match = NULL; 431 static const XML_Char *entity_value_to_match = NULL; 432 static int entity_match_flag = ENTITY_MATCH_NOT_FOUND; 433 434 static void XMLCALL 435 param_entity_match_handler(void *UNUSED_P(userData), 436 const XML_Char *entityName, 437 int is_parameter_entity, 438 const XML_Char *value, 439 int value_length, 440 const XML_Char *UNUSED_P(base), 441 const XML_Char *UNUSED_P(systemId), 442 const XML_Char *UNUSED_P(publicId), 443 const XML_Char *UNUSED_P(notationName)) 444 { 445 if (!is_parameter_entity || 446 entity_name_to_match == NULL || 447 entity_value_to_match == NULL) { 448 return; 449 } 450 if (!xcstrcmp(entityName, entity_name_to_match)) { 451 /* The cast here is safe because we control the horizontal and 452 * the vertical, and we therefore know our strings are never 453 * going to overflow an int. 454 */ 455 if (value_length != (int)xcstrlen(entity_value_to_match) || 456 xcstrncmp(value, entity_value_to_match, value_length)) { 457 entity_match_flag = ENTITY_MATCH_FAIL; 458 } else { 459 entity_match_flag = ENTITY_MATCH_SUCCESS; 460 } 461 } 462 /* Else leave the match flag alone */ 463 } 464 465 /* 466 * Character & encoding tests. 467 */ 468 469 START_TEST(test_nul_byte) 470 { 471 char text[] = "<doc>\0</doc>"; 472 473 /* test that a NUL byte (in US-ASCII data) is an error */ 474 if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text) - 1, XML_TRUE) == XML_STATUS_OK) 475 fail("Parser did not report error on NUL-byte."); 476 if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_TOKEN) 477 xml_failure(parser); 478 } 479 END_TEST 480 481 482 START_TEST(test_u0000_char) 483 { 484 /* test that a NUL byte (in US-ASCII data) is an error */ 485 expect_failure("<doc>�</doc>", 486 XML_ERROR_BAD_CHAR_REF, 487 "Parser did not report error on NUL-byte."); 488 } 489 END_TEST 490 491 START_TEST(test_siphash_self) 492 { 493 if (! sip24_valid()) 494 fail("SipHash self-test failed"); 495 } 496 END_TEST 497 498 START_TEST(test_siphash_spec) 499 { 500 /* https://131002.net/siphash/siphash.pdf (page 19, "Test values") */ 501 const char message[] = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09" 502 "\x0a\x0b\x0c\x0d\x0e"; 503 const size_t len = sizeof(message) - 1; 504 const uint64_t expected = _SIP_ULL(0xa129ca61U, 0x49be45e5U); 505 struct siphash state; 506 struct sipkey key; 507 508 sip_tokey(&key, 509 "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09" 510 "\x0a\x0b\x0c\x0d\x0e\x0f"); 511 sip24_init(&state, &key); 512 513 /* Cover spread across calls */ 514 sip24_update(&state, message, 4); 515 sip24_update(&state, message + 4, len - 4); 516 517 /* Cover null length */ 518 sip24_update(&state, message, 0); 519 520 if (sip24_final(&state) != expected) 521 fail("sip24_final failed spec test\n"); 522 523 /* Cover wrapper */ 524 if (siphash24(message, len, &key) != expected) 525 fail("siphash24 failed spec test\n"); 526 } 527 END_TEST 528 529 START_TEST(test_bom_utf8) 530 { 531 /* This test is really just making sure we don't core on a UTF-8 BOM. */ 532 const char *text = "\357\273\277<e/>"; 533 534 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR) 535 xml_failure(parser); 536 } 537 END_TEST 538 539 START_TEST(test_bom_utf16_be) 540 { 541 char text[] = "\376\377\0<\0e\0/\0>"; 542 543 if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text)-1, XML_TRUE) == XML_STATUS_ERROR) 544 xml_failure(parser); 545 } 546 END_TEST 547 548 START_TEST(test_bom_utf16_le) 549 { 550 char text[] = "\377\376<\0e\0/\0>\0"; 551 552 if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text)-1, XML_TRUE) == XML_STATUS_ERROR) 553 xml_failure(parser); 554 } 555 END_TEST 556 557 /* Parse whole buffer at once to exercise a different code path */ 558 START_TEST(test_nobom_utf16_le) 559 { 560 char text[] = " \0<\0e\0/\0>\0"; 561 562 if (XML_Parse(parser, text, sizeof(text)-1, XML_TRUE) == XML_STATUS_ERROR) 563 xml_failure(parser); 564 } 565 END_TEST 566 567 static void XMLCALL 568 accumulate_characters(void *userData, const XML_Char *s, int len) 569 { 570 CharData_AppendXMLChars((CharData *)userData, s, len); 571 } 572 573 static void XMLCALL 574 accumulate_attribute(void *userData, const XML_Char *UNUSED_P(name), 575 const XML_Char **atts) 576 { 577 CharData *storage = (CharData *)userData; 578 579 /* Check there are attributes to deal with */ 580 if (atts == NULL) 581 return; 582 583 while (storage->count < 0 && atts[0] != NULL) { 584 /* "accumulate" the value of the first attribute we see */ 585 CharData_AppendXMLChars(storage, atts[1], -1); 586 atts += 2; 587 } 588 } 589 590 591 static void 592 _run_character_check(const char *text, const XML_Char *expected, 593 const char *file, int line) 594 { 595 CharData storage; 596 597 CharData_Init(&storage); 598 XML_SetUserData(parser, &storage); 599 XML_SetCharacterDataHandler(parser, accumulate_characters); 600 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR) 601 _xml_failure(parser, file, line); 602 CharData_CheckXMLChars(&storage, expected); 603 } 604 605 #define run_character_check(text, expected) \ 606 _run_character_check(text, expected, __FILE__, __LINE__) 607 608 static void 609 _run_attribute_check(const char *text, const XML_Char *expected, 610 const char *file, int line) 611 { 612 CharData storage; 613 614 CharData_Init(&storage); 615 XML_SetUserData(parser, &storage); 616 XML_SetStartElementHandler(parser, accumulate_attribute); 617 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR) 618 _xml_failure(parser, file, line); 619 CharData_CheckXMLChars(&storage, expected); 620 } 621 622 #define run_attribute_check(text, expected) \ 623 _run_attribute_check(text, expected, __FILE__, __LINE__) 624 625 typedef struct ExtTest { 626 const char *parse_text; 627 const XML_Char *encoding; 628 CharData *storage; 629 } ExtTest; 630 631 static void XMLCALL 632 ext_accumulate_characters(void *userData, const XML_Char *s, int len) 633 { 634 ExtTest *test_data = (ExtTest *)userData; 635 accumulate_characters(test_data->storage, s, len); 636 } 637 638 static void 639 _run_ext_character_check(const char *text, 640 ExtTest *test_data, 641 const XML_Char *expected, 642 const char *file, int line) 643 { 644 CharData storage; 645 646 CharData_Init(&storage); 647 test_data->storage = &storage; 648 XML_SetUserData(parser, test_data); 649 XML_SetCharacterDataHandler(parser, ext_accumulate_characters); 650 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 651 XML_TRUE) == XML_STATUS_ERROR) 652 _xml_failure(parser, file, line); 653 CharData_CheckXMLChars(&storage, expected); 654 } 655 656 #define run_ext_character_check(text, test_data, expected) \ 657 _run_ext_character_check(text, test_data, expected, __FILE__, __LINE__) 658 659 /* Regression test for SF bug #491986. */ 660 START_TEST(test_danish_latin1) 661 { 662 const char *text = 663 "<?xml version='1.0' encoding='iso-8859-1'?>\n" 664 "<e>J\xF8rgen \xE6\xF8\xE5\xC6\xD8\xC5</e>"; 665 #ifdef XML_UNICODE 666 const XML_Char *expected = 667 XCS("J\x00f8rgen \x00e6\x00f8\x00e5\x00c6\x00d8\x00c5"); 668 #else 669 const XML_Char *expected = 670 XCS("J\xC3\xB8rgen \xC3\xA6\xC3\xB8\xC3\xA5\xC3\x86\xC3\x98\xC3\x85"); 671 #endif 672 run_character_check(text, expected); 673 } 674 END_TEST 675 676 677 /* Regression test for SF bug #514281. */ 678 START_TEST(test_french_charref_hexidecimal) 679 { 680 const char *text = 681 "<?xml version='1.0' encoding='iso-8859-1'?>\n" 682 "<doc>éèàçêÈ</doc>"; 683 #ifdef XML_UNICODE 684 const XML_Char *expected = 685 XCS("\x00e9\x00e8\x00e0\x00e7\x00ea\x00c8"); 686 #else 687 const XML_Char *expected = 688 XCS("\xC3\xA9\xC3\xA8\xC3\xA0\xC3\xA7\xC3\xAA\xC3\x88"); 689 #endif 690 run_character_check(text, expected); 691 } 692 END_TEST 693 694 START_TEST(test_french_charref_decimal) 695 { 696 const char *text = 697 "<?xml version='1.0' encoding='iso-8859-1'?>\n" 698 "<doc>éèàçêÈ</doc>"; 699 #ifdef XML_UNICODE 700 const XML_Char *expected = 701 XCS("\x00e9\x00e8\x00e0\x00e7\x00ea\x00c8"); 702 #else 703 const XML_Char *expected = 704 XCS("\xC3\xA9\xC3\xA8\xC3\xA0\xC3\xA7\xC3\xAA\xC3\x88"); 705 #endif 706 run_character_check(text, expected); 707 } 708 END_TEST 709 710 START_TEST(test_french_latin1) 711 { 712 const char *text = 713 "<?xml version='1.0' encoding='iso-8859-1'?>\n" 714 "<doc>\xE9\xE8\xE0\xE7\xEa\xC8</doc>"; 715 #ifdef XML_UNICODE 716 const XML_Char *expected = 717 XCS("\x00e9\x00e8\x00e0\x00e7\x00ea\x00c8"); 718 #else 719 const XML_Char *expected = 720 XCS("\xC3\xA9\xC3\xA8\xC3\xA0\xC3\xA7\xC3\xAA\xC3\x88"); 721 #endif 722 run_character_check(text, expected); 723 } 724 END_TEST 725 726 START_TEST(test_french_utf8) 727 { 728 const char *text = 729 "<?xml version='1.0' encoding='utf-8'?>\n" 730 "<doc>\xC3\xA9</doc>"; 731 #ifdef XML_UNICODE 732 const XML_Char *expected = XCS("\x00e9"); 733 #else 734 const XML_Char *expected = XCS("\xC3\xA9"); 735 #endif 736 run_character_check(text, expected); 737 } 738 END_TEST 739 740 /* Regression test for SF bug #600479. 741 XXX There should be a test that exercises all legal XML Unicode 742 characters as PCDATA and attribute value content, and XML Name 743 characters as part of element and attribute names. 744 */ 745 START_TEST(test_utf8_false_rejection) 746 { 747 const char *text = "<doc>\xEF\xBA\xBF</doc>"; 748 #ifdef XML_UNICODE 749 const XML_Char *expected = XCS("\xfebf"); 750 #else 751 const XML_Char *expected = XCS("\xEF\xBA\xBF"); 752 #endif 753 run_character_check(text, expected); 754 } 755 END_TEST 756 757 /* Regression test for SF bug #477667. 758 This test assures that any 8-bit character followed by a 7-bit 759 character will not be mistakenly interpreted as a valid UTF-8 760 sequence. 761 */ 762 START_TEST(test_illegal_utf8) 763 { 764 char text[100]; 765 int i; 766 767 for (i = 128; i <= 255; ++i) { 768 sprintf(text, "<e>%ccd</e>", i); 769 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_OK) { 770 sprintf(text, 771 "expected token error for '%c' (ordinal %d) in UTF-8 text", 772 i, i); 773 fail(text); 774 } 775 else if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_TOKEN) 776 xml_failure(parser); 777 /* Reset the parser since we use the same parser repeatedly. */ 778 XML_ParserReset(parser, NULL); 779 } 780 } 781 END_TEST 782 783 784 /* Examples, not masks: */ 785 #define UTF8_LEAD_1 "\x7f" /* 0b01111111 */ 786 #define UTF8_LEAD_2 "\xdf" /* 0b11011111 */ 787 #define UTF8_LEAD_3 "\xef" /* 0b11101111 */ 788 #define UTF8_LEAD_4 "\xf7" /* 0b11110111 */ 789 #define UTF8_FOLLOW "\xbf" /* 0b10111111 */ 790 791 START_TEST(test_utf8_auto_align) 792 { 793 struct TestCase { 794 ptrdiff_t expectedMovementInChars; 795 const char * input; 796 }; 797 798 struct TestCase cases[] = { 799 {00, ""}, 800 801 {00, UTF8_LEAD_1}, 802 803 {-1, UTF8_LEAD_2}, 804 {00, UTF8_LEAD_2 UTF8_FOLLOW}, 805 806 {-1, UTF8_LEAD_3}, 807 {-2, UTF8_LEAD_3 UTF8_FOLLOW}, 808 {00, UTF8_LEAD_3 UTF8_FOLLOW UTF8_FOLLOW}, 809 810 {-1, UTF8_LEAD_4}, 811 {-2, UTF8_LEAD_4 UTF8_FOLLOW}, 812 {-3, UTF8_LEAD_4 UTF8_FOLLOW UTF8_FOLLOW}, 813 {00, UTF8_LEAD_4 UTF8_FOLLOW UTF8_FOLLOW UTF8_FOLLOW}, 814 }; 815 816 size_t i = 0; 817 bool success = true; 818 for (; i < sizeof(cases) / sizeof(*cases); i++) { 819 const char * fromLim = cases[i].input + strlen(cases[i].input); 820 const char * const fromLimInitially = fromLim; 821 ptrdiff_t actualMovementInChars; 822 823 _INTERNAL_trim_to_complete_utf8_characters(cases[i].input, &fromLim); 824 825 actualMovementInChars = (fromLim - fromLimInitially); 826 if (actualMovementInChars != cases[i].expectedMovementInChars) { 827 size_t j = 0; 828 success = false; 829 printf("[-] UTF-8 case %2u: Expected movement by %2d chars" 830 ", actually moved by %2d chars: \"", 831 (unsigned)(i + 1), 832 (int)cases[i].expectedMovementInChars, 833 (int)actualMovementInChars); 834 for (; j < strlen(cases[i].input); j++) { 835 printf("\\x%02x", (unsigned char)cases[i].input[j]); 836 } 837 printf("\"\n"); 838 } 839 } 840 841 if (! success) { 842 fail("UTF-8 auto-alignment is not bullet-proof\n"); 843 } 844 } 845 END_TEST 846 847 START_TEST(test_utf16) 848 { 849 /* <?xml version="1.0" encoding="UTF-16"?> 850 * <doc a='123'>some {A} text</doc> 851 * 852 * where {A} is U+FF21, FULLWIDTH LATIN CAPITAL LETTER A 853 */ 854 char text[] = 855 "\000<\000?\000x\000m\000\154\000 \000v\000e\000r\000s\000i\000o" 856 "\000n\000=\000'\0001\000.\000\060\000'\000 \000e\000n\000c\000o" 857 "\000d\000i\000n\000g\000=\000'\000U\000T\000F\000-\0001\000\066" 858 "\000'\000?\000>\000\n" 859 "\000<\000d\000o\000c\000 \000a\000=\000'\0001\0002\0003\000'\000>" 860 "\000s\000o\000m\000e\000 \xff\x21\000 \000t\000e\000x\000t\000" 861 "<\000/\000d\000o\000c\000>"; 862 #ifdef XML_UNICODE 863 const XML_Char *expected = XCS("some \xff21 text"); 864 #else 865 const XML_Char *expected = XCS("some \357\274\241 text"); 866 #endif 867 CharData storage; 868 869 CharData_Init(&storage); 870 XML_SetUserData(parser, &storage); 871 XML_SetCharacterDataHandler(parser, accumulate_characters); 872 if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text)-1, XML_TRUE) == XML_STATUS_ERROR) 873 xml_failure(parser); 874 CharData_CheckXMLChars(&storage, expected); 875 } 876 END_TEST 877 878 START_TEST(test_utf16_le_epilog_newline) 879 { 880 unsigned int first_chunk_bytes = 17; 881 char text[] = 882 "\xFF\xFE" /* BOM */ 883 "<\000e\000/\000>\000" /* document element */ 884 "\r\000\n\000\r\000\n\000"; /* epilog */ 885 886 if (first_chunk_bytes >= sizeof(text) - 1) 887 fail("bad value of first_chunk_bytes"); 888 if ( _XML_Parse_SINGLE_BYTES(parser, text, first_chunk_bytes, XML_FALSE) 889 == XML_STATUS_ERROR) 890 xml_failure(parser); 891 else { 892 enum XML_Status rc; 893 rc = _XML_Parse_SINGLE_BYTES(parser, text + first_chunk_bytes, 894 sizeof(text) - first_chunk_bytes - 1, XML_TRUE); 895 if (rc == XML_STATUS_ERROR) 896 xml_failure(parser); 897 } 898 } 899 END_TEST 900 901 /* Test that an outright lie in the encoding is faulted */ 902 START_TEST(test_not_utf16) 903 { 904 const char *text = 905 "<?xml version='1.0' encoding='utf-16'?>" 906 "<doc>Hi</doc>"; 907 908 /* Use a handler to provoke the appropriate code paths */ 909 XML_SetXmlDeclHandler(parser, dummy_xdecl_handler); 910 expect_failure(text, 911 XML_ERROR_INCORRECT_ENCODING, 912 "UTF-16 declared in UTF-8 not faulted"); 913 } 914 END_TEST 915 916 /* Test that an unknown encoding is rejected */ 917 START_TEST(test_bad_encoding) 918 { 919 const char *text = "<doc>Hi</doc>"; 920 921 if (!XML_SetEncoding(parser, XCS("unknown-encoding"))) 922 fail("XML_SetEncoding failed"); 923 expect_failure(text, 924 XML_ERROR_UNKNOWN_ENCODING, 925 "Unknown encoding not faulted"); 926 } 927 END_TEST 928 929 /* Regression test for SF bug #481609, #774028. */ 930 START_TEST(test_latin1_umlauts) 931 { 932 const char *text = 933 "<?xml version='1.0' encoding='iso-8859-1'?>\n" 934 "<e a='\xE4 \xF6 \xFC ä ö ü ä ö ü >'\n" 935 " >\xE4 \xF6 \xFC ä ö ü ä ö ü ></e>"; 936 #ifdef XML_UNICODE 937 /* Expected results in UTF-16 */ 938 const XML_Char *expected = 939 XCS("\x00e4 \x00f6 \x00fc ") 940 XCS("\x00e4 \x00f6 \x00fc ") 941 XCS("\x00e4 \x00f6 \x00fc >"); 942 #else 943 /* Expected results in UTF-8 */ 944 const XML_Char *expected = 945 XCS("\xC3\xA4 \xC3\xB6 \xC3\xBC ") 946 XCS("\xC3\xA4 \xC3\xB6 \xC3\xBC ") 947 XCS("\xC3\xA4 \xC3\xB6 \xC3\xBC >"); 948 #endif 949 950 run_character_check(text, expected); 951 XML_ParserReset(parser, NULL); 952 run_attribute_check(text, expected); 953 /* Repeat with a default handler */ 954 XML_ParserReset(parser, NULL); 955 XML_SetDefaultHandler(parser, dummy_default_handler); 956 run_character_check(text, expected); 957 XML_ParserReset(parser, NULL); 958 XML_SetDefaultHandler(parser, dummy_default_handler); 959 run_attribute_check(text, expected); 960 } 961 END_TEST 962 963 /* Test that an element name with a 4-byte UTF-8 character is rejected */ 964 START_TEST(test_long_utf8_character) 965 { 966 const char *text = 967 "<?xml version='1.0' encoding='utf-8'?>\n" 968 /* 0xf0 0x90 0x80 0x80 = U+10000, the first Linear B character */ 969 "<do\xf0\x90\x80\x80/>"; 970 expect_failure(text, 971 XML_ERROR_INVALID_TOKEN, 972 "4-byte UTF-8 character in element name not faulted"); 973 } 974 END_TEST 975 976 /* Test that a long latin-1 attribute (too long to convert in one go) 977 * is correctly converted 978 */ 979 START_TEST(test_long_latin1_attribute) 980 { 981 const char *text = 982 "<?xml version='1.0' encoding='iso-8859-1'?>\n" 983 "<doc att='" 984 /* 64 characters per line */ 985 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 986 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 987 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 988 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 989 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 990 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 991 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 992 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 993 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 994 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 995 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 996 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 997 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 998 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 999 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1000 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 1001 /* Last character splits across a buffer boundary */ 1002 "\xe4'>\n</doc>"; 1003 #ifdef XML_UNICODE 1004 const XML_Char *expected = 1005 /* 64 characters per line */ 1006 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1007 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1008 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1009 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1010 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1011 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1012 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1013 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1014 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1015 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1016 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1017 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1018 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1019 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1020 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1021 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO") 1022 XCS("\x00e4"); 1023 #else 1024 const XML_Char *expected = 1025 /* 64 characters per line */ 1026 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1027 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1028 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1029 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1030 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1031 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1032 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1033 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1034 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1035 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1036 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1037 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1038 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1039 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1040 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1041 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO") 1042 XCS("\xc3\xa4"); 1043 #endif 1044 1045 run_attribute_check(text, expected); 1046 } 1047 END_TEST 1048 1049 1050 /* Test that a long ASCII attribute (too long to convert in one go) 1051 * is correctly converted 1052 */ 1053 START_TEST(test_long_ascii_attribute) 1054 { 1055 const char *text = 1056 "<?xml version='1.0' encoding='us-ascii'?>\n" 1057 "<doc att='" 1058 /* 64 characters per line */ 1059 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1060 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1061 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1062 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1063 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1064 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1065 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1066 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1067 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1068 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1069 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1070 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1071 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1072 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1073 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1074 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1075 "01234'>\n</doc>"; 1076 const XML_Char *expected = 1077 /* 64 characters per line */ 1078 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1079 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1080 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1081 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1082 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1083 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1084 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1085 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1086 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1087 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1088 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1089 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1090 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1091 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1092 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1093 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 1094 XCS("01234"); 1095 1096 run_attribute_check(text, expected); 1097 } 1098 END_TEST 1099 1100 /* Regression test #1 for SF bug #653180. */ 1101 START_TEST(test_line_number_after_parse) 1102 { 1103 const char *text = 1104 "<tag>\n" 1105 "\n" 1106 "\n</tag>"; 1107 XML_Size lineno; 1108 1109 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_FALSE) == XML_STATUS_ERROR) 1110 xml_failure(parser); 1111 lineno = XML_GetCurrentLineNumber(parser); 1112 if (lineno != 4) { 1113 char buffer[100]; 1114 sprintf(buffer, 1115 "expected 4 lines, saw %" XML_FMT_INT_MOD "u", lineno); 1116 fail(buffer); 1117 } 1118 } 1119 END_TEST 1120 1121 /* Regression test #2 for SF bug #653180. */ 1122 START_TEST(test_column_number_after_parse) 1123 { 1124 const char *text = "<tag></tag>"; 1125 XML_Size colno; 1126 1127 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_FALSE) == XML_STATUS_ERROR) 1128 xml_failure(parser); 1129 colno = XML_GetCurrentColumnNumber(parser); 1130 if (colno != 11) { 1131 char buffer[100]; 1132 sprintf(buffer, 1133 "expected 11 columns, saw %" XML_FMT_INT_MOD "u", colno); 1134 fail(buffer); 1135 } 1136 } 1137 END_TEST 1138 1139 #define STRUCT_START_TAG 0 1140 #define STRUCT_END_TAG 1 1141 static void XMLCALL 1142 start_element_event_handler2(void *userData, const XML_Char *name, 1143 const XML_Char **UNUSED_P(attr)) 1144 { 1145 StructData *storage = (StructData *) userData; 1146 StructData_AddItem(storage, name, 1147 XML_GetCurrentColumnNumber(parser), 1148 XML_GetCurrentLineNumber(parser), 1149 STRUCT_START_TAG); 1150 } 1151 1152 static void XMLCALL 1153 end_element_event_handler2(void *userData, const XML_Char *name) 1154 { 1155 StructData *storage = (StructData *) userData; 1156 StructData_AddItem(storage, name, 1157 XML_GetCurrentColumnNumber(parser), 1158 XML_GetCurrentLineNumber(parser), 1159 STRUCT_END_TAG); 1160 } 1161 1162 /* Regression test #3 for SF bug #653180. */ 1163 START_TEST(test_line_and_column_numbers_inside_handlers) 1164 { 1165 const char *text = 1166 "<a>\n" /* Unix end-of-line */ 1167 " <b>\r\n" /* Windows end-of-line */ 1168 " <c/>\r" /* Mac OS end-of-line */ 1169 " </b>\n" 1170 " <d>\n" 1171 " <f/>\n" 1172 " </d>\n" 1173 "</a>"; 1174 const StructDataEntry expected[] = { 1175 { XCS("a"), 0, 1, STRUCT_START_TAG }, 1176 { XCS("b"), 2, 2, STRUCT_START_TAG }, 1177 { XCS("c"), 4, 3, STRUCT_START_TAG }, 1178 { XCS("c"), 8, 3, STRUCT_END_TAG }, 1179 { XCS("b"), 2, 4, STRUCT_END_TAG }, 1180 { XCS("d"), 2, 5, STRUCT_START_TAG }, 1181 { XCS("f"), 4, 6, STRUCT_START_TAG }, 1182 { XCS("f"), 8, 6, STRUCT_END_TAG }, 1183 { XCS("d"), 2, 7, STRUCT_END_TAG }, 1184 { XCS("a"), 0, 8, STRUCT_END_TAG } 1185 }; 1186 const int expected_count = sizeof(expected) / sizeof(StructDataEntry); 1187 StructData storage; 1188 1189 StructData_Init(&storage); 1190 XML_SetUserData(parser, &storage); 1191 XML_SetStartElementHandler(parser, start_element_event_handler2); 1192 XML_SetEndElementHandler(parser, end_element_event_handler2); 1193 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR) 1194 xml_failure(parser); 1195 1196 StructData_CheckItems(&storage, expected, expected_count); 1197 StructData_Dispose(&storage); 1198 } 1199 END_TEST 1200 1201 /* Regression test #4 for SF bug #653180. */ 1202 START_TEST(test_line_number_after_error) 1203 { 1204 const char *text = 1205 "<a>\n" 1206 " <b>\n" 1207 " </a>"; /* missing </b> */ 1208 XML_Size lineno; 1209 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_FALSE) != XML_STATUS_ERROR) 1210 fail("Expected a parse error"); 1211 1212 lineno = XML_GetCurrentLineNumber(parser); 1213 if (lineno != 3) { 1214 char buffer[100]; 1215 sprintf(buffer, "expected 3 lines, saw %" XML_FMT_INT_MOD "u", lineno); 1216 fail(buffer); 1217 } 1218 } 1219 END_TEST 1220 1221 /* Regression test #5 for SF bug #653180. */ 1222 START_TEST(test_column_number_after_error) 1223 { 1224 const char *text = 1225 "<a>\n" 1226 " <b>\n" 1227 " </a>"; /* missing </b> */ 1228 XML_Size colno; 1229 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_FALSE) != XML_STATUS_ERROR) 1230 fail("Expected a parse error"); 1231 1232 colno = XML_GetCurrentColumnNumber(parser); 1233 if (colno != 4) { 1234 char buffer[100]; 1235 sprintf(buffer, 1236 "expected 4 columns, saw %" XML_FMT_INT_MOD "u", colno); 1237 fail(buffer); 1238 } 1239 } 1240 END_TEST 1241 1242 /* Regression test for SF bug #478332. */ 1243 START_TEST(test_really_long_lines) 1244 { 1245 /* This parses an input line longer than INIT_DATA_BUF_SIZE 1246 characters long (defined to be 1024 in xmlparse.c). We take a 1247 really cheesy approach to building the input buffer, because 1248 this avoids writing bugs in buffer-filling code. 1249 */ 1250 const char *text = 1251 "<e>" 1252 /* 64 chars */ 1253 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 1254 /* until we have at least 1024 characters on the line: */ 1255 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 1256 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 1257 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 1258 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 1259 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 1260 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 1261 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 1262 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 1263 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 1264 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 1265 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 1266 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 1267 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 1268 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 1269 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 1270 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 1271 "</e>"; 1272 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR) 1273 xml_failure(parser); 1274 } 1275 END_TEST 1276 1277 /* Test cdata processing across a buffer boundary */ 1278 START_TEST(test_really_long_encoded_lines) 1279 { 1280 /* As above, except that we want to provoke an output buffer 1281 * overflow with a non-trivial encoding. For this we need to pass 1282 * the whole cdata in one go, not byte-by-byte. 1283 */ 1284 void *buffer; 1285 const char *text = 1286 "<?xml version='1.0' encoding='iso-8859-1'?>" 1287 "<e>" 1288 /* 64 chars */ 1289 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 1290 /* until we have at least 1024 characters on the line: */ 1291 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 1292 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 1293 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 1294 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 1295 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 1296 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 1297 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 1298 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 1299 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 1300 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 1301 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 1302 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 1303 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 1304 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 1305 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 1306 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 1307 "</e>"; 1308 int parse_len = (int)strlen(text); 1309 1310 /* Need a cdata handler to provoke the code path we want to test */ 1311 XML_SetCharacterDataHandler(parser, dummy_cdata_handler); 1312 buffer = XML_GetBuffer(parser, parse_len); 1313 if (buffer == NULL) 1314 fail("Could not allocate parse buffer"); 1315 memcpy(buffer, text, parse_len); 1316 if (XML_ParseBuffer(parser, parse_len, XML_TRUE) == XML_STATUS_ERROR) 1317 xml_failure(parser); 1318 } 1319 END_TEST 1320 1321 1322 /* 1323 * Element event tests. 1324 */ 1325 1326 static void XMLCALL 1327 start_element_event_handler(void *userData, 1328 const XML_Char *name, 1329 const XML_Char **UNUSED_P(atts)) 1330 { 1331 CharData_AppendXMLChars((CharData *)userData, name, -1); 1332 } 1333 1334 static void XMLCALL 1335 end_element_event_handler(void *userData, const XML_Char *name) 1336 { 1337 CharData *storage = (CharData *) userData; 1338 CharData_AppendXMLChars(storage, XCS("/"), 1); 1339 CharData_AppendXMLChars(storage, name, -1); 1340 } 1341 1342 START_TEST(test_end_element_events) 1343 { 1344 const char *text = "<a><b><c/></b><d><f/></d></a>"; 1345 const XML_Char *expected = XCS("/c/b/f/d/a"); 1346 CharData storage; 1347 1348 CharData_Init(&storage); 1349 XML_SetUserData(parser, &storage); 1350 XML_SetEndElementHandler(parser, end_element_event_handler); 1351 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR) 1352 xml_failure(parser); 1353 CharData_CheckXMLChars(&storage, expected); 1354 } 1355 END_TEST 1356 1357 1358 /* 1359 * Attribute tests. 1360 */ 1361 1362 /* Helpers used by the following test; this checks any "attr" and "refs" 1363 attributes to make sure whitespace has been normalized. 1364 1365 Return true if whitespace has been normalized in a string, using 1366 the rules for attribute value normalization. The 'is_cdata' flag 1367 is needed since CDATA attributes don't need to have multiple 1368 whitespace characters collapsed to a single space, while other 1369 attribute data types do. (Section 3.3.3 of the recommendation.) 1370 */ 1371 static int 1372 is_whitespace_normalized(const XML_Char *s, int is_cdata) 1373 { 1374 int blanks = 0; 1375 int at_start = 1; 1376 while (*s) { 1377 if (*s == XCS(' ')) 1378 ++blanks; 1379 else if (*s == XCS('\t') || *s == XCS('\n') || *s == XCS('\r')) 1380 return 0; 1381 else { 1382 if (at_start) { 1383 at_start = 0; 1384 if (blanks && !is_cdata) 1385 /* illegal leading blanks */ 1386 return 0; 1387 } 1388 else if (blanks > 1 && !is_cdata) 1389 return 0; 1390 blanks = 0; 1391 } 1392 ++s; 1393 } 1394 if (blanks && !is_cdata) 1395 return 0; 1396 return 1; 1397 } 1398 1399 /* Check the attribute whitespace checker: */ 1400 static void 1401 testhelper_is_whitespace_normalized(void) 1402 { 1403 assert(is_whitespace_normalized(XCS("abc"), 0)); 1404 assert(is_whitespace_normalized(XCS("abc"), 1)); 1405 assert(is_whitespace_normalized(XCS("abc def ghi"), 0)); 1406 assert(is_whitespace_normalized(XCS("abc def ghi"), 1)); 1407 assert(!is_whitespace_normalized(XCS(" abc def ghi"), 0)); 1408 assert(is_whitespace_normalized(XCS(" abc def ghi"), 1)); 1409 assert(!is_whitespace_normalized(XCS("abc def ghi"), 0)); 1410 assert(is_whitespace_normalized(XCS("abc def ghi"), 1)); 1411 assert(!is_whitespace_normalized(XCS("abc def ghi "), 0)); 1412 assert(is_whitespace_normalized(XCS("abc def ghi "), 1)); 1413 assert(!is_whitespace_normalized(XCS(" "), 0)); 1414 assert(is_whitespace_normalized(XCS(" "), 1)); 1415 assert(!is_whitespace_normalized(XCS("\t"), 0)); 1416 assert(!is_whitespace_normalized(XCS("\t"), 1)); 1417 assert(!is_whitespace_normalized(XCS("\n"), 0)); 1418 assert(!is_whitespace_normalized(XCS("\n"), 1)); 1419 assert(!is_whitespace_normalized(XCS("\r"), 0)); 1420 assert(!is_whitespace_normalized(XCS("\r"), 1)); 1421 assert(!is_whitespace_normalized(XCS("abc\t def"), 1)); 1422 } 1423 1424 static void XMLCALL 1425 check_attr_contains_normalized_whitespace(void *UNUSED_P(userData), 1426 const XML_Char *UNUSED_P(name), 1427 const XML_Char **atts) 1428 { 1429 int i; 1430 for (i = 0; atts[i] != NULL; i += 2) { 1431 const XML_Char *attrname = atts[i]; 1432 const XML_Char *value = atts[i + 1]; 1433 if (xcstrcmp(XCS("attr"), attrname) == 0 1434 || xcstrcmp(XCS("ents"), attrname) == 0 1435 || xcstrcmp(XCS("refs"), attrname) == 0) { 1436 if (!is_whitespace_normalized(value, 0)) { 1437 char buffer[256]; 1438 sprintf(buffer, "attribute value not normalized: %" 1439 XML_FMT_STR "='%" XML_FMT_STR "'", 1440 attrname, value); 1441 fail(buffer); 1442 } 1443 } 1444 } 1445 } 1446 1447 START_TEST(test_attr_whitespace_normalization) 1448 { 1449 const char *text = 1450 "<!DOCTYPE doc [\n" 1451 " <!ATTLIST doc\n" 1452 " attr NMTOKENS #REQUIRED\n" 1453 " ents ENTITIES #REQUIRED\n" 1454 " refs IDREFS #REQUIRED>\n" 1455 "]>\n" 1456 "<doc attr=' a b c\t\td\te\t' refs=' id-1 \t id-2\t\t' \n" 1457 " ents=' ent-1 \t\r\n" 1458 " ent-2 ' >\n" 1459 " <e id='id-1'/>\n" 1460 " <e id='id-2'/>\n" 1461 "</doc>"; 1462 1463 XML_SetStartElementHandler(parser, 1464 check_attr_contains_normalized_whitespace); 1465 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR) 1466 xml_failure(parser); 1467 } 1468 END_TEST 1469 1470 1471 /* 1472 * XML declaration tests. 1473 */ 1474 1475 START_TEST(test_xmldecl_misplaced) 1476 { 1477 expect_failure("\n" 1478 "<?xml version='1.0'?>\n" 1479 "<a/>", 1480 XML_ERROR_MISPLACED_XML_PI, 1481 "failed to report misplaced XML declaration"); 1482 } 1483 END_TEST 1484 1485 START_TEST(test_xmldecl_invalid) 1486 { 1487 expect_failure("<?xml version='1.0' \xc3\xa7?>\n<doc/>", 1488 XML_ERROR_XML_DECL, 1489 "Failed to report invalid XML declaration"); 1490 } 1491 END_TEST 1492 1493 START_TEST(test_xmldecl_missing_attr) 1494 { 1495 expect_failure("<?xml ='1.0'?>\n<doc/>\n", 1496 XML_ERROR_XML_DECL, 1497 "Failed to report missing XML declaration attribute"); 1498 } 1499 END_TEST 1500 1501 START_TEST(test_xmldecl_missing_value) 1502 { 1503 expect_failure("<?xml version='1.0' encoding='us-ascii' standalone?>\n" 1504 "<doc/>", 1505 XML_ERROR_XML_DECL, 1506 "Failed to report missing attribute value"); 1507 } 1508 END_TEST 1509 1510 /* Regression test for SF bug #584832. */ 1511 static int XMLCALL 1512 UnknownEncodingHandler(void *UNUSED_P(data),const XML_Char *encoding,XML_Encoding *info) 1513 { 1514 if (xcstrcmp(encoding, XCS("unsupported-encoding")) == 0) { 1515 int i; 1516 for (i = 0; i < 256; ++i) 1517 info->map[i] = i; 1518 info->data = NULL; 1519 info->convert = NULL; 1520 info->release = NULL; 1521 return XML_STATUS_OK; 1522 } 1523 return XML_STATUS_ERROR; 1524 } 1525 1526 START_TEST(test_unknown_encoding_internal_entity) 1527 { 1528 const char *text = 1529 "<?xml version='1.0' encoding='unsupported-encoding'?>\n" 1530 "<!DOCTYPE test [<!ENTITY foo 'bar'>]>\n" 1531 "<test a='&foo;'/>"; 1532 1533 XML_SetUnknownEncodingHandler(parser, UnknownEncodingHandler, NULL); 1534 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR) 1535 xml_failure(parser); 1536 } 1537 END_TEST 1538 1539 /* Test unrecognised encoding handler */ 1540 static void dummy_release(void *UNUSED_P(data)) 1541 { 1542 } 1543 1544 static int XMLCALL 1545 UnrecognisedEncodingHandler(void *UNUSED_P(data), 1546 const XML_Char *UNUSED_P(encoding), 1547 XML_Encoding *info) 1548 { 1549 info->data = NULL; 1550 info->convert = NULL; 1551 info->release = dummy_release; 1552 return XML_STATUS_ERROR; 1553 } 1554 1555 START_TEST(test_unrecognised_encoding_internal_entity) 1556 { 1557 const char *text = 1558 "<?xml version='1.0' encoding='unsupported-encoding'?>\n" 1559 "<!DOCTYPE test [<!ENTITY foo 'bar'>]>\n" 1560 "<test a='&foo;'/>"; 1561 1562 XML_SetUnknownEncodingHandler(parser, 1563 UnrecognisedEncodingHandler, 1564 NULL); 1565 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR) 1566 fail("Unrecognised encoding not rejected"); 1567 } 1568 END_TEST 1569 1570 /* Regression test for SF bug #620106. */ 1571 static int XMLCALL 1572 external_entity_loader(XML_Parser parser, 1573 const XML_Char *context, 1574 const XML_Char *UNUSED_P(base), 1575 const XML_Char *UNUSED_P(systemId), 1576 const XML_Char *UNUSED_P(publicId)) 1577 { 1578 ExtTest *test_data = (ExtTest *)XML_GetUserData(parser); 1579 XML_Parser extparser; 1580 1581 extparser = XML_ExternalEntityParserCreate(parser, context, NULL); 1582 if (extparser == NULL) 1583 fail("Could not create external entity parser."); 1584 if (test_data->encoding != NULL) { 1585 if (!XML_SetEncoding(extparser, test_data->encoding)) 1586 fail("XML_SetEncoding() ignored for external entity"); 1587 } 1588 if ( _XML_Parse_SINGLE_BYTES(extparser, 1589 test_data->parse_text, 1590 (int)strlen(test_data->parse_text), 1591 XML_TRUE) 1592 == XML_STATUS_ERROR) { 1593 xml_failure(extparser); 1594 return XML_STATUS_ERROR; 1595 } 1596 XML_ParserFree(extparser); 1597 return XML_STATUS_OK; 1598 } 1599 1600 START_TEST(test_ext_entity_set_encoding) 1601 { 1602 const char *text = 1603 "<!DOCTYPE doc [\n" 1604 " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n" 1605 "]>\n" 1606 "<doc>&en;</doc>"; 1607 ExtTest test_data = { 1608 /* This text says it's an unsupported encoding, but it's really 1609 UTF-8, which we tell Expat using XML_SetEncoding(). 1610 */ 1611 "<?xml encoding='iso-8859-3'?>\xC3\xA9", 1612 XCS("utf-8"), 1613 NULL 1614 }; 1615 #ifdef XML_UNICODE 1616 const XML_Char *expected = XCS("\x00e9"); 1617 #else 1618 const XML_Char *expected = XCS("\xc3\xa9"); 1619 #endif 1620 1621 XML_SetExternalEntityRefHandler(parser, external_entity_loader); 1622 run_ext_character_check(text, &test_data, expected); 1623 } 1624 END_TEST 1625 1626 /* Test external entities with no handler */ 1627 START_TEST(test_ext_entity_no_handler) 1628 { 1629 const char *text = 1630 "<!DOCTYPE doc [\n" 1631 " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n" 1632 "]>\n" 1633 "<doc>&en;</doc>"; 1634 1635 XML_SetDefaultHandler(parser, dummy_default_handler); 1636 run_character_check(text, XCS("")); 1637 } 1638 END_TEST 1639 1640 /* Test UTF-8 BOM is accepted */ 1641 START_TEST(test_ext_entity_set_bom) 1642 { 1643 const char *text = 1644 "<!DOCTYPE doc [\n" 1645 " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n" 1646 "]>\n" 1647 "<doc>&en;</doc>"; 1648 ExtTest test_data = { 1649 "\xEF\xBB\xBF" /* BOM */ 1650 "<?xml encoding='iso-8859-3'?>" 1651 "\xC3\xA9", 1652 XCS("utf-8"), 1653 NULL 1654 }; 1655 #ifdef XML_UNICODE 1656 const XML_Char *expected = XCS("\x00e9"); 1657 #else 1658 const XML_Char *expected = XCS("\xc3\xa9"); 1659 #endif 1660 1661 XML_SetExternalEntityRefHandler(parser, external_entity_loader); 1662 run_ext_character_check(text, &test_data, expected); 1663 } 1664 END_TEST 1665 1666 1667 /* Test that bad encodings are faulted */ 1668 typedef struct ext_faults 1669 { 1670 const char *parse_text; 1671 const char *fail_text; 1672 const XML_Char *encoding; 1673 enum XML_Error error; 1674 } ExtFaults; 1675 1676 static int XMLCALL 1677 external_entity_faulter(XML_Parser parser, 1678 const XML_Char *context, 1679 const XML_Char *UNUSED_P(base), 1680 const XML_Char *UNUSED_P(systemId), 1681 const XML_Char *UNUSED_P(publicId)) 1682 { 1683 XML_Parser ext_parser; 1684 ExtFaults *fault = (ExtFaults *)XML_GetUserData(parser); 1685 1686 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 1687 if (ext_parser == NULL) 1688 fail("Could not create external entity parser"); 1689 if (fault->encoding != NULL) { 1690 if (!XML_SetEncoding(ext_parser, fault->encoding)) 1691 fail("XML_SetEncoding failed"); 1692 } 1693 if (_XML_Parse_SINGLE_BYTES(ext_parser, 1694 fault->parse_text, 1695 (int)strlen(fault->parse_text), 1696 XML_TRUE) != XML_STATUS_ERROR) 1697 fail(fault->fail_text); 1698 if (XML_GetErrorCode(ext_parser) != fault->error) 1699 xml_failure(ext_parser); 1700 1701 XML_ParserFree(ext_parser); 1702 return XML_STATUS_ERROR; 1703 } 1704 1705 START_TEST(test_ext_entity_bad_encoding) 1706 { 1707 const char *text = 1708 "<!DOCTYPE doc [\n" 1709 " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n" 1710 "]>\n" 1711 "<doc>&en;</doc>"; 1712 ExtFaults fault = { 1713 "<?xml encoding='iso-8859-3'?>u", 1714 "Unsupported encoding not faulted", 1715 XCS("unknown"), 1716 XML_ERROR_UNKNOWN_ENCODING 1717 }; 1718 1719 XML_SetExternalEntityRefHandler(parser, external_entity_faulter); 1720 XML_SetUserData(parser, &fault); 1721 expect_failure(text, 1722 XML_ERROR_EXTERNAL_ENTITY_HANDLING, 1723 "Bad encoding should not have been accepted"); 1724 } 1725 END_TEST 1726 1727 /* Try handing an invalid encoding to an external entity parser */ 1728 START_TEST(test_ext_entity_bad_encoding_2) 1729 { 1730 const char *text = 1731 "<?xml version='1.0' encoding='us-ascii'?>\n" 1732 "<!DOCTYPE doc SYSTEM 'foo'>\n" 1733 "<doc>&entity;</doc>"; 1734 ExtFaults fault = { 1735 "<!ELEMENT doc (#PCDATA)*>", 1736 "Unknown encoding not faulted", 1737 XCS("unknown-encoding"), 1738 XML_ERROR_UNKNOWN_ENCODING 1739 }; 1740 1741 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 1742 XML_SetExternalEntityRefHandler(parser, external_entity_faulter); 1743 XML_SetUserData(parser, &fault); 1744 expect_failure(text, XML_ERROR_EXTERNAL_ENTITY_HANDLING, 1745 "Bad encoding not faulted in external entity handler"); 1746 } 1747 END_TEST 1748 1749 /* Test that no error is reported for unknown entities if we don't 1750 read an external subset. This was fixed in Expat 1.95.5. 1751 */ 1752 START_TEST(test_wfc_undeclared_entity_unread_external_subset) { 1753 const char *text = 1754 "<!DOCTYPE doc SYSTEM 'foo'>\n" 1755 "<doc>&entity;</doc>"; 1756 1757 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR) 1758 xml_failure(parser); 1759 } 1760 END_TEST 1761 1762 /* Test that an error is reported for unknown entities if we don't 1763 have an external subset. 1764 */ 1765 START_TEST(test_wfc_undeclared_entity_no_external_subset) { 1766 expect_failure("<doc>&entity;</doc>", 1767 XML_ERROR_UNDEFINED_ENTITY, 1768 "Parser did not report undefined entity w/out a DTD."); 1769 } 1770 END_TEST 1771 1772 /* Test that an error is reported for unknown entities if we don't 1773 read an external subset, but have been declared standalone. 1774 */ 1775 START_TEST(test_wfc_undeclared_entity_standalone) { 1776 const char *text = 1777 "<?xml version='1.0' encoding='us-ascii' standalone='yes'?>\n" 1778 "<!DOCTYPE doc SYSTEM 'foo'>\n" 1779 "<doc>&entity;</doc>"; 1780 1781 expect_failure(text, 1782 XML_ERROR_UNDEFINED_ENTITY, 1783 "Parser did not report undefined entity (standalone)."); 1784 } 1785 END_TEST 1786 1787 /* Test that an error is reported for unknown entities if we have read 1788 an external subset, and standalone is true. 1789 */ 1790 START_TEST(test_wfc_undeclared_entity_with_external_subset_standalone) { 1791 const char *text = 1792 "<?xml version='1.0' encoding='us-ascii' standalone='yes'?>\n" 1793 "<!DOCTYPE doc SYSTEM 'foo'>\n" 1794 "<doc>&entity;</doc>"; 1795 ExtTest test_data = { 1796 "<!ELEMENT doc (#PCDATA)*>", 1797 NULL, 1798 NULL 1799 }; 1800 1801 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 1802 XML_SetUserData(parser, &test_data); 1803 XML_SetExternalEntityRefHandler(parser, external_entity_loader); 1804 expect_failure(text, 1805 XML_ERROR_UNDEFINED_ENTITY, 1806 "Parser did not report undefined entity (external DTD)."); 1807 } 1808 END_TEST 1809 1810 /* Test that external entity handling is not done if the parsing flag 1811 * is set to UNLESS_STANDALONE 1812 */ 1813 START_TEST(test_entity_with_external_subset_unless_standalone) { 1814 const char *text = 1815 "<?xml version='1.0' encoding='us-ascii' standalone='yes'?>\n" 1816 "<!DOCTYPE doc SYSTEM 'foo'>\n" 1817 "<doc>&entity;</doc>"; 1818 ExtTest test_data = { "<!ENTITY entity 'bar'>", NULL, NULL }; 1819 1820 XML_SetParamEntityParsing(parser, 1821 XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE); 1822 XML_SetUserData(parser, &test_data); 1823 XML_SetExternalEntityRefHandler(parser, external_entity_loader); 1824 expect_failure(text, 1825 XML_ERROR_UNDEFINED_ENTITY, 1826 "Parser did not report undefined entity"); 1827 } 1828 END_TEST 1829 1830 /* Test that no error is reported for unknown entities if we have read 1831 an external subset, and standalone is false. 1832 */ 1833 START_TEST(test_wfc_undeclared_entity_with_external_subset) { 1834 const char *text = 1835 "<?xml version='1.0' encoding='us-ascii'?>\n" 1836 "<!DOCTYPE doc SYSTEM 'foo'>\n" 1837 "<doc>&entity;</doc>"; 1838 ExtTest test_data = { 1839 "<!ELEMENT doc (#PCDATA)*>", 1840 NULL, 1841 NULL 1842 }; 1843 1844 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 1845 XML_SetExternalEntityRefHandler(parser, external_entity_loader); 1846 run_ext_character_check(text, &test_data, XCS("")); 1847 } 1848 END_TEST 1849 1850 /* Test that an error is reported if our NotStandalone handler fails */ 1851 static int XMLCALL 1852 reject_not_standalone_handler(void *UNUSED_P(userData)) 1853 { 1854 return XML_STATUS_ERROR; 1855 } 1856 1857 START_TEST(test_not_standalone_handler_reject) 1858 { 1859 const char *text = 1860 "<?xml version='1.0' encoding='us-ascii'?>\n" 1861 "<!DOCTYPE doc SYSTEM 'foo'>\n" 1862 "<doc>&entity;</doc>"; 1863 ExtTest test_data = { 1864 "<!ELEMENT doc (#PCDATA)*>", 1865 NULL, 1866 NULL 1867 }; 1868 1869 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 1870 XML_SetUserData(parser, &test_data); 1871 XML_SetExternalEntityRefHandler(parser, external_entity_loader); 1872 XML_SetNotStandaloneHandler(parser, reject_not_standalone_handler); 1873 expect_failure(text, XML_ERROR_NOT_STANDALONE, 1874 "NotStandalone handler failed to reject"); 1875 1876 /* Try again but without external entity handling */ 1877 XML_ParserReset(parser, NULL); 1878 XML_SetNotStandaloneHandler(parser, reject_not_standalone_handler); 1879 expect_failure(text, XML_ERROR_NOT_STANDALONE, 1880 "NotStandalone handler failed to reject"); 1881 } 1882 END_TEST 1883 1884 /* Test that no error is reported if our NotStandalone handler succeeds */ 1885 static int XMLCALL 1886 accept_not_standalone_handler(void *UNUSED_P(userData)) 1887 { 1888 return XML_STATUS_OK; 1889 } 1890 1891 START_TEST(test_not_standalone_handler_accept) 1892 { 1893 const char *text = 1894 "<?xml version='1.0' encoding='us-ascii'?>\n" 1895 "<!DOCTYPE doc SYSTEM 'foo'>\n" 1896 "<doc>&entity;</doc>"; 1897 ExtTest test_data = { 1898 "<!ELEMENT doc (#PCDATA)*>", 1899 NULL, 1900 NULL 1901 }; 1902 1903 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 1904 XML_SetExternalEntityRefHandler(parser, external_entity_loader); 1905 XML_SetNotStandaloneHandler(parser, accept_not_standalone_handler); 1906 run_ext_character_check(text, &test_data, XCS("")); 1907 1908 /* Repeat wtihout the external entity handler */ 1909 XML_ParserReset(parser, NULL); 1910 XML_SetNotStandaloneHandler(parser, accept_not_standalone_handler); 1911 run_character_check(text, XCS("")); 1912 } 1913 END_TEST 1914 1915 START_TEST(test_wfc_no_recursive_entity_refs) 1916 { 1917 const char *text = 1918 "<!DOCTYPE doc [\n" 1919 " <!ENTITY entity '&entity;'>\n" 1920 "]>\n" 1921 "<doc>&entity;</doc>"; 1922 1923 expect_failure(text, 1924 XML_ERROR_RECURSIVE_ENTITY_REF, 1925 "Parser did not report recursive entity reference."); 1926 } 1927 END_TEST 1928 1929 /* Test incomplete external entities are faulted */ 1930 START_TEST(test_ext_entity_invalid_parse) 1931 { 1932 const char *text = 1933 "<!DOCTYPE doc [\n" 1934 " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n" 1935 "]>\n" 1936 "<doc>&en;</doc>"; 1937 const ExtFaults faults[] = { 1938 { 1939 "<", 1940 "Incomplete element declaration not faulted", 1941 NULL, 1942 XML_ERROR_UNCLOSED_TOKEN 1943 }, 1944 { 1945 "<\xe2\x82", /* First two bytes of a three-byte char */ 1946 "Incomplete character not faulted", 1947 NULL, 1948 XML_ERROR_PARTIAL_CHAR 1949 }, 1950 { 1951 "<tag>\xe2\x82", 1952 "Incomplete character in CDATA not faulted", 1953 NULL, 1954 XML_ERROR_PARTIAL_CHAR 1955 }, 1956 { NULL, NULL, NULL, XML_ERROR_NONE } 1957 }; 1958 const ExtFaults *fault = faults; 1959 1960 for (; fault->parse_text != NULL; fault++) { 1961 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 1962 XML_SetExternalEntityRefHandler(parser, external_entity_faulter); 1963 XML_SetUserData(parser, (void *)fault); 1964 expect_failure(text, 1965 XML_ERROR_EXTERNAL_ENTITY_HANDLING, 1966 "Parser did not report external entity error"); 1967 XML_ParserReset(parser, NULL); 1968 } 1969 } 1970 END_TEST 1971 1972 1973 /* Regression test for SF bug #483514. */ 1974 START_TEST(test_dtd_default_handling) 1975 { 1976 const char *text = 1977 "<!DOCTYPE doc [\n" 1978 "<!ENTITY e SYSTEM 'http://example.org/e'>\n" 1979 "<!NOTATION n SYSTEM 'http://example.org/n'>\n" 1980 "<!ELEMENT doc EMPTY>\n" 1981 "<!ATTLIST doc a CDATA #IMPLIED>\n" 1982 "<?pi in dtd?>\n" 1983 "<!--comment in dtd-->\n" 1984 "]><doc/>"; 1985 1986 XML_SetDefaultHandler(parser, accumulate_characters); 1987 XML_SetStartDoctypeDeclHandler(parser, dummy_start_doctype_handler); 1988 XML_SetEndDoctypeDeclHandler(parser, dummy_end_doctype_handler); 1989 XML_SetEntityDeclHandler(parser, dummy_entity_decl_handler); 1990 XML_SetNotationDeclHandler(parser, dummy_notation_decl_handler); 1991 XML_SetElementDeclHandler(parser, dummy_element_decl_handler); 1992 XML_SetAttlistDeclHandler(parser, dummy_attlist_decl_handler); 1993 XML_SetProcessingInstructionHandler(parser, dummy_pi_handler); 1994 XML_SetCommentHandler(parser, dummy_comment_handler); 1995 XML_SetStartCdataSectionHandler(parser, dummy_start_cdata_handler); 1996 XML_SetEndCdataSectionHandler(parser, dummy_end_cdata_handler); 1997 run_character_check(text, XCS("\n\n\n\n\n\n\n<doc/>")); 1998 } 1999 END_TEST 2000 2001 /* Test handling of attribute declarations */ 2002 typedef struct AttTest { 2003 const char *definition; 2004 const XML_Char *element_name; 2005 const XML_Char *attr_name; 2006 const XML_Char *attr_type; 2007 const XML_Char *default_value; 2008 int is_required; 2009 } AttTest; 2010 2011 static void XMLCALL 2012 verify_attlist_decl_handler(void *userData, 2013 const XML_Char *element_name, 2014 const XML_Char *attr_name, 2015 const XML_Char *attr_type, 2016 const XML_Char *default_value, 2017 int is_required) 2018 { 2019 AttTest *at = (AttTest *)userData; 2020 2021 if (xcstrcmp(element_name, at->element_name)) 2022 fail("Unexpected element name in attribute declaration"); 2023 if (xcstrcmp(attr_name, at->attr_name)) 2024 fail("Unexpected attribute name in attribute declaration"); 2025 if (xcstrcmp(attr_type, at->attr_type)) 2026 fail("Unexpected attribute type in attribute declaration"); 2027 if ((default_value == NULL && at->default_value != NULL) || 2028 (default_value != NULL && at->default_value == NULL) || 2029 (default_value != NULL && xcstrcmp(default_value, at->default_value))) 2030 fail("Unexpected default value in attribute declaration"); 2031 if (is_required != at->is_required) 2032 fail("Requirement mismatch in attribute declaration"); 2033 } 2034 2035 START_TEST(test_dtd_attr_handling) 2036 { 2037 const char *prolog = 2038 "<!DOCTYPE doc [\n" 2039 "<!ELEMENT doc EMPTY>\n"; 2040 AttTest attr_data[] = { 2041 { 2042 "<!ATTLIST doc a ( one | two | three ) #REQUIRED>\n" 2043 "]>" 2044 "<doc a='two'/>", 2045 XCS("doc"), 2046 XCS("a"), 2047 XCS("(one|two|three)"), /* Extraneous spaces will be removed */ 2048 NULL, 2049 XML_TRUE 2050 }, 2051 { 2052 "<!NOTATION foo SYSTEM 'http://example.org/foo'>\n" 2053 "<!ATTLIST doc a NOTATION (foo) #IMPLIED>\n" 2054 "]>" 2055 "<doc/>", 2056 XCS("doc"), 2057 XCS("a"), 2058 XCS("NOTATION(foo)"), 2059 NULL, 2060 XML_FALSE 2061 }, 2062 { 2063 "<!ATTLIST doc a NOTATION (foo) 'bar'>\n" 2064 "]>" 2065 "<doc/>", 2066 XCS("doc"), 2067 XCS("a"), 2068 XCS("NOTATION(foo)"), 2069 XCS("bar"), 2070 XML_FALSE 2071 }, 2072 { 2073 "<!ATTLIST doc a CDATA '\xdb\xb2'>\n" 2074 "]>" 2075 "<doc/>", 2076 XCS("doc"), 2077 XCS("a"), 2078 XCS("CDATA"), 2079 #ifdef XML_UNICODE 2080 XCS("\x06f2"), 2081 #else 2082 XCS("\xdb\xb2"), 2083 #endif 2084 XML_FALSE 2085 }, 2086 { NULL, NULL, NULL, NULL, NULL, XML_FALSE } 2087 }; 2088 AttTest *test; 2089 2090 for (test = attr_data; test->definition != NULL; test++) { 2091 XML_SetAttlistDeclHandler(parser, verify_attlist_decl_handler); 2092 XML_SetUserData(parser, test); 2093 if (_XML_Parse_SINGLE_BYTES(parser, prolog, (int)strlen(prolog), 2094 XML_FALSE) == XML_STATUS_ERROR) 2095 xml_failure(parser); 2096 if (_XML_Parse_SINGLE_BYTES(parser, 2097 test->definition, 2098 (int)strlen(test->definition), 2099 XML_TRUE) == XML_STATUS_ERROR) 2100 xml_failure(parser); 2101 XML_ParserReset(parser, NULL); 2102 } 2103 } 2104 END_TEST 2105 2106 /* See related SF bug #673791. 2107 When namespace processing is enabled, setting the namespace URI for 2108 a prefix is not allowed; this test ensures that it *is* allowed 2109 when namespace processing is not enabled. 2110 (See Namespaces in XML, section 2.) 2111 */ 2112 START_TEST(test_empty_ns_without_namespaces) 2113 { 2114 const char *text = 2115 "<doc xmlns:prefix='http://example.org/'>\n" 2116 " <e xmlns:prefix=''/>\n" 2117 "</doc>"; 2118 2119 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR) 2120 xml_failure(parser); 2121 } 2122 END_TEST 2123 2124 /* Regression test for SF bug #824420. 2125 Checks that an xmlns:prefix attribute set in an attribute's default 2126 value isn't misinterpreted. 2127 */ 2128 START_TEST(test_ns_in_attribute_default_without_namespaces) 2129 { 2130 const char *text = 2131 "<!DOCTYPE e:element [\n" 2132 " <!ATTLIST e:element\n" 2133 " xmlns:e CDATA 'http://example.org/'>\n" 2134 " ]>\n" 2135 "<e:element/>"; 2136 2137 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR) 2138 xml_failure(parser); 2139 } 2140 END_TEST 2141 2142 static const char *long_character_data_text = 2143 "<?xml version='1.0' encoding='iso-8859-1'?><s>" 2144 "012345678901234567890123456789012345678901234567890123456789" 2145 "012345678901234567890123456789012345678901234567890123456789" 2146 "012345678901234567890123456789012345678901234567890123456789" 2147 "012345678901234567890123456789012345678901234567890123456789" 2148 "012345678901234567890123456789012345678901234567890123456789" 2149 "012345678901234567890123456789012345678901234567890123456789" 2150 "012345678901234567890123456789012345678901234567890123456789" 2151 "012345678901234567890123456789012345678901234567890123456789" 2152 "012345678901234567890123456789012345678901234567890123456789" 2153 "012345678901234567890123456789012345678901234567890123456789" 2154 "012345678901234567890123456789012345678901234567890123456789" 2155 "012345678901234567890123456789012345678901234567890123456789" 2156 "012345678901234567890123456789012345678901234567890123456789" 2157 "012345678901234567890123456789012345678901234567890123456789" 2158 "012345678901234567890123456789012345678901234567890123456789" 2159 "012345678901234567890123456789012345678901234567890123456789" 2160 "012345678901234567890123456789012345678901234567890123456789" 2161 "012345678901234567890123456789012345678901234567890123456789" 2162 "012345678901234567890123456789012345678901234567890123456789" 2163 "012345678901234567890123456789012345678901234567890123456789" 2164 "</s>"; 2165 2166 static XML_Bool resumable = XML_FALSE; 2167 2168 static void 2169 clearing_aborting_character_handler(void *UNUSED_P(userData), 2170 const XML_Char *UNUSED_P(s), int UNUSED_P(len)) 2171 { 2172 XML_StopParser(parser, resumable); 2173 XML_SetCharacterDataHandler(parser, NULL); 2174 } 2175 2176 /* Regression test for SF bug #1515266: missing check of stopped 2177 parser in doContext() 'for' loop. */ 2178 START_TEST(test_stop_parser_between_char_data_calls) 2179 { 2180 /* The sample data must be big enough that there are two calls to 2181 the character data handler from within the inner "for" loop of 2182 the XML_TOK_DATA_CHARS case in doContent(), and the character 2183 handler must stop the parser and clear the character data 2184 handler. 2185 */ 2186 const char *text = long_character_data_text; 2187 2188 XML_SetCharacterDataHandler(parser, clearing_aborting_character_handler); 2189 resumable = XML_FALSE; 2190 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR) 2191 xml_failure(parser); 2192 if (XML_GetErrorCode(parser) != XML_ERROR_ABORTED) 2193 xml_failure(parser); 2194 } 2195 END_TEST 2196 2197 /* Regression test for SF bug #1515266: missing check of stopped 2198 parser in doContext() 'for' loop. */ 2199 START_TEST(test_suspend_parser_between_char_data_calls) 2200 { 2201 /* The sample data must be big enough that there are two calls to 2202 the character data handler from within the inner "for" loop of 2203 the XML_TOK_DATA_CHARS case in doContent(), and the character 2204 handler must stop the parser and clear the character data 2205 handler. 2206 */ 2207 const char *text = long_character_data_text; 2208 2209 XML_SetCharacterDataHandler(parser, clearing_aborting_character_handler); 2210 resumable = XML_TRUE; 2211 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_SUSPENDED) 2212 xml_failure(parser); 2213 if (XML_GetErrorCode(parser) != XML_ERROR_NONE) 2214 xml_failure(parser); 2215 /* Try parsing directly */ 2216 if (XML_Parse(parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR) 2217 fail("Attempt to continue parse while suspended not faulted"); 2218 if (XML_GetErrorCode(parser) != XML_ERROR_SUSPENDED) 2219 fail("Suspended parse not faulted with correct error"); 2220 } 2221 END_TEST 2222 2223 2224 static XML_Bool abortable = XML_FALSE; 2225 2226 static void 2227 parser_stop_character_handler(void *UNUSED_P(userData), 2228 const XML_Char *UNUSED_P(s), 2229 int UNUSED_P(len)) 2230 { 2231 XML_StopParser(parser, resumable); 2232 XML_SetCharacterDataHandler(parser, NULL); 2233 if (!resumable) { 2234 /* Check that aborting an aborted parser is faulted */ 2235 if (XML_StopParser(parser, XML_FALSE) != XML_STATUS_ERROR) 2236 fail("Aborting aborted parser not faulted"); 2237 if (XML_GetErrorCode(parser) != XML_ERROR_FINISHED) 2238 xml_failure(parser); 2239 } else if (abortable) { 2240 /* Check that aborting a suspended parser works */ 2241 if (XML_StopParser(parser, XML_FALSE) == XML_STATUS_ERROR) 2242 xml_failure(parser); 2243 } else { 2244 /* Check that suspending a suspended parser works */ 2245 if (XML_StopParser(parser, XML_TRUE) != XML_STATUS_ERROR) 2246 fail("Suspending suspended parser not faulted"); 2247 if (XML_GetErrorCode(parser) != XML_ERROR_SUSPENDED) 2248 xml_failure(parser); 2249 } 2250 } 2251 2252 /* Test repeated calls to XML_StopParser are handled correctly */ 2253 START_TEST(test_repeated_stop_parser_between_char_data_calls) 2254 { 2255 const char *text = long_character_data_text; 2256 2257 XML_SetCharacterDataHandler(parser, parser_stop_character_handler); 2258 resumable = XML_FALSE; 2259 abortable = XML_FALSE; 2260 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 2261 XML_TRUE) != XML_STATUS_ERROR) 2262 fail("Failed to double-stop parser"); 2263 2264 XML_ParserReset(parser, NULL); 2265 XML_SetCharacterDataHandler(parser, parser_stop_character_handler); 2266 resumable = XML_TRUE; 2267 abortable = XML_FALSE; 2268 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 2269 XML_TRUE) != XML_STATUS_SUSPENDED) 2270 fail("Failed to double-suspend parser"); 2271 2272 XML_ParserReset(parser, NULL); 2273 XML_SetCharacterDataHandler(parser, parser_stop_character_handler); 2274 resumable = XML_TRUE; 2275 abortable = XML_TRUE; 2276 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 2277 XML_TRUE) != XML_STATUS_ERROR) 2278 fail("Failed to suspend-abort parser"); 2279 } 2280 END_TEST 2281 2282 2283 START_TEST(test_good_cdata_ascii) 2284 { 2285 const char *text = "<a><![CDATA[<greeting>Hello, world!</greeting>]]></a>"; 2286 const XML_Char *expected = XCS("<greeting>Hello, world!</greeting>"); 2287 2288 CharData storage; 2289 CharData_Init(&storage); 2290 XML_SetUserData(parser, &storage); 2291 XML_SetCharacterDataHandler(parser, accumulate_characters); 2292 /* Add start and end handlers for coverage */ 2293 XML_SetStartCdataSectionHandler(parser, dummy_start_cdata_handler); 2294 XML_SetEndCdataSectionHandler(parser, dummy_end_cdata_handler); 2295 2296 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR) 2297 xml_failure(parser); 2298 CharData_CheckXMLChars(&storage, expected); 2299 2300 /* Try again, this time with a default handler */ 2301 XML_ParserReset(parser, NULL); 2302 CharData_Init(&storage); 2303 XML_SetUserData(parser, &storage); 2304 XML_SetCharacterDataHandler(parser, accumulate_characters); 2305 XML_SetDefaultHandler(parser, dummy_default_handler); 2306 2307 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR) 2308 xml_failure(parser); 2309 CharData_CheckXMLChars(&storage, expected); 2310 } 2311 END_TEST 2312 2313 START_TEST(test_good_cdata_utf16) 2314 { 2315 /* Test data is: 2316 * <?xml version='1.0' encoding='utf-16'?> 2317 * <a><![CDATA[hello]]></a> 2318 */ 2319 const char text[] = 2320 "\0<\0?\0x\0m\0l\0" 2321 " \0v\0e\0r\0s\0i\0o\0n\0=\0'\0\x31\0.\0\x30\0'\0" 2322 " \0e\0n\0c\0o\0d\0i\0n\0g\0=\0'\0u\0t\0f\0-\0""1\0""6\0'" 2323 "\0?\0>\0\n" 2324 "\0<\0a\0>\0<\0!\0[\0C\0D\0A\0T\0A\0[\0h\0e\0l\0l\0o\0]\0]\0>\0<\0/\0a\0>"; 2325 const XML_Char *expected = XCS("hello"); 2326 2327 CharData storage; 2328 CharData_Init(&storage); 2329 XML_SetUserData(parser, &storage); 2330 XML_SetCharacterDataHandler(parser, accumulate_characters); 2331 2332 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text) - 1, XML_TRUE) == XML_STATUS_ERROR) 2333 xml_failure(parser); 2334 CharData_CheckXMLChars(&storage, expected); 2335 } 2336 END_TEST 2337 2338 START_TEST(test_good_cdata_utf16_le) 2339 { 2340 /* Test data is: 2341 * <?xml version='1.0' encoding='utf-16'?> 2342 * <a><![CDATA[hello]]></a> 2343 */ 2344 const char text[] = 2345 "<\0?\0x\0m\0l\0" 2346 " \0v\0e\0r\0s\0i\0o\0n\0=\0'\0\x31\0.\0\x30\0'\0" 2347 " \0e\0n\0c\0o\0d\0i\0n\0g\0=\0'\0u\0t\0f\0-\0""1\0""6\0'" 2348 "\0?\0>\0\n" 2349 "\0<\0a\0>\0<\0!\0[\0C\0D\0A\0T\0A\0[\0h\0e\0l\0l\0o\0]\0]\0>\0<\0/\0a\0>\0"; 2350 const XML_Char *expected = XCS("hello"); 2351 2352 CharData storage; 2353 CharData_Init(&storage); 2354 XML_SetUserData(parser, &storage); 2355 XML_SetCharacterDataHandler(parser, accumulate_characters); 2356 2357 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text) - 1, XML_TRUE) == XML_STATUS_ERROR) 2358 xml_failure(parser); 2359 CharData_CheckXMLChars(&storage, expected); 2360 } 2361 END_TEST 2362 2363 /* Test UTF16 conversion of a long cdata string */ 2364 2365 /* 16 characters: handy macro to reduce visual clutter */ 2366 #define A_TO_P_IN_UTF16 "\0A\0B\0C\0D\0E\0F\0G\0H\0I\0J\0K\0L\0M\0N\0O\0P" 2367 2368 START_TEST(test_long_cdata_utf16) 2369 { 2370 /* Test data is: 2371 * <?xlm version='1.0' encoding='utf-16'?> 2372 * <a><![CDATA[ 2373 * ABCDEFGHIJKLMNOP 2374 * ]]></a> 2375 */ 2376 const char text[] = 2377 "\0<\0?\0x\0m\0l\0 " 2378 "\0v\0e\0r\0s\0i\0o\0n\0=\0'\0\x31\0.\0\x30\0'\0 " 2379 "\0e\0n\0c\0o\0d\0i\0n\0g\0=\0'\0u\0t\0f\0-\0\x31\0\x36\0'\0?\0>" 2380 "\0<\0a\0>\0<\0!\0[\0C\0D\0A\0T\0A\0[" 2381 /* 64 characters per line */ 2382 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 2383 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 2384 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 2385 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 2386 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 2387 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 2388 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 2389 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 2390 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 2391 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 2392 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 2393 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 2394 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 2395 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 2396 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 2397 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 2398 A_TO_P_IN_UTF16 2399 "\0]\0]\0>\0<\0/\0a\0>"; 2400 const XML_Char *expected = 2401 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 2402 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 2403 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 2404 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 2405 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 2406 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 2407 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 2408 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 2409 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 2410 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 2411 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 2412 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 2413 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 2414 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 2415 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 2416 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP") 2417 XCS("ABCDEFGHIJKLMNOP";) 2418 CharData storage; 2419 void *buffer; 2420 2421 CharData_Init(&storage); 2422 XML_SetUserData(parser, &storage); 2423 XML_SetCharacterDataHandler(parser, accumulate_characters); 2424 buffer = XML_GetBuffer(parser, sizeof(text) - 1); 2425 if (buffer == NULL) 2426 fail("Could not allocate parse buffer"); 2427 memcpy(buffer, text, sizeof(text) - 1); 2428 if (XML_ParseBuffer(parser, 2429 sizeof(text) - 1, 2430 XML_TRUE) == XML_STATUS_ERROR) 2431 xml_failure(parser); 2432 CharData_CheckXMLChars(&storage, expected); 2433 } 2434 END_TEST 2435 2436 /* Test handling of multiple unit UTF-16 characters */ 2437 START_TEST(test_multichar_cdata_utf16) 2438 { 2439 /* Test data is: 2440 * <?xml version='1.0' encoding='utf-16'?> 2441 * <a><![CDATA[{MINIM}{CROTCHET}]]></a> 2442 * 2443 * where {MINIM} is U+1d15e (a minim or half-note) 2444 * UTF-16: 0xd834 0xdd5e 2445 * UTF-8: 0xf0 0x9d 0x85 0x9e 2446 * and {CROTCHET} is U+1d15f (a crotchet or quarter-note) 2447 * UTF-16: 0xd834 0xdd5f 2448 * UTF-8: 0xf0 0x9d 0x85 0x9f 2449 */ 2450 const char text[] = 2451 "\0<\0?\0x\0m\0l\0" 2452 " \0v\0e\0r\0s\0i\0o\0n\0=\0'\0\x31\0.\0\x30\0'\0" 2453 " \0e\0n\0c\0o\0d\0i\0n\0g\0=\0'\0u\0t\0f\0-\0""1\0""6\0'" 2454 "\0?\0>\0\n" 2455 "\0<\0a\0>\0<\0!\0[\0C\0D\0A\0T\0A\0[" 2456 "\xd8\x34\xdd\x5e\xd8\x34\xdd\x5f" 2457 "\0]\0]\0>\0<\0/\0a\0>"; 2458 #ifdef XML_UNICODE 2459 const XML_Char *expected = XCS("\xd834\xdd5e\xd834\xdd5f"); 2460 #else 2461 const XML_Char *expected = XCS("\xf0\x9d\x85\x9e\xf0\x9d\x85\x9f"); 2462 #endif 2463 CharData storage; 2464 2465 CharData_Init(&storage); 2466 XML_SetUserData(parser, &storage); 2467 XML_SetCharacterDataHandler(parser, accumulate_characters); 2468 2469 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text) - 1, XML_TRUE) == XML_STATUS_ERROR) 2470 xml_failure(parser); 2471 CharData_CheckXMLChars(&storage, expected); 2472 } 2473 END_TEST 2474 2475 /* Test that an element name with a UTF-16 surrogate pair is rejected */ 2476 START_TEST(test_utf16_bad_surrogate_pair) 2477 { 2478 /* Test data is: 2479 * <?xml version='1.0' encoding='utf-16'?> 2480 * <a><![CDATA[{BADLINB}]]></a> 2481 * 2482 * where {BADLINB} is U+10000 (the first Linear B character) 2483 * with the UTF-16 surrogate pair in the wrong order, i.e. 2484 * 0xdc00 0xd800 2485 */ 2486 const char text[] = 2487 "\0<\0?\0x\0m\0l\0" 2488 " \0v\0e\0r\0s\0i\0o\0n\0=\0'\0\x31\0.\0\x30\0'\0" 2489 " \0e\0n\0c\0o\0d\0i\0n\0g\0=\0'\0u\0t\0f\0-\0""1\0""6\0'" 2490 "\0?\0>\0\n" 2491 "\0<\0a\0>\0<\0!\0[\0C\0D\0A\0T\0A\0[" 2492 "\xdc\x00\xd8\x00" 2493 "\0]\0]\0>\0<\0/\0a\0>"; 2494 2495 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text) - 1, 2496 XML_TRUE) != XML_STATUS_ERROR) 2497 fail("Reversed UTF-16 surrogate pair not faulted"); 2498 if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_TOKEN) 2499 xml_failure(parser); 2500 } 2501 END_TEST 2502 2503 2504 START_TEST(test_bad_cdata) 2505 { 2506 struct CaseData { 2507 const char *text; 2508 enum XML_Error expectedError; 2509 }; 2510 2511 struct CaseData cases[] = { 2512 {"<a><", XML_ERROR_UNCLOSED_TOKEN}, 2513 {"<a><!", XML_ERROR_UNCLOSED_TOKEN}, 2514 {"<a><![", XML_ERROR_UNCLOSED_TOKEN}, 2515 {"<a><![C", XML_ERROR_UNCLOSED_TOKEN}, 2516 {"<a><![CD", XML_ERROR_UNCLOSED_TOKEN}, 2517 {"<a><![CDA", XML_ERROR_UNCLOSED_TOKEN}, 2518 {"<a><![CDAT", XML_ERROR_UNCLOSED_TOKEN}, 2519 {"<a><![CDATA", XML_ERROR_UNCLOSED_TOKEN}, 2520 2521 {"<a><![CDATA[", XML_ERROR_UNCLOSED_CDATA_SECTION}, 2522 {"<a><![CDATA[]", XML_ERROR_UNCLOSED_CDATA_SECTION}, 2523 {"<a><![CDATA[]]", XML_ERROR_UNCLOSED_CDATA_SECTION}, 2524 2525 {"<a><!<a/>", XML_ERROR_INVALID_TOKEN}, 2526 {"<a><![<a/>", XML_ERROR_UNCLOSED_TOKEN}, /* ?! */ 2527 {"<a><![C<a/>", XML_ERROR_UNCLOSED_TOKEN}, /* ?! */ 2528 {"<a><![CD<a/>", XML_ERROR_INVALID_TOKEN}, 2529 {"<a><![CDA<a/>", XML_ERROR_INVALID_TOKEN}, 2530 {"<a><![CDAT<a/>", XML_ERROR_INVALID_TOKEN}, 2531 {"<a><![CDATA<a/>", XML_ERROR_INVALID_TOKEN}, 2532 2533 {"<a><![CDATA[<a/>", XML_ERROR_UNCLOSED_CDATA_SECTION}, 2534 {"<a><![CDATA[]<a/>", XML_ERROR_UNCLOSED_CDATA_SECTION}, 2535 {"<a><![CDATA[]]<a/>", XML_ERROR_UNCLOSED_CDATA_SECTION} 2536 }; 2537 2538 size_t i = 0; 2539 for (; i < sizeof(cases) / sizeof(struct CaseData); i++) { 2540 const enum XML_Status actualStatus = _XML_Parse_SINGLE_BYTES( 2541 parser, cases[i].text, (int)strlen(cases[i].text), XML_TRUE); 2542 const enum XML_Error actualError = XML_GetErrorCode(parser); 2543 2544 assert(actualStatus == XML_STATUS_ERROR); 2545 2546 if (actualError != cases[i].expectedError) { 2547 char message[100]; 2548 sprintf(message, "Expected error %d but got error %d for case %u: \"%s\"\n", 2549 cases[i].expectedError, actualError, (unsigned int)i + 1, cases[i].text); 2550 fail(message); 2551 } 2552 2553 XML_ParserReset(parser, NULL); 2554 } 2555 } 2556 END_TEST 2557 2558 /* Test failures in UTF-16 CDATA */ 2559 START_TEST(test_bad_cdata_utf16) 2560 { 2561 struct CaseData { 2562 size_t text_bytes; 2563 const char *text; 2564 enum XML_Error expected_error; 2565 }; 2566 2567 const char prolog[] = 2568 "\0<\0?\0x\0m\0l\0" 2569 " \0v\0e\0r\0s\0i\0o\0n\0=\0'\0\x31\0.\0\x30\0'\0" 2570 " \0e\0n\0c\0o\0d\0i\0n\0g\0=\0'\0u\0t\0f\0-\0""1\0""6\0'" 2571 "\0?\0>\0\n" 2572 "\0<\0a\0>"; 2573 struct CaseData cases[] = { 2574 {1, "\0", XML_ERROR_UNCLOSED_TOKEN}, 2575 {2, "\0<", XML_ERROR_UNCLOSED_TOKEN}, 2576 {3, "\0<\0", XML_ERROR_UNCLOSED_TOKEN}, 2577 {4, "\0<\0!", XML_ERROR_UNCLOSED_TOKEN}, 2578 {5, "\0<\0!\0", XML_ERROR_UNCLOSED_TOKEN}, 2579 {6, "\0<\0!\0[", XML_ERROR_UNCLOSED_TOKEN}, 2580 {7, "\0<\0!\0[\0", XML_ERROR_UNCLOSED_TOKEN}, 2581 {8, "\0<\0!\0[\0C", XML_ERROR_UNCLOSED_TOKEN}, 2582 {9, "\0<\0!\0[\0C\0", XML_ERROR_UNCLOSED_TOKEN}, 2583 {10, "\0<\0!\0[\0C\0D", XML_ERROR_UNCLOSED_TOKEN}, 2584 {11, "\0<\0!\0[\0C\0D\0", XML_ERROR_UNCLOSED_TOKEN}, 2585 {12, "\0<\0!\0[\0C\0D\0A", XML_ERROR_UNCLOSED_TOKEN}, 2586 {13, "\0<\0!\0[\0C\0D\0A\0", XML_ERROR_UNCLOSED_TOKEN}, 2587 {14, "\0<\0!\0[\0C\0D\0A\0T", XML_ERROR_UNCLOSED_TOKEN}, 2588 {15, "\0<\0!\0[\0C\0D\0A\0T\0", XML_ERROR_UNCLOSED_TOKEN}, 2589 {16, "\0<\0!\0[\0C\0D\0A\0T\0A", XML_ERROR_UNCLOSED_TOKEN}, 2590 {17, "\0<\0!\0[\0C\0D\0A\0T\0A\0", XML_ERROR_UNCLOSED_TOKEN}, 2591 {18, "\0<\0!\0[\0C\0D\0A\0T\0A\0[", 2592 XML_ERROR_UNCLOSED_CDATA_SECTION}, 2593 {19, "\0<\0!\0[\0C\0D\0A\0T\0A\0[\0", 2594 XML_ERROR_UNCLOSED_CDATA_SECTION}, 2595 {20, "\0<\0!\0[\0C\0D\0A\0T\0A\0[\0Z", 2596 XML_ERROR_UNCLOSED_CDATA_SECTION}, 2597 /* Now add a four-byte UTF-16 character */ 2598 {21, "\0<\0!\0[\0C\0D\0A\0T\0A\0[\0Z\xd8", 2599 XML_ERROR_UNCLOSED_CDATA_SECTION}, 2600 {22, "\0<\0!\0[\0C\0D\0A\0T\0A\0[\0Z\xd8\x34", 2601 XML_ERROR_PARTIAL_CHAR}, 2602 {23, "\0<\0!\0[\0C\0D\0A\0T\0A\0[\0Z\xd8\x34\xdd", 2603 XML_ERROR_PARTIAL_CHAR}, 2604 {24, "\0<\0!\0[\0C\0D\0A\0T\0A\0[\0Z\xd8\x34\xdd\x5e", 2605 XML_ERROR_UNCLOSED_CDATA_SECTION} 2606 }; 2607 size_t i; 2608 2609 for (i = 0; i < sizeof(cases)/sizeof(struct CaseData); i++) { 2610 enum XML_Status actual_status; 2611 enum XML_Error actual_error; 2612 2613 if (_XML_Parse_SINGLE_BYTES(parser, prolog, (int)sizeof(prolog)-1, 2614 XML_FALSE) == XML_STATUS_ERROR) 2615 xml_failure(parser); 2616 actual_status = _XML_Parse_SINGLE_BYTES(parser, 2617 cases[i].text, 2618 (int)cases[i].text_bytes, 2619 XML_TRUE); 2620 assert(actual_status == XML_STATUS_ERROR); 2621 actual_error = XML_GetErrorCode(parser); 2622 if (actual_error != cases[i].expected_error) { 2623 char message[1024]; 2624 2625 sprintf(message, 2626 "Expected error %d (%" XML_FMT_STR 2627 "), got %d (%" XML_FMT_STR ") for case %lu\n", 2628 cases[i].expected_error, 2629 XML_ErrorString(cases[i].expected_error), 2630 actual_error, 2631 XML_ErrorString(actual_error), 2632 (long unsigned)(i+1)); 2633 fail(message); 2634 } 2635 XML_ParserReset(parser, NULL); 2636 } 2637 } 2638 END_TEST 2639 2640 static const char *long_cdata_text = 2641 "<s><![CDATA[" 2642 "012345678901234567890123456789012345678901234567890123456789" 2643 "012345678901234567890123456789012345678901234567890123456789" 2644 "012345678901234567890123456789012345678901234567890123456789" 2645 "012345678901234567890123456789012345678901234567890123456789" 2646 "012345678901234567890123456789012345678901234567890123456789" 2647 "012345678901234567890123456789012345678901234567890123456789" 2648 "012345678901234567890123456789012345678901234567890123456789" 2649 "012345678901234567890123456789012345678901234567890123456789" 2650 "012345678901234567890123456789012345678901234567890123456789" 2651 "012345678901234567890123456789012345678901234567890123456789" 2652 "012345678901234567890123456789012345678901234567890123456789" 2653 "012345678901234567890123456789012345678901234567890123456789" 2654 "012345678901234567890123456789012345678901234567890123456789" 2655 "012345678901234567890123456789012345678901234567890123456789" 2656 "012345678901234567890123456789012345678901234567890123456789" 2657 "012345678901234567890123456789012345678901234567890123456789" 2658 "012345678901234567890123456789012345678901234567890123456789" 2659 "012345678901234567890123456789012345678901234567890123456789" 2660 "012345678901234567890123456789012345678901234567890123456789" 2661 "012345678901234567890123456789012345678901234567890123456789" 2662 "]]></s>"; 2663 2664 /* Test stopping the parser in cdata handler */ 2665 START_TEST(test_stop_parser_between_cdata_calls) 2666 { 2667 const char *text = long_cdata_text; 2668 2669 XML_SetCharacterDataHandler(parser, 2670 clearing_aborting_character_handler); 2671 resumable = XML_FALSE; 2672 expect_failure(text, XML_ERROR_ABORTED, 2673 "Parse not aborted in CDATA handler"); 2674 } 2675 END_TEST 2676 2677 /* Test suspending the parser in cdata handler */ 2678 START_TEST(test_suspend_parser_between_cdata_calls) 2679 { 2680 const char *text = long_cdata_text; 2681 enum XML_Status result; 2682 2683 XML_SetCharacterDataHandler(parser, 2684 clearing_aborting_character_handler); 2685 resumable = XML_TRUE; 2686 result = _XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE); 2687 if (result != XML_STATUS_SUSPENDED) { 2688 if (result == XML_STATUS_ERROR) 2689 xml_failure(parser); 2690 fail("Parse not suspended in CDATA handler"); 2691 } 2692 if (XML_GetErrorCode(parser) != XML_ERROR_NONE) 2693 xml_failure(parser); 2694 } 2695 END_TEST 2696 2697 /* Test memory allocation functions */ 2698 START_TEST(test_memory_allocation) 2699 { 2700 char *buffer = (char *)XML_MemMalloc(parser, 256); 2701 char *p; 2702 2703 if (buffer == NULL) { 2704 fail("Allocation failed"); 2705 } else { 2706 /* Try writing to memory; some OSes try to cheat! */ 2707 buffer[0] = 'T'; 2708 buffer[1] = 'E'; 2709 buffer[2] = 'S'; 2710 buffer[3] = 'T'; 2711 buffer[4] = '\0'; 2712 if (strcmp(buffer, "TEST") != 0) { 2713 fail("Memory not writable"); 2714 } else { 2715 p = (char *)XML_MemRealloc(parser, buffer, 512); 2716 if (p == NULL) { 2717 fail("Reallocation failed"); 2718 } else { 2719 /* Write again, just to be sure */ 2720 buffer = p; 2721 buffer[0] = 'V'; 2722 if (strcmp(buffer, "VEST") != 0) { 2723 fail("Reallocated memory not writable"); 2724 } 2725 } 2726 } 2727 XML_MemFree(parser, buffer); 2728 } 2729 } 2730 END_TEST 2731 2732 static void XMLCALL 2733 record_default_handler(void *userData, 2734 const XML_Char *UNUSED_P(s), 2735 int UNUSED_P(len)) 2736 { 2737 CharData_AppendXMLChars((CharData *)userData, XCS("D"), 1); 2738 } 2739 2740 static void XMLCALL 2741 record_cdata_handler(void *userData, 2742 const XML_Char *UNUSED_P(s), 2743 int UNUSED_P(len)) 2744 { 2745 CharData_AppendXMLChars((CharData *)userData, XCS("C"), 1); 2746 XML_DefaultCurrent(parser); 2747 } 2748 2749 static void XMLCALL 2750 record_cdata_nodefault_handler(void *userData, 2751 const XML_Char *UNUSED_P(s), 2752 int UNUSED_P(len)) 2753 { 2754 CharData_AppendXMLChars((CharData *)userData, XCS("c"), 1); 2755 } 2756 2757 static void XMLCALL 2758 record_skip_handler(void *userData, 2759 const XML_Char *UNUSED_P(entityName), 2760 int is_parameter_entity) 2761 { 2762 CharData_AppendXMLChars((CharData *)userData, 2763 is_parameter_entity ? XCS("E") : XCS("e"), 1); 2764 } 2765 2766 /* Test XML_DefaultCurrent() passes handling on correctly */ 2767 START_TEST(test_default_current) 2768 { 2769 const char *text = "<doc>hell]</doc>"; 2770 const char *entity_text = 2771 "<!DOCTYPE doc [\n" 2772 "<!ENTITY entity '%'>\n" 2773 "]>\n" 2774 "<doc>&entity;</doc>"; 2775 CharData storage; 2776 2777 XML_SetDefaultHandler(parser, record_default_handler); 2778 XML_SetCharacterDataHandler(parser, record_cdata_handler); 2779 CharData_Init(&storage); 2780 XML_SetUserData(parser, &storage); 2781 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 2782 XML_TRUE) == XML_STATUS_ERROR) 2783 xml_failure(parser); 2784 CharData_CheckXMLChars(&storage, XCS("DCDCDCDCDCDD")); 2785 2786 /* Again, without the defaulting */ 2787 XML_ParserReset(parser, NULL); 2788 XML_SetDefaultHandler(parser, record_default_handler); 2789 XML_SetCharacterDataHandler(parser, record_cdata_nodefault_handler); 2790 CharData_Init(&storage); 2791 XML_SetUserData(parser, &storage); 2792 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 2793 XML_TRUE) == XML_STATUS_ERROR) 2794 xml_failure(parser); 2795 CharData_CheckXMLChars(&storage, XCS("DcccccD")); 2796 2797 /* Now with an internal entity to complicate matters */ 2798 XML_ParserReset(parser, NULL); 2799 XML_SetDefaultHandler(parser, record_default_handler); 2800 XML_SetCharacterDataHandler(parser, record_cdata_handler); 2801 CharData_Init(&storage); 2802 XML_SetUserData(parser, &storage); 2803 if (_XML_Parse_SINGLE_BYTES(parser, entity_text, (int)strlen(entity_text), 2804 XML_TRUE) == XML_STATUS_ERROR) 2805 xml_failure(parser); 2806 /* The default handler suppresses the entity */ 2807 CharData_CheckXMLChars(&storage, XCS("DDDDDDDDDDDDDDDDDDD")); 2808 2809 /* Again, with a skip handler */ 2810 XML_ParserReset(parser, NULL); 2811 XML_SetDefaultHandler(parser, record_default_handler); 2812 XML_SetCharacterDataHandler(parser, record_cdata_handler); 2813 XML_SetSkippedEntityHandler(parser, record_skip_handler); 2814 CharData_Init(&storage); 2815 XML_SetUserData(parser, &storage); 2816 if (_XML_Parse_SINGLE_BYTES(parser, entity_text, (int)strlen(entity_text), 2817 XML_TRUE) == XML_STATUS_ERROR) 2818 xml_failure(parser); 2819 /* The default handler suppresses the entity */ 2820 CharData_CheckXMLChars(&storage, XCS("DDDDDDDDDDDDDDDDDeD")); 2821 2822 /* This time, allow the entity through */ 2823 XML_ParserReset(parser, NULL); 2824 XML_SetDefaultHandlerExpand(parser, record_default_handler); 2825 XML_SetCharacterDataHandler(parser, record_cdata_handler); 2826 CharData_Init(&storage); 2827 XML_SetUserData(parser, &storage); 2828 if (_XML_Parse_SINGLE_BYTES(parser, entity_text, (int)strlen(entity_text), 2829 XML_TRUE) == XML_STATUS_ERROR) 2830 xml_failure(parser); 2831 CharData_CheckXMLChars(&storage, XCS("DDDDDDDDDDDDDDDDDCDD")); 2832 2833 /* Finally, without passing the cdata to the default handler */ 2834 XML_ParserReset(parser, NULL); 2835 XML_SetDefaultHandlerExpand(parser, record_default_handler); 2836 XML_SetCharacterDataHandler(parser, record_cdata_nodefault_handler); 2837 CharData_Init(&storage); 2838 XML_SetUserData(parser, &storage); 2839 if (_XML_Parse_SINGLE_BYTES(parser, entity_text, (int)strlen(entity_text), 2840 XML_TRUE) == XML_STATUS_ERROR) 2841 xml_failure(parser); 2842 CharData_CheckXMLChars(&storage, XCS("DDDDDDDDDDDDDDDDDcD")); 2843 } 2844 END_TEST 2845 2846 /* Test DTD element parsing code paths */ 2847 START_TEST(test_dtd_elements) 2848 { 2849 const char *text = 2850 "<!DOCTYPE doc [\n" 2851 "<!ELEMENT doc (chapter)>\n" 2852 "<!ELEMENT chapter (#PCDATA)>\n" 2853 "]>\n" 2854 "<doc><chapter>Wombats are go</chapter></doc>"; 2855 2856 XML_SetElementDeclHandler(parser, dummy_element_decl_handler); 2857 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 2858 XML_TRUE) == XML_STATUS_ERROR) 2859 xml_failure(parser); 2860 } 2861 END_TEST 2862 2863 /* Test foreign DTD handling */ 2864 START_TEST(test_set_foreign_dtd) 2865 { 2866 const char *text1 = 2867 "<?xml version='1.0' encoding='us-ascii'?>\n"; 2868 const char *text2 = 2869 "<doc>&entity;</doc>"; 2870 ExtTest test_data = { 2871 "<!ELEMENT doc (#PCDATA)*>", 2872 NULL, 2873 NULL 2874 }; 2875 2876 /* Check hash salt is passed through too */ 2877 XML_SetHashSalt(parser, 0x12345678); 2878 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 2879 XML_SetUserData(parser, &test_data); 2880 XML_SetExternalEntityRefHandler(parser, external_entity_loader); 2881 /* Add a default handler to exercise more code paths */ 2882 XML_SetDefaultHandler(parser, dummy_default_handler); 2883 if (XML_UseForeignDTD(parser, XML_TRUE) != XML_ERROR_NONE) 2884 fail("Could not set foreign DTD"); 2885 if (_XML_Parse_SINGLE_BYTES(parser, text1, (int)strlen(text1), 2886 XML_FALSE) == XML_STATUS_ERROR) 2887 xml_failure(parser); 2888 2889 /* Ensure that trying to set the DTD after parsing has started 2890 * is faulted, even if it's the same setting. 2891 */ 2892 if (XML_UseForeignDTD(parser, XML_TRUE) != 2893 XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING) 2894 fail("Failed to reject late foreign DTD setting"); 2895 /* Ditto for the hash salt */ 2896 if (XML_SetHashSalt(parser, 0x23456789)) 2897 fail("Failed to reject late hash salt change"); 2898 2899 /* Now finish the parse */ 2900 if (_XML_Parse_SINGLE_BYTES(parser, text2, (int)strlen(text2), 2901 XML_TRUE) == XML_STATUS_ERROR) 2902 xml_failure(parser); 2903 } 2904 END_TEST 2905 2906 /* Test foreign DTD handling with a failing NotStandalone handler */ 2907 START_TEST(test_foreign_dtd_not_standalone) 2908 { 2909 const char *text = 2910 "<?xml version='1.0' encoding='us-ascii'?>\n" 2911 "<doc>&entity;</doc>"; 2912 ExtTest test_data = { 2913 "<!ELEMENT doc (#PCDATA)*>", 2914 NULL, 2915 NULL 2916 }; 2917 2918 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 2919 XML_SetUserData(parser, &test_data); 2920 XML_SetExternalEntityRefHandler(parser, external_entity_loader); 2921 XML_SetNotStandaloneHandler(parser, reject_not_standalone_handler); 2922 if (XML_UseForeignDTD(parser, XML_TRUE) != XML_ERROR_NONE) 2923 fail("Could not set foreign DTD"); 2924 expect_failure(text, XML_ERROR_NOT_STANDALONE, 2925 "NotStandalonehandler failed to reject"); 2926 } 2927 END_TEST 2928 2929 /* Test invalid character in a foreign DTD is faulted */ 2930 START_TEST(test_invalid_foreign_dtd) 2931 { 2932 const char *text = 2933 "<?xml version='1.0' encoding='us-ascii'?>\n" 2934 "<doc>&entity;</doc>"; 2935 ExtFaults test_data = { 2936 "$", 2937 "Dollar not faulted", 2938 NULL, 2939 XML_ERROR_INVALID_TOKEN 2940 }; 2941 2942 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 2943 XML_SetUserData(parser, &test_data); 2944 XML_SetExternalEntityRefHandler(parser, external_entity_faulter); 2945 XML_UseForeignDTD(parser, XML_TRUE); 2946 expect_failure(text, 2947 XML_ERROR_EXTERNAL_ENTITY_HANDLING, 2948 "Bad DTD should not have been accepted"); 2949 } 2950 END_TEST 2951 2952 /* Test foreign DTD use with a doctype */ 2953 START_TEST(test_foreign_dtd_with_doctype) 2954 { 2955 const char *text1 = 2956 "<?xml version='1.0' encoding='us-ascii'?>\n" 2957 "<!DOCTYPE doc [<!ENTITY entity 'hello world'>]>\n"; 2958 const char *text2 = 2959 "<doc>&entity;</doc>"; 2960 ExtTest test_data = { 2961 "<!ELEMENT doc (#PCDATA)*>", 2962 NULL, 2963 NULL 2964 }; 2965 2966 /* Check hash salt is passed through too */ 2967 XML_SetHashSalt(parser, 0x12345678); 2968 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 2969 XML_SetUserData(parser, &test_data); 2970 XML_SetExternalEntityRefHandler(parser, external_entity_loader); 2971 /* Add a default handler to exercise more code paths */ 2972 XML_SetDefaultHandler(parser, dummy_default_handler); 2973 if (XML_UseForeignDTD(parser, XML_TRUE) != XML_ERROR_NONE) 2974 fail("Could not set foreign DTD"); 2975 if (_XML_Parse_SINGLE_BYTES(parser, text1, (int)strlen(text1), 2976 XML_FALSE) == XML_STATUS_ERROR) 2977 xml_failure(parser); 2978 2979 /* Ensure that trying to set the DTD after parsing has started 2980 * is faulted, even if it's the same setting. 2981 */ 2982 if (XML_UseForeignDTD(parser, XML_TRUE) != 2983 XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING) 2984 fail("Failed to reject late foreign DTD setting"); 2985 /* Ditto for the hash salt */ 2986 if (XML_SetHashSalt(parser, 0x23456789)) 2987 fail("Failed to reject late hash salt change"); 2988 2989 /* Now finish the parse */ 2990 if (_XML_Parse_SINGLE_BYTES(parser, text2, (int)strlen(text2), 2991 XML_TRUE) == XML_STATUS_ERROR) 2992 xml_failure(parser); 2993 } 2994 END_TEST 2995 2996 /* Test XML_UseForeignDTD with no external subset present */ 2997 static int XMLCALL 2998 external_entity_null_loader(XML_Parser UNUSED_P(parser), 2999 const XML_Char *UNUSED_P(context), 3000 const XML_Char *UNUSED_P(base), 3001 const XML_Char *UNUSED_P(systemId), 3002 const XML_Char *UNUSED_P(publicId)) 3003 { 3004 return XML_STATUS_OK; 3005 } 3006 3007 START_TEST(test_foreign_dtd_without_external_subset) 3008 { 3009 const char *text = 3010 "<!DOCTYPE doc [<!ENTITY foo 'bar'>]>\n" 3011 "<doc>&foo;</doc>"; 3012 3013 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 3014 XML_SetUserData(parser, NULL); 3015 XML_SetExternalEntityRefHandler(parser, external_entity_null_loader); 3016 XML_UseForeignDTD(parser, XML_TRUE); 3017 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 3018 XML_TRUE) == XML_STATUS_ERROR) 3019 xml_failure(parser); 3020 } 3021 END_TEST 3022 3023 START_TEST(test_empty_foreign_dtd) 3024 { 3025 const char *text = 3026 "<?xml version='1.0' encoding='us-ascii'?>\n" 3027 "<doc>&entity;</doc>"; 3028 3029 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 3030 XML_SetExternalEntityRefHandler(parser, external_entity_null_loader); 3031 XML_UseForeignDTD(parser, XML_TRUE); 3032 expect_failure(text, XML_ERROR_UNDEFINED_ENTITY, 3033 "Undefined entity not faulted"); 3034 } 3035 END_TEST 3036 3037 /* Test XML Base is set and unset appropriately */ 3038 START_TEST(test_set_base) 3039 { 3040 const XML_Char *old_base; 3041 const XML_Char *new_base = XCS("/local/file/name.xml"); 3042 3043 old_base = XML_GetBase(parser); 3044 if (XML_SetBase(parser, new_base) != XML_STATUS_OK) 3045 fail("Unable to set base"); 3046 if (xcstrcmp(XML_GetBase(parser), new_base) != 0) 3047 fail("Base setting not correct"); 3048 if (XML_SetBase(parser, NULL) != XML_STATUS_OK) 3049 fail("Unable to NULL base"); 3050 if (XML_GetBase(parser) != NULL) 3051 fail("Base setting not nulled"); 3052 XML_SetBase(parser, old_base); 3053 } 3054 END_TEST 3055 3056 /* Test attribute counts, indexing, etc */ 3057 typedef struct attrInfo { 3058 const XML_Char *name; 3059 const XML_Char *value; 3060 } AttrInfo; 3061 3062 typedef struct elementInfo { 3063 const XML_Char *name; 3064 int attr_count; 3065 const XML_Char *id_name; 3066 AttrInfo *attributes; 3067 } ElementInfo; 3068 3069 static void XMLCALL 3070 counting_start_element_handler(void *userData, 3071 const XML_Char *name, 3072 const XML_Char **atts) 3073 { 3074 ElementInfo *info = (ElementInfo *)userData; 3075 AttrInfo *attr; 3076 int count, id, i; 3077 3078 while (info->name != NULL) { 3079 if (!xcstrcmp(name, info->name)) 3080 break; 3081 info++; 3082 } 3083 if (info->name == NULL) 3084 fail("Element not recognised"); 3085 /* The attribute count is twice what you might expect. It is a 3086 * count of items in atts, an array which contains alternating 3087 * attribute names and attribute values. For the naive user this 3088 * is possibly a little unexpected, but it is what the 3089 * documentation in expat.h tells us to expect. 3090 */ 3091 count = XML_GetSpecifiedAttributeCount(parser); 3092 if (info->attr_count * 2 != count) { 3093 fail("Not got expected attribute count"); 3094 return; 3095 } 3096 id = XML_GetIdAttributeIndex(parser); 3097 if (id == -1 && info->id_name != NULL) { 3098 fail("ID not present"); 3099 return; 3100 } 3101 if (id != -1 && xcstrcmp(atts[id], info->id_name)) { 3102 fail("ID does not have the correct name"); 3103 return; 3104 } 3105 for (i = 0; i < info->attr_count; i++) { 3106 attr = info->attributes; 3107 while (attr->name != NULL) { 3108 if (!xcstrcmp(atts[0], attr->name)) 3109 break; 3110 attr++; 3111 } 3112 if (attr->name == NULL) { 3113 fail("Attribute not recognised"); 3114 return; 3115 } 3116 if (xcstrcmp(atts[1], attr->value)) { 3117 fail("Attribute has wrong value"); 3118 return; 3119 } 3120 /* Remember, two entries in atts per attribute (see above) */ 3121 atts += 2; 3122 } 3123 } 3124 3125 START_TEST(test_attributes) 3126 { 3127 const char *text = 3128 "<!DOCTYPE doc [\n" 3129 "<!ELEMENT doc (tag)>\n" 3130 "<!ATTLIST doc id ID #REQUIRED>\n" 3131 "]>" 3132 "<doc a='1' id='one' b='2'>" 3133 "<tag c='3'/>" 3134 "</doc>"; 3135 AttrInfo doc_info[] = { 3136 { XCS("a"), XCS("1") }, 3137 { XCS("b"), XCS("2") }, 3138 { XCS("id"), XCS("one") }, 3139 { NULL, NULL } 3140 }; 3141 AttrInfo tag_info[] = { 3142 { XCS("c"), XCS("3") }, 3143 { NULL, NULL } 3144 }; 3145 ElementInfo info[] = { 3146 { XCS("doc"), 3, XCS("id"), NULL }, 3147 { XCS("tag"), 1, NULL, NULL }, 3148 { NULL, 0, NULL, NULL } 3149 }; 3150 info[0].attributes = doc_info; 3151 info[1].attributes = tag_info; 3152 3153 XML_SetStartElementHandler(parser, counting_start_element_handler); 3154 XML_SetUserData(parser, info); 3155 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR) 3156 xml_failure(parser); 3157 } 3158 END_TEST 3159 3160 /* Test reset works correctly in the middle of processing an internal 3161 * entity. Exercises some obscure code in XML_ParserReset(). 3162 */ 3163 START_TEST(test_reset_in_entity) 3164 { 3165 const char *text = 3166 "<!DOCTYPE doc [\n" 3167 "<!ENTITY wombat 'wom'>\n" 3168 "<!ENTITY entity 'hi &wom; there'>\n" 3169 "]>\n" 3170 "<doc>&entity;</doc>"; 3171 XML_ParsingStatus status; 3172 3173 resumable = XML_TRUE; 3174 XML_SetCharacterDataHandler(parser, clearing_aborting_character_handler); 3175 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_FALSE) == XML_STATUS_ERROR) 3176 xml_failure(parser); 3177 XML_GetParsingStatus(parser, &status); 3178 if (status.parsing != XML_SUSPENDED) 3179 fail("Parsing status not SUSPENDED"); 3180 XML_ParserReset(parser, NULL); 3181 XML_GetParsingStatus(parser, &status); 3182 if (status.parsing != XML_INITIALIZED) 3183 fail("Parsing status doesn't reset to INITIALIZED"); 3184 } 3185 END_TEST 3186 3187 /* Test that resume correctly passes through parse errors */ 3188 START_TEST(test_resume_invalid_parse) 3189 { 3190 const char *text = "<doc>Hello</doc"; /* Missing closing wedge */ 3191 3192 resumable = XML_TRUE; 3193 XML_SetCharacterDataHandler(parser, 3194 clearing_aborting_character_handler); 3195 if (XML_Parse(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR) 3196 xml_failure(parser); 3197 if (XML_ResumeParser(parser) == XML_STATUS_OK) 3198 fail("Resumed invalid parse not faulted"); 3199 if (XML_GetErrorCode(parser) != XML_ERROR_UNCLOSED_TOKEN) 3200 fail("Invalid parse not correctly faulted"); 3201 } 3202 END_TEST 3203 3204 /* Test that re-suspended parses are correctly passed through */ 3205 START_TEST(test_resume_resuspended) 3206 { 3207 const char *text = "<doc>Hello<meep/>world</doc>"; 3208 3209 resumable = XML_TRUE; 3210 XML_SetCharacterDataHandler(parser, 3211 clearing_aborting_character_handler); 3212 if (XML_Parse(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR) 3213 xml_failure(parser); 3214 resumable = XML_TRUE; 3215 XML_SetCharacterDataHandler(parser, 3216 clearing_aborting_character_handler); 3217 if (XML_ResumeParser(parser) != XML_STATUS_SUSPENDED) 3218 fail("Resumption not suspended"); 3219 /* This one should succeed and finish up */ 3220 if (XML_ResumeParser(parser) != XML_STATUS_OK) 3221 xml_failure(parser); 3222 } 3223 END_TEST 3224 3225 /* Test that CDATA shows up correctly through a default handler */ 3226 START_TEST(test_cdata_default) 3227 { 3228 const char *text = "<doc><![CDATA[Hello\nworld]]></doc>"; 3229 const XML_Char *expected = XCS("<doc><![CDATA[Hello\nworld]]></doc>"); 3230 CharData storage; 3231 3232 CharData_Init(&storage); 3233 XML_SetUserData(parser, &storage); 3234 XML_SetDefaultHandler(parser, accumulate_characters); 3235 3236 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 3237 XML_TRUE) == XML_STATUS_ERROR) 3238 xml_failure(parser); 3239 CharData_CheckXMLChars(&storage, expected); 3240 } 3241 END_TEST 3242 3243 /* Test resetting a subordinate parser does exactly nothing */ 3244 static int XMLCALL 3245 external_entity_resetter(XML_Parser parser, 3246 const XML_Char *context, 3247 const XML_Char *UNUSED_P(base), 3248 const XML_Char *UNUSED_P(systemId), 3249 const XML_Char *UNUSED_P(publicId)) 3250 { 3251 const char *text = "<!ELEMENT doc (#PCDATA)*>"; 3252 XML_Parser ext_parser; 3253 XML_ParsingStatus status; 3254 3255 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 3256 if (ext_parser == NULL) 3257 fail("Could not create external entity parser"); 3258 XML_GetParsingStatus(ext_parser, &status); 3259 if (status.parsing != XML_INITIALIZED) { 3260 fail("Parsing status is not INITIALIZED"); 3261 return XML_STATUS_ERROR; 3262 } 3263 if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), 3264 XML_TRUE) == XML_STATUS_ERROR) { 3265 xml_failure(parser); 3266 return XML_STATUS_ERROR; 3267 } 3268 XML_GetParsingStatus(ext_parser, &status); 3269 if (status.parsing != XML_FINISHED) { 3270 fail("Parsing status is not FINISHED"); 3271 return XML_STATUS_ERROR; 3272 } 3273 /* Check we can't parse here */ 3274 if (XML_Parse(ext_parser, text, (int)strlen(text), 3275 XML_TRUE) != XML_STATUS_ERROR) 3276 fail("Parsing when finished not faulted"); 3277 if (XML_GetErrorCode(ext_parser) != XML_ERROR_FINISHED) 3278 fail("Parsing when finished faulted with wrong code"); 3279 XML_ParserReset(ext_parser, NULL); 3280 XML_GetParsingStatus(ext_parser, &status); 3281 if (status.parsing != XML_FINISHED) { 3282 fail("Parsing status not still FINISHED"); 3283 return XML_STATUS_ERROR; 3284 } 3285 XML_ParserFree(ext_parser); 3286 return XML_STATUS_OK; 3287 } 3288 3289 START_TEST(test_subordinate_reset) 3290 { 3291 const char *text = 3292 "<?xml version='1.0' encoding='us-ascii'?>\n" 3293 "<!DOCTYPE doc SYSTEM 'foo'>\n" 3294 "<doc>&entity;</doc>"; 3295 3296 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 3297 XML_SetExternalEntityRefHandler(parser, external_entity_resetter); 3298 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR) 3299 xml_failure(parser); 3300 } 3301 END_TEST 3302 3303 3304 /* Test suspending a subordinate parser */ 3305 3306 static void XMLCALL 3307 entity_suspending_decl_handler(void *userData, 3308 const XML_Char *UNUSED_P(name), 3309 XML_Content *model) 3310 { 3311 XML_Parser ext_parser = (XML_Parser)userData; 3312 3313 if (XML_StopParser(ext_parser, XML_TRUE) != XML_STATUS_ERROR) 3314 fail("Attempting to suspend a subordinate parser not faulted"); 3315 if (XML_GetErrorCode(ext_parser) != XML_ERROR_SUSPEND_PE) 3316 fail("Suspending subordinate parser get wrong code"); 3317 XML_SetElementDeclHandler(ext_parser, NULL); 3318 XML_FreeContentModel(parser, model); 3319 } 3320 3321 static int XMLCALL 3322 external_entity_suspender(XML_Parser parser, 3323 const XML_Char *context, 3324 const XML_Char *UNUSED_P(base), 3325 const XML_Char *UNUSED_P(systemId), 3326 const XML_Char *UNUSED_P(publicId)) 3327 { 3328 const char *text = "<!ELEMENT doc (#PCDATA)*>"; 3329 XML_Parser ext_parser; 3330 3331 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 3332 if (ext_parser == NULL) 3333 fail("Could not create external entity parser"); 3334 XML_SetElementDeclHandler(ext_parser, entity_suspending_decl_handler); 3335 XML_SetUserData(ext_parser, ext_parser); 3336 if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), 3337 XML_TRUE) == XML_STATUS_ERROR) { 3338 xml_failure(ext_parser); 3339 return XML_STATUS_ERROR; 3340 } 3341 XML_ParserFree(ext_parser); 3342 return XML_STATUS_OK; 3343 } 3344 3345 START_TEST(test_subordinate_suspend) 3346 { 3347 const char *text = 3348 "<?xml version='1.0' encoding='us-ascii'?>\n" 3349 "<!DOCTYPE doc SYSTEM 'foo'>\n" 3350 "<doc>&entity;</doc>"; 3351 3352 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 3353 XML_SetExternalEntityRefHandler(parser, external_entity_suspender); 3354 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR) 3355 xml_failure(parser); 3356 } 3357 END_TEST 3358 3359 /* Test suspending a subordinate parser from an XML declaration */ 3360 /* Increases code coverage of the tests */ 3361 static void XMLCALL 3362 entity_suspending_xdecl_handler(void *userData, 3363 const XML_Char *UNUSED_P(version), 3364 const XML_Char *UNUSED_P(encoding), 3365 int UNUSED_P(standalone)) 3366 { 3367 XML_Parser ext_parser = (XML_Parser)userData; 3368 3369 XML_StopParser(ext_parser, resumable); 3370 XML_SetXmlDeclHandler(ext_parser, NULL); 3371 } 3372 3373 static int XMLCALL 3374 external_entity_suspend_xmldecl(XML_Parser parser, 3375 const XML_Char *context, 3376 const XML_Char *UNUSED_P(base), 3377 const XML_Char *UNUSED_P(systemId), 3378 const XML_Char *UNUSED_P(publicId)) 3379 { 3380 const char *text = "<?xml version='1.0' encoding='us-ascii'?>"; 3381 XML_Parser ext_parser; 3382 XML_ParsingStatus status; 3383 enum XML_Status rc; 3384 3385 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 3386 if (ext_parser == NULL) 3387 fail("Could not create external entity parser"); 3388 XML_SetXmlDeclHandler(ext_parser, entity_suspending_xdecl_handler); 3389 XML_SetUserData(ext_parser, ext_parser); 3390 rc = _XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE); 3391 XML_GetParsingStatus(ext_parser, &status); 3392 if (resumable) { 3393 if (rc == XML_STATUS_ERROR) 3394 xml_failure(ext_parser); 3395 if (status.parsing != XML_SUSPENDED) 3396 fail("Ext Parsing status not SUSPENDED"); 3397 } else { 3398 if (rc != XML_STATUS_ERROR) 3399 fail("Ext parsing not aborted"); 3400 if (XML_GetErrorCode(ext_parser) != XML_ERROR_ABORTED) 3401 xml_failure(ext_parser); 3402 if (status.parsing != XML_FINISHED) 3403 fail("Ext Parsing status not FINISHED"); 3404 } 3405 3406 XML_ParserFree(ext_parser); 3407 return XML_STATUS_OK; 3408 } 3409 3410 START_TEST(test_subordinate_xdecl_suspend) 3411 { 3412 const char *text = 3413 "<!DOCTYPE doc [\n" 3414 " <!ENTITY entity SYSTEM 'http://example.org/dummy.ent'>\n" 3415 "]>\n" 3416 "<doc>&entity;</doc>"; 3417 3418 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 3419 XML_SetExternalEntityRefHandler(parser, 3420 external_entity_suspend_xmldecl); 3421 resumable = XML_TRUE; 3422 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 3423 XML_TRUE) == XML_STATUS_ERROR) 3424 xml_failure(parser); 3425 } 3426 END_TEST 3427 3428 START_TEST(test_subordinate_xdecl_abort) 3429 { 3430 const char *text = 3431 "<!DOCTYPE doc [\n" 3432 " <!ENTITY entity SYSTEM 'http://example.org/dummy.ent'>\n" 3433 "]>\n" 3434 "<doc>&entity;</doc>"; 3435 3436 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 3437 XML_SetExternalEntityRefHandler(parser, 3438 external_entity_suspend_xmldecl); 3439 resumable = XML_FALSE; 3440 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 3441 XML_TRUE) == XML_STATUS_ERROR) 3442 xml_failure(parser); 3443 } 3444 END_TEST 3445 3446 /* Test external entity fault handling with suspension */ 3447 static int XMLCALL 3448 external_entity_suspending_faulter(XML_Parser parser, 3449 const XML_Char *context, 3450 const XML_Char *UNUSED_P(base), 3451 const XML_Char *UNUSED_P(systemId), 3452 const XML_Char *UNUSED_P(publicId)) 3453 { 3454 XML_Parser ext_parser; 3455 ExtFaults *fault = (ExtFaults *)XML_GetUserData(parser); 3456 void *buffer; 3457 int parse_len = (int)strlen(fault->parse_text); 3458 3459 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 3460 if (ext_parser == NULL) 3461 fail("Could not create external entity parser"); 3462 XML_SetXmlDeclHandler(ext_parser, entity_suspending_xdecl_handler); 3463 XML_SetUserData(ext_parser, ext_parser); 3464 resumable = XML_TRUE; 3465 buffer = XML_GetBuffer(ext_parser, parse_len); 3466 if (buffer == NULL) 3467 fail("Could not allocate parse buffer"); 3468 memcpy(buffer, fault->parse_text, parse_len); 3469 if (XML_ParseBuffer(ext_parser, parse_len, 3470 XML_FALSE) != XML_STATUS_SUSPENDED) 3471 fail("XML declaration did not suspend"); 3472 if (XML_ResumeParser(ext_parser) != XML_STATUS_OK) 3473 xml_failure(ext_parser); 3474 if (XML_ParseBuffer(ext_parser, 0, XML_TRUE) != XML_STATUS_ERROR) 3475 fail(fault->fail_text); 3476 if (XML_GetErrorCode(ext_parser) != fault->error) 3477 xml_failure(ext_parser); 3478 3479 XML_ParserFree(ext_parser); 3480 return XML_STATUS_ERROR; 3481 } 3482 3483 START_TEST(test_ext_entity_invalid_suspended_parse) 3484 { 3485 const char *text = 3486 "<!DOCTYPE doc [\n" 3487 " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n" 3488 "]>\n" 3489 "<doc>&en;</doc>"; 3490 ExtFaults faults[] = { 3491 { 3492 "<?xml version='1.0' encoding='us-ascii'?><", 3493 "Incomplete element declaration not faulted", 3494 NULL, 3495 XML_ERROR_UNCLOSED_TOKEN 3496 }, 3497 { 3498 /* First two bytes of a three-byte char */ 3499 "<?xml version='1.0' encoding='utf-8'?>\xe2\x82", 3500 "Incomplete character not faulted", 3501 NULL, 3502 XML_ERROR_PARTIAL_CHAR 3503 }, 3504 { NULL, NULL, NULL, XML_ERROR_NONE } 3505 }; 3506 ExtFaults *fault; 3507 3508 for (fault = &faults[0]; fault->parse_text != NULL; fault++) { 3509 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 3510 XML_SetExternalEntityRefHandler(parser, 3511 external_entity_suspending_faulter); 3512 XML_SetUserData(parser, fault); 3513 expect_failure(text, 3514 XML_ERROR_EXTERNAL_ENTITY_HANDLING, 3515 "Parser did not report external entity error"); 3516 XML_ParserReset(parser, NULL); 3517 } 3518 } 3519 END_TEST 3520 3521 3522 3523 /* Test setting an explicit encoding */ 3524 START_TEST(test_explicit_encoding) 3525 { 3526 const char *text1 = "<doc>Hello "; 3527 const char *text2 = " World</doc>"; 3528 3529 /* Just check that we can set the encoding to NULL before starting */ 3530 if (XML_SetEncoding(parser, NULL) != XML_STATUS_OK) 3531 fail("Failed to initialise encoding to NULL"); 3532 /* Say we are UTF-8 */ 3533 if (XML_SetEncoding(parser, XCS("utf-8")) != XML_STATUS_OK) 3534 fail("Failed to set explicit encoding"); 3535 if (_XML_Parse_SINGLE_BYTES(parser, text1, (int)strlen(text1), 3536 XML_FALSE) == XML_STATUS_ERROR) 3537 xml_failure(parser); 3538 /* Try to switch encodings mid-parse */ 3539 if (XML_SetEncoding(parser, XCS("us-ascii")) != XML_STATUS_ERROR) 3540 fail("Allowed encoding change"); 3541 if (_XML_Parse_SINGLE_BYTES(parser, text2, (int)strlen(text2), 3542 XML_TRUE) == XML_STATUS_ERROR) 3543 xml_failure(parser); 3544 /* Try now the parse is over */ 3545 if (XML_SetEncoding(parser, NULL) != XML_STATUS_OK) 3546 fail("Failed to unset encoding"); 3547 } 3548 END_TEST 3549 3550 3551 /* Test handling of trailing CR (rather than newline) */ 3552 static void XMLCALL 3553 cr_cdata_handler(void *userData, const XML_Char *s, int len) 3554 { 3555 int *pfound = (int *)userData; 3556 3557 /* Internal processing turns the CR into a newline for the 3558 * character data handler, but not for the default handler 3559 */ 3560 if (len == 1 && (*s == XCS('\n') || *s == XCS('\r'))) 3561 *pfound = 1; 3562 } 3563 3564 START_TEST(test_trailing_cr) 3565 { 3566 const char *text = "<doc>\r"; 3567 int found_cr; 3568 3569 /* Try with a character handler, for code coverage */ 3570 XML_SetCharacterDataHandler(parser, cr_cdata_handler); 3571 XML_SetUserData(parser, &found_cr); 3572 found_cr = 0; 3573 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 3574 XML_TRUE) == XML_STATUS_OK) 3575 fail("Failed to fault unclosed doc"); 3576 if (found_cr == 0) 3577 fail("Did not catch the carriage return"); 3578 XML_ParserReset(parser, NULL); 3579 3580 /* Now with a default handler instead */ 3581 XML_SetDefaultHandler(parser, cr_cdata_handler); 3582 XML_SetUserData(parser, &found_cr); 3583 found_cr = 0; 3584 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 3585 XML_TRUE) == XML_STATUS_OK) 3586 fail("Failed to fault unclosed doc"); 3587 if (found_cr == 0) 3588 fail("Did not catch default carriage return"); 3589 } 3590 END_TEST 3591 3592 /* Test trailing CR in an external entity parse */ 3593 static int XMLCALL 3594 external_entity_cr_catcher(XML_Parser parser, 3595 const XML_Char *context, 3596 const XML_Char *UNUSED_P(base), 3597 const XML_Char *UNUSED_P(systemId), 3598 const XML_Char *UNUSED_P(publicId)) 3599 { 3600 const char *text = "\r"; 3601 XML_Parser ext_parser; 3602 3603 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 3604 if (ext_parser == NULL) 3605 fail("Could not create external entity parser"); 3606 XML_SetCharacterDataHandler(ext_parser, cr_cdata_handler); 3607 if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), 3608 XML_TRUE) == XML_STATUS_ERROR) 3609 xml_failure(ext_parser); 3610 XML_ParserFree(ext_parser); 3611 return XML_STATUS_OK; 3612 } 3613 3614 static int XMLCALL 3615 external_entity_bad_cr_catcher(XML_Parser parser, 3616 const XML_Char *context, 3617 const XML_Char *UNUSED_P(base), 3618 const XML_Char *UNUSED_P(systemId), 3619 const XML_Char *UNUSED_P(publicId)) 3620 { 3621 const char *text = "<tag>\r"; 3622 XML_Parser ext_parser; 3623 3624 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 3625 if (ext_parser == NULL) 3626 fail("Could not create external entity parser"); 3627 XML_SetCharacterDataHandler(ext_parser, cr_cdata_handler); 3628 if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), 3629 XML_TRUE) == XML_STATUS_OK) 3630 fail("Async entity error not caught"); 3631 if (XML_GetErrorCode(ext_parser) != XML_ERROR_ASYNC_ENTITY) 3632 xml_failure(ext_parser); 3633 XML_ParserFree(ext_parser); 3634 return XML_STATUS_OK; 3635 } 3636 3637 START_TEST(test_ext_entity_trailing_cr) 3638 { 3639 const char *text = 3640 "<!DOCTYPE doc [\n" 3641 " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n" 3642 "]>\n" 3643 "<doc>&en;</doc>"; 3644 int found_cr; 3645 3646 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 3647 XML_SetExternalEntityRefHandler(parser, external_entity_cr_catcher); 3648 XML_SetUserData(parser, &found_cr); 3649 found_cr = 0; 3650 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 3651 XML_TRUE) != XML_STATUS_OK) 3652 xml_failure(parser); 3653 if (found_cr == 0) 3654 fail("No carriage return found"); 3655 XML_ParserReset(parser, NULL); 3656 3657 /* Try again with a different trailing CR */ 3658 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 3659 XML_SetExternalEntityRefHandler(parser, external_entity_bad_cr_catcher); 3660 XML_SetUserData(parser, &found_cr); 3661 found_cr = 0; 3662 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 3663 XML_TRUE) != XML_STATUS_OK) 3664 xml_failure(parser); 3665 if (found_cr == 0) 3666 fail("No carriage return found"); 3667 } 3668 END_TEST 3669 3670 /* Test handling of trailing square bracket */ 3671 static void XMLCALL 3672 rsqb_handler(void *userData, const XML_Char *s, int len) 3673 { 3674 int *pfound = (int *)userData; 3675 3676 if (len == 1 && *s == XCS(']')) 3677 *pfound = 1; 3678 } 3679 3680 START_TEST(test_trailing_rsqb) 3681 { 3682 const char *text8 = "<doc>]"; 3683 const char text16[] = "\xFF\xFE<\000d\000o\000c\000>\000]\000"; 3684 int found_rsqb; 3685 int text8_len = (int)strlen(text8); 3686 3687 XML_SetCharacterDataHandler(parser, rsqb_handler); 3688 XML_SetUserData(parser, &found_rsqb); 3689 found_rsqb = 0; 3690 if (_XML_Parse_SINGLE_BYTES(parser, text8, text8_len, 3691 XML_TRUE) == XML_STATUS_OK) 3692 fail("Failed to fault unclosed doc"); 3693 if (found_rsqb == 0) 3694 fail("Did not catch the right square bracket"); 3695 3696 /* Try again with a different encoding */ 3697 XML_ParserReset(parser, NULL); 3698 XML_SetCharacterDataHandler(parser, rsqb_handler); 3699 XML_SetUserData(parser, &found_rsqb); 3700 found_rsqb = 0; 3701 if (_XML_Parse_SINGLE_BYTES(parser, text16, (int)sizeof(text16)-1, 3702 XML_TRUE) == XML_STATUS_OK) 3703 fail("Failed to fault unclosed doc"); 3704 if (found_rsqb == 0) 3705 fail("Did not catch the right square bracket"); 3706 3707 /* And finally with a default handler */ 3708 XML_ParserReset(parser, NULL); 3709 XML_SetDefaultHandler(parser, rsqb_handler); 3710 XML_SetUserData(parser, &found_rsqb); 3711 found_rsqb = 0; 3712 if (_XML_Parse_SINGLE_BYTES(parser, text16, (int)sizeof(text16)-1, 3713 XML_TRUE) == XML_STATUS_OK) 3714 fail("Failed to fault unclosed doc"); 3715 if (found_rsqb == 0) 3716 fail("Did not catch the right square bracket"); 3717 } 3718 END_TEST 3719 3720 /* Test trailing right square bracket in an external entity parse */ 3721 static int XMLCALL 3722 external_entity_rsqb_catcher(XML_Parser parser, 3723 const XML_Char *context, 3724 const XML_Char *UNUSED_P(base), 3725 const XML_Char *UNUSED_P(systemId), 3726 const XML_Char *UNUSED_P(publicId)) 3727 { 3728 const char *text = "<tag>]"; 3729 XML_Parser ext_parser; 3730 3731 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 3732 if (ext_parser == NULL) 3733 fail("Could not create external entity parser"); 3734 XML_SetCharacterDataHandler(ext_parser, rsqb_handler); 3735 if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), 3736 XML_TRUE) != XML_STATUS_ERROR) 3737 fail("Async entity error not caught"); 3738 if (XML_GetErrorCode(ext_parser) != XML_ERROR_ASYNC_ENTITY) 3739 xml_failure(ext_parser); 3740 XML_ParserFree(ext_parser); 3741 return XML_STATUS_OK; 3742 } 3743 3744 START_TEST(test_ext_entity_trailing_rsqb) 3745 { 3746 const char *text = 3747 "<!DOCTYPE doc [\n" 3748 " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n" 3749 "]>\n" 3750 "<doc>&en;</doc>"; 3751 int found_rsqb; 3752 3753 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 3754 XML_SetExternalEntityRefHandler(parser, external_entity_rsqb_catcher); 3755 XML_SetUserData(parser, &found_rsqb); 3756 found_rsqb = 0; 3757 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 3758 XML_TRUE) != XML_STATUS_OK) 3759 xml_failure(parser); 3760 if (found_rsqb == 0) 3761 fail("No right square bracket found"); 3762 } 3763 END_TEST 3764 3765 /* Test CDATA handling in an external entity */ 3766 static int XMLCALL 3767 external_entity_good_cdata_ascii(XML_Parser parser, 3768 const XML_Char *context, 3769 const XML_Char *UNUSED_P(base), 3770 const XML_Char *UNUSED_P(systemId), 3771 const XML_Char *UNUSED_P(publicId)) 3772 { 3773 const char *text = 3774 "<a><![CDATA[<greeting>Hello, world!</greeting>]]></a>"; 3775 const XML_Char *expected = XCS("<greeting>Hello, world!</greeting>"); 3776 CharData storage; 3777 XML_Parser ext_parser; 3778 3779 CharData_Init(&storage); 3780 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 3781 if (ext_parser == NULL) 3782 fail("Could not create external entity parser"); 3783 XML_SetUserData(ext_parser, &storage); 3784 XML_SetCharacterDataHandler(ext_parser, accumulate_characters); 3785 3786 if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), 3787 XML_TRUE) == XML_STATUS_ERROR) 3788 xml_failure(ext_parser); 3789 CharData_CheckXMLChars(&storage, expected); 3790 3791 XML_ParserFree(ext_parser); 3792 return XML_STATUS_OK; 3793 } 3794 3795 START_TEST(test_ext_entity_good_cdata) 3796 { 3797 const char *text = 3798 "<!DOCTYPE doc [\n" 3799 " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n" 3800 "]>\n" 3801 "<doc>&en;</doc>"; 3802 3803 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 3804 XML_SetExternalEntityRefHandler(parser, 3805 external_entity_good_cdata_ascii); 3806 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 3807 XML_TRUE) != XML_STATUS_OK) 3808 xml_failure(parser); 3809 } 3810 END_TEST 3811 3812 /* Test user parameter settings */ 3813 /* Variable holding the expected handler userData */ 3814 static void *handler_data = NULL; 3815 /* Count of the number of times the comment handler has been invoked */ 3816 static int comment_count = 0; 3817 /* Count of the number of skipped entities */ 3818 static int skip_count = 0; 3819 /* Count of the number of times the XML declaration handler is invoked */ 3820 static int xdecl_count = 0; 3821 3822 static void XMLCALL 3823 xml_decl_handler(void *userData, 3824 const XML_Char *UNUSED_P(version), 3825 const XML_Char *UNUSED_P(encoding), 3826 int standalone) 3827 { 3828 if (userData != handler_data) 3829 fail("User data (xml decl) not correctly set"); 3830 if (standalone != -1) 3831 fail("Standalone not flagged as not present in XML decl"); 3832 xdecl_count++; 3833 } 3834 3835 static void XMLCALL 3836 param_check_skip_handler(void *userData, 3837 const XML_Char *UNUSED_P(entityName), 3838 int UNUSED_P(is_parameter_entity)) 3839 { 3840 if (userData != handler_data) 3841 fail("User data (skip) not correctly set"); 3842 skip_count++; 3843 } 3844 3845 static void XMLCALL 3846 data_check_comment_handler(void *userData, const XML_Char *UNUSED_P(data)) 3847 { 3848 /* Check that the userData passed through is what we expect */ 3849 if (userData != handler_data) 3850 fail("User data (parser) not correctly set"); 3851 /* Check that the user data in the parser is appropriate */ 3852 if (XML_GetUserData(userData) != (void *)1) 3853 fail("User data in parser not correctly set"); 3854 comment_count++; 3855 } 3856 3857 static int XMLCALL 3858 external_entity_param_checker(XML_Parser parser, 3859 const XML_Char *context, 3860 const XML_Char *UNUSED_P(base), 3861 const XML_Char *UNUSED_P(systemId), 3862 const XML_Char *UNUSED_P(publicId)) 3863 { 3864 const char *text = 3865 "<!-- Subordinate parser -->\n" 3866 "<!ELEMENT doc (#PCDATA)*>"; 3867 XML_Parser ext_parser; 3868 3869 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 3870 if (ext_parser == NULL) 3871 fail("Could not create external entity parser"); 3872 handler_data = ext_parser; 3873 if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), 3874 XML_TRUE) == XML_STATUS_ERROR) { 3875 xml_failure(parser); 3876 return XML_STATUS_ERROR; 3877 } 3878 handler_data = parser; 3879 XML_ParserFree(ext_parser); 3880 return XML_STATUS_OK; 3881 } 3882 3883 START_TEST(test_user_parameters) 3884 { 3885 const char *text = 3886 "<?xml version='1.0' encoding='us-ascii'?>\n" 3887 "<!-- Primary parse -->\n" 3888 "<!DOCTYPE doc SYSTEM 'foo'>\n" 3889 "<doc>&entity;"; 3890 const char *epilog = 3891 "<!-- Back to primary parser -->\n" 3892 "</doc>"; 3893 3894 comment_count = 0; 3895 skip_count = 0; 3896 xdecl_count = 0; 3897 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 3898 XML_SetXmlDeclHandler(parser, xml_decl_handler); 3899 XML_SetExternalEntityRefHandler(parser, external_entity_param_checker); 3900 XML_SetCommentHandler(parser, data_check_comment_handler); 3901 XML_SetSkippedEntityHandler(parser, param_check_skip_handler); 3902 XML_UseParserAsHandlerArg(parser); 3903 XML_SetUserData(parser, (void *)1); 3904 handler_data = parser; 3905 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 3906 XML_FALSE) == XML_STATUS_ERROR) 3907 xml_failure(parser); 3908 if (comment_count != 2) 3909 fail("Comment handler not invoked enough times"); 3910 /* Ensure we can't change policy mid-parse */ 3911 if (XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_NEVER)) 3912 fail("Changed param entity parsing policy while parsing"); 3913 if (_XML_Parse_SINGLE_BYTES(parser, epilog, (int)strlen(epilog), 3914 XML_TRUE) == XML_STATUS_ERROR) 3915 xml_failure(parser); 3916 if (comment_count != 3) 3917 fail("Comment handler not invoked enough times"); 3918 if (skip_count != 1) 3919 fail("Skip handler not invoked enough times"); 3920 if (xdecl_count != 1) 3921 fail("XML declaration handler not invoked"); 3922 } 3923 END_TEST 3924 3925 /* Test that an explicit external entity handler argument replaces 3926 * the parser as the first argument. 3927 * 3928 * We do not call the first parameter to the external entity handler 3929 * 'parser' for once, since the first time the handler is called it 3930 * will actually be a text string. We need to be able to access the 3931 * global 'parser' variable to create our external entity parser from, 3932 * since there are code paths we need to ensure get executed. 3933 */ 3934 static int XMLCALL 3935 external_entity_ref_param_checker(XML_Parser parameter, 3936 const XML_Char *context, 3937 const XML_Char *UNUSED_P(base), 3938 const XML_Char *UNUSED_P(systemId), 3939 const XML_Char *UNUSED_P(publicId)) 3940 { 3941 const char *text = "<!ELEMENT doc (#PCDATA)*>"; 3942 XML_Parser ext_parser; 3943 3944 if ((void *)parameter != handler_data) 3945 fail("External entity ref handler parameter not correct"); 3946 3947 /* Here we use the global 'parser' variable */ 3948 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 3949 if (ext_parser == NULL) 3950 fail("Could not create external entity parser"); 3951 if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), 3952 XML_TRUE) == XML_STATUS_ERROR) 3953 xml_failure(ext_parser); 3954 3955 XML_ParserFree(ext_parser); 3956 return XML_STATUS_OK; 3957 } 3958 3959 START_TEST(test_ext_entity_ref_parameter) 3960 { 3961 const char *text = 3962 "<?xml version='1.0' encoding='us-ascii'?>\n" 3963 "<!DOCTYPE doc SYSTEM 'foo'>\n" 3964 "<doc>&entity;</doc>"; 3965 3966 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 3967 XML_SetExternalEntityRefHandler(parser, 3968 external_entity_ref_param_checker); 3969 /* Set a handler arg that is not NULL and not parser (which is 3970 * what NULL would cause to be passed. 3971 */ 3972 XML_SetExternalEntityRefHandlerArg(parser, (void *)text); 3973 handler_data = (void *)text; 3974 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 3975 XML_TRUE) == XML_STATUS_ERROR) 3976 xml_failure(parser); 3977 3978 /* Now try again with unset args */ 3979 XML_ParserReset(parser, NULL); 3980 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 3981 XML_SetExternalEntityRefHandler(parser, 3982 external_entity_ref_param_checker); 3983 XML_SetExternalEntityRefHandlerArg(parser, NULL); 3984 handler_data = (void *)parser; 3985 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 3986 XML_TRUE) == XML_STATUS_ERROR) 3987 xml_failure(parser); 3988 } 3989 END_TEST 3990 3991 /* Test the parsing of an empty string */ 3992 START_TEST(test_empty_parse) 3993 { 3994 const char *text = "<doc></doc>"; 3995 const char *partial = "<doc>"; 3996 3997 if (XML_Parse(parser, NULL, 0, XML_FALSE) == XML_STATUS_ERROR) 3998 fail("Parsing empty string faulted"); 3999 if (XML_Parse(parser, NULL, 0, XML_TRUE) != XML_STATUS_ERROR) 4000 fail("Parsing final empty string not faulted"); 4001 if (XML_GetErrorCode(parser) != XML_ERROR_NO_ELEMENTS) 4002 fail("Parsing final empty string faulted for wrong reason"); 4003 4004 /* Now try with valid text before the empty end */ 4005 XML_ParserReset(parser, NULL); 4006 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 4007 XML_FALSE) == XML_STATUS_ERROR) 4008 xml_failure(parser); 4009 if (XML_Parse(parser, NULL, 0, XML_TRUE) == XML_STATUS_ERROR) 4010 fail("Parsing final empty string faulted"); 4011 4012 /* Now try with invalid text before the empty end */ 4013 XML_ParserReset(parser, NULL); 4014 if (_XML_Parse_SINGLE_BYTES(parser, partial, (int)strlen(partial), 4015 XML_FALSE) == XML_STATUS_ERROR) 4016 xml_failure(parser); 4017 if (XML_Parse(parser, NULL, 0, XML_TRUE) != XML_STATUS_ERROR) 4018 fail("Parsing final incomplete empty string not faulted"); 4019 } 4020 END_TEST 4021 4022 /* Test odd corners of the XML_GetBuffer interface */ 4023 static enum XML_Status 4024 get_feature(enum XML_FeatureEnum feature_id, long *presult) 4025 { 4026 const XML_Feature *feature = XML_GetFeatureList(); 4027 4028 if (feature == NULL) 4029 return XML_STATUS_ERROR; 4030 for (; feature->feature != XML_FEATURE_END; feature++) { 4031 if (feature->feature == feature_id) { 4032 *presult = feature->value; 4033 return XML_STATUS_OK; 4034 } 4035 } 4036 return XML_STATUS_ERROR; 4037 } 4038 4039 /* Having an element name longer than 1024 characters exercises some 4040 * of the pool allocation code in the parser that otherwise does not 4041 * get executed. The count at the end of the line is the number of 4042 * characters (bytes) in the element name by that point.x 4043 */ 4044 static const char *get_buffer_test_text = 4045 "<documentwitharidiculouslylongelementnametotease" /* 0x030 */ 4046 "aparticularcorneroftheallocationinXML_GetBuffers" /* 0x060 */ 4047 "othatwecanimprovethecoverageyetagain012345678901" /* 0x090 */ 4048 "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x0c0 */ 4049 "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x0f0 */ 4050 "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x120 */ 4051 "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x150 */ 4052 "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x180 */ 4053 "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x1b0 */ 4054 "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x1e0 */ 4055 "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x210 */ 4056 "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x240 */ 4057 "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x270 */ 4058 "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x2a0 */ 4059 "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x2d0 */ 4060 "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x300 */ 4061 "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x330 */ 4062 "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x360 */ 4063 "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x390 */ 4064 "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x3c0 */ 4065 "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x3f0 */ 4066 "123456789abcdef0123456789abcdef0123456789>\n<ef0"; /* 0x420 */ 4067 4068 /* Test odd corners of the XML_GetBuffer interface */ 4069 START_TEST(test_get_buffer_1) 4070 { 4071 const char *text = get_buffer_test_text; 4072 void *buffer; 4073 long context_bytes; 4074 4075 /* Attempt to allocate a negative length buffer */ 4076 if (XML_GetBuffer(parser, -12) != NULL) 4077 fail("Negative length buffer not failed"); 4078 4079 /* Now get a small buffer and extend it past valid length */ 4080 buffer = XML_GetBuffer(parser, 1536); 4081 if (buffer == NULL) 4082 fail("1.5K buffer failed"); 4083 memcpy(buffer, text, strlen(text)); 4084 if (XML_ParseBuffer(parser, (int)strlen(text), XML_FALSE) == XML_STATUS_ERROR) 4085 xml_failure(parser); 4086 if (XML_GetBuffer(parser, INT_MAX) != NULL) 4087 fail("INT_MAX buffer not failed"); 4088 4089 /* Now try extending it a more reasonable but still too large 4090 * amount. The allocator in XML_GetBuffer() doubles the buffer 4091 * size until it exceeds the requested amount or INT_MAX. If it 4092 * exceeds INT_MAX, it rejects the request, so we want a request 4093 * between INT_MAX and INT_MAX/2. A gap of 1K seems comfortable, 4094 * with an extra byte just to ensure that the request is off any 4095 * boundary. The request will be inflated internally by 4096 * XML_CONTEXT_BYTES (if defined), so we subtract that from our 4097 * request. 4098 */ 4099 if (get_feature(XML_FEATURE_CONTEXT_BYTES, 4100 &context_bytes) != XML_STATUS_OK) 4101 context_bytes = 0; 4102 if (XML_GetBuffer(parser, INT_MAX - (context_bytes + 1025)) != NULL) 4103 fail("INT_MAX- buffer not failed"); 4104 4105 /* Now try extending it a carefully crafted amount */ 4106 if (XML_GetBuffer(parser, 1000) == NULL) 4107 fail("1000 buffer failed"); 4108 } 4109 END_TEST 4110 4111 /* Test more corners of the XML_GetBuffer interface */ 4112 START_TEST(test_get_buffer_2) 4113 { 4114 const char *text = get_buffer_test_text; 4115 void *buffer; 4116 4117 /* Now get a decent buffer */ 4118 buffer = XML_GetBuffer(parser, 1536); 4119 if (buffer == NULL) 4120 fail("1.5K buffer failed"); 4121 memcpy(buffer, text, strlen(text)); 4122 if (XML_ParseBuffer(parser, (int)strlen(text), XML_FALSE) == XML_STATUS_ERROR) 4123 xml_failure(parser); 4124 4125 /* Extend it, to catch a different code path */ 4126 if (XML_GetBuffer(parser, 1024) == NULL) 4127 fail("1024 buffer failed"); 4128 } 4129 END_TEST 4130 4131 /* Test position information macros */ 4132 START_TEST(test_byte_info_at_end) 4133 { 4134 const char *text = "<doc></doc>"; 4135 4136 if (XML_GetCurrentByteIndex(parser) != -1 || 4137 XML_GetCurrentByteCount(parser) != 0) 4138 fail("Byte index/count incorrect at start of parse"); 4139 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 4140 XML_TRUE) == XML_STATUS_ERROR) 4141 xml_failure(parser); 4142 /* At end, the count will be zero and the index the end of string */ 4143 if (XML_GetCurrentByteCount(parser) != 0) 4144 fail("Terminal byte count incorrect"); 4145 if (XML_GetCurrentByteIndex(parser) != (XML_Index)strlen(text)) 4146 fail("Terminal byte index incorrect"); 4147 } 4148 END_TEST 4149 4150 /* Test position information from errors */ 4151 #define PRE_ERROR_STR "<doc></" 4152 #define POST_ERROR_STR "wombat></doc>" 4153 START_TEST(test_byte_info_at_error) 4154 { 4155 const char *text = PRE_ERROR_STR POST_ERROR_STR; 4156 4157 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 4158 XML_TRUE) == XML_STATUS_OK) 4159 fail("Syntax error not faulted"); 4160 if (XML_GetCurrentByteCount(parser) != 0) 4161 fail("Error byte count incorrect"); 4162 if (XML_GetCurrentByteIndex(parser) != strlen(PRE_ERROR_STR)) 4163 fail("Error byte index incorrect"); 4164 } 4165 END_TEST 4166 #undef PRE_ERROR_STR 4167 #undef POST_ERROR_STR 4168 4169 /* Test position information in handler */ 4170 typedef struct ByteTestData { 4171 int start_element_len; 4172 int cdata_len; 4173 int total_string_len; 4174 } ByteTestData; 4175 4176 static void 4177 byte_character_handler(void *userData, 4178 const XML_Char *UNUSED_P(s), 4179 int len) 4180 { 4181 #ifdef XML_CONTEXT_BYTES 4182 int offset, size; 4183 const char *buffer; 4184 ByteTestData *data = (ByteTestData *)userData; 4185 4186 buffer = XML_GetInputContext(parser, &offset, &size); 4187 if (buffer == NULL) 4188 fail("Failed to get context buffer"); 4189 if (offset != data->start_element_len) 4190 fail("Context offset in unexpected position"); 4191 if (len != data->cdata_len) 4192 fail("CDATA length reported incorrectly"); 4193 if (size != data->total_string_len) 4194 fail("Context size is not full buffer"); 4195 if (XML_GetCurrentByteIndex(parser) != offset) 4196 fail("Character byte index incorrect"); 4197 if (XML_GetCurrentByteCount(parser) != len) 4198 fail("Character byte count incorrect"); 4199 #else 4200 (void)userData; 4201 (void)len; 4202 #endif 4203 } 4204 4205 #define START_ELEMENT "<e>" 4206 #define CDATA_TEXT "Hello" 4207 #define END_ELEMENT "</e>" 4208 START_TEST(test_byte_info_at_cdata) 4209 { 4210 const char *text = START_ELEMENT CDATA_TEXT END_ELEMENT; 4211 int offset, size; 4212 ByteTestData data; 4213 4214 /* Check initial context is empty */ 4215 if (XML_GetInputContext(parser, &offset, &size) != NULL) 4216 fail("Unexpected context at start of parse"); 4217 4218 data.start_element_len = (int)strlen(START_ELEMENT); 4219 data.cdata_len = (int)strlen(CDATA_TEXT); 4220 data.total_string_len = (int)strlen(text); 4221 XML_SetCharacterDataHandler(parser, byte_character_handler); 4222 XML_SetUserData(parser, &data); 4223 if (XML_Parse(parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_OK) 4224 xml_failure(parser); 4225 } 4226 END_TEST 4227 #undef START_ELEMENT 4228 #undef CDATA_TEXT 4229 #undef END_ELEMENT 4230 4231 /* Test predefined entities are correctly recognised */ 4232 START_TEST(test_predefined_entities) 4233 { 4234 const char *text = "<doc><>&"'</doc>"; 4235 const XML_Char *expected = XCS("<doc><>&"'</doc>"); 4236 const XML_Char *result = XCS("<>&\"'"); 4237 CharData storage; 4238 4239 XML_SetDefaultHandler(parser, accumulate_characters); 4240 /* run_character_check uses XML_SetCharacterDataHandler(), which 4241 * unfortunately heads off a code path that we need to exercise. 4242 */ 4243 CharData_Init(&storage); 4244 XML_SetUserData(parser, &storage); 4245 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 4246 XML_TRUE) == XML_STATUS_ERROR) 4247 xml_failure(parser); 4248 /* The default handler doesn't translate the entities */ 4249 CharData_CheckXMLChars(&storage, expected); 4250 4251 /* Now try again and check the translation */ 4252 XML_ParserReset(parser, NULL); 4253 run_character_check(text, result); 4254 } 4255 END_TEST 4256 4257 /* Regression test that an invalid tag in an external parameter 4258 * reference in an external DTD is correctly faulted. 4259 * 4260 * Only a few specific tags are legal in DTDs ignoring comments and 4261 * processing instructions, all of which begin with an exclamation 4262 * mark. "<el/>" is not one of them, so the parser should raise an 4263 * error on encountering it. 4264 */ 4265 static int XMLCALL 4266 external_entity_param(XML_Parser parser, 4267 const XML_Char *context, 4268 const XML_Char *UNUSED_P(base), 4269 const XML_Char *systemId, 4270 const XML_Char *UNUSED_P(publicId)) 4271 { 4272 const char *text1 = 4273 "<!ELEMENT doc EMPTY>\n" 4274 "<!ENTITY % e1 SYSTEM '004-2.ent'>\n" 4275 "<!ENTITY % e2 '%e1;'>\n" 4276 "%e1;\n"; 4277 const char *text2 = 4278 "<!ELEMENT el EMPTY>\n" 4279 "<el/>\n"; 4280 XML_Parser ext_parser; 4281 4282 if (systemId == NULL) 4283 return XML_STATUS_OK; 4284 4285 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 4286 if (ext_parser == NULL) 4287 fail("Could not create external entity parser"); 4288 4289 if (!xcstrcmp(systemId, XCS("004-1.ent"))) { 4290 if (_XML_Parse_SINGLE_BYTES(ext_parser, text1, (int)strlen(text1), 4291 XML_TRUE) != XML_STATUS_ERROR) 4292 fail("Inner DTD with invalid tag not rejected"); 4293 if (XML_GetErrorCode(ext_parser) != XML_ERROR_EXTERNAL_ENTITY_HANDLING) 4294 xml_failure(ext_parser); 4295 } 4296 else if (!xcstrcmp(systemId, XCS("004-2.ent"))) { 4297 if (_XML_Parse_SINGLE_BYTES(ext_parser, text2, (int)strlen(text2), 4298 XML_TRUE) != XML_STATUS_ERROR) 4299 fail("Invalid tag in external param not rejected"); 4300 if (XML_GetErrorCode(ext_parser) != XML_ERROR_SYNTAX) 4301 xml_failure(ext_parser); 4302 } else { 4303 fail("Unknown system ID"); 4304 } 4305 4306 XML_ParserFree(ext_parser); 4307 return XML_STATUS_ERROR; 4308 } 4309 4310 START_TEST(test_invalid_tag_in_dtd) 4311 { 4312 const char *text = 4313 "<!DOCTYPE doc SYSTEM '004-1.ent'>\n" 4314 "<doc></doc>\n"; 4315 4316 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 4317 XML_SetExternalEntityRefHandler(parser, external_entity_param); 4318 expect_failure(text, XML_ERROR_EXTERNAL_ENTITY_HANDLING, 4319 "Invalid tag IN DTD external param not rejected"); 4320 } 4321 END_TEST 4322 4323 /* Test entities not quite the predefined ones are not mis-recognised */ 4324 START_TEST(test_not_predefined_entities) 4325 { 4326 const char *text[] = { 4327 "<doc>&pt;</doc>", 4328 "<doc>&amo;</doc>", 4329 "<doc>&quid;</doc>", 4330 "<doc>&apod;</doc>", 4331 NULL 4332 }; 4333 int i = 0; 4334 4335 while (text[i] != NULL) { 4336 expect_failure(text[i], XML_ERROR_UNDEFINED_ENTITY, 4337 "Undefined entity not rejected"); 4338 XML_ParserReset(parser, NULL); 4339 i++; 4340 } 4341 } 4342 END_TEST 4343 4344 /* Test conditional inclusion (IGNORE) */ 4345 static int XMLCALL 4346 external_entity_load_ignore(XML_Parser parser, 4347 const XML_Char *context, 4348 const XML_Char *UNUSED_P(base), 4349 const XML_Char *UNUSED_P(systemId), 4350 const XML_Char *UNUSED_P(publicId)) 4351 { 4352 const char *text = "<![IGNORE[<!ELEMENT e (#PCDATA)*>]]>"; 4353 XML_Parser ext_parser; 4354 4355 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 4356 if (ext_parser == NULL) 4357 fail("Could not create external entity parser"); 4358 if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), 4359 XML_TRUE) == XML_STATUS_ERROR) 4360 xml_failure(parser); 4361 4362 XML_ParserFree(ext_parser); 4363 return XML_STATUS_OK; 4364 } 4365 4366 START_TEST(test_ignore_section) 4367 { 4368 const char *text = 4369 "<!DOCTYPE doc SYSTEM 'foo'>\n" 4370 "<doc><e>&entity;</e></doc>"; 4371 const XML_Char *expected = 4372 XCS("<![IGNORE[<!ELEMENT e (#PCDATA)*>]]>\n&entity;"); 4373 CharData storage; 4374 4375 CharData_Init(&storage); 4376 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 4377 XML_SetUserData(parser, &storage); 4378 XML_SetExternalEntityRefHandler(parser, external_entity_load_ignore); 4379 XML_SetDefaultHandler(parser, accumulate_characters); 4380 XML_SetStartDoctypeDeclHandler(parser, dummy_start_doctype_handler); 4381 XML_SetEndDoctypeDeclHandler(parser, dummy_end_doctype_handler); 4382 XML_SetElementDeclHandler(parser, dummy_element_decl_handler); 4383 XML_SetStartElementHandler(parser, dummy_start_element); 4384 XML_SetEndElementHandler(parser, dummy_end_element); 4385 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 4386 XML_TRUE) == XML_STATUS_ERROR) 4387 xml_failure(parser); 4388 CharData_CheckXMLChars(&storage, expected); 4389 } 4390 END_TEST 4391 4392 static int XMLCALL 4393 external_entity_load_ignore_utf16(XML_Parser parser, 4394 const XML_Char *context, 4395 const XML_Char *UNUSED_P(base), 4396 const XML_Char *UNUSED_P(systemId), 4397 const XML_Char *UNUSED_P(publicId)) 4398 { 4399 const char text[] = 4400 /* <![IGNORE[<!ELEMENT e (#PCDATA)*>]]> */ 4401 "<\0!\0[\0I\0G\0N\0O\0R\0E\0[\0" 4402 "<\0!\0E\0L\0E\0M\0E\0N\0T\0 \0e\0 \0" 4403 "(\0#\0P\0C\0D\0A\0T\0A\0)\0*\0>\0]\0]\0>\0"; 4404 XML_Parser ext_parser; 4405 4406 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 4407 if (ext_parser == NULL) 4408 fail("Could not create external entity parser"); 4409 if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)sizeof(text)-1, 4410 XML_TRUE) == XML_STATUS_ERROR) 4411 xml_failure(parser); 4412 4413 XML_ParserFree(ext_parser); 4414 return XML_STATUS_OK; 4415 } 4416 4417 START_TEST(test_ignore_section_utf16) 4418 { 4419 const char text[] = 4420 /* <!DOCTYPE d SYSTEM 's'> */ 4421 "<\0!\0D\0O\0C\0T\0Y\0P\0E\0 \0d\0 " 4422 "\0S\0Y\0S\0T\0E\0M\0 \0'\0s\0'\0>\0\n\0" 4423 /* <d><e>&en;</e></d> */ 4424 "<\0d\0>\0<\0e\0>\0&\0e\0n\0;\0<\0/\0e\0>\0<\0/\0d\0>\0"; 4425 const XML_Char *expected = 4426 XCS("<![IGNORE[<!ELEMENT e (#PCDATA)*>]]>\n&en;"); 4427 CharData storage; 4428 4429 CharData_Init(&storage); 4430 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 4431 XML_SetUserData(parser, &storage); 4432 XML_SetExternalEntityRefHandler(parser, 4433 external_entity_load_ignore_utf16); 4434 XML_SetDefaultHandler(parser, accumulate_characters); 4435 XML_SetStartDoctypeDeclHandler(parser, dummy_start_doctype_handler); 4436 XML_SetEndDoctypeDeclHandler(parser, dummy_end_doctype_handler); 4437 XML_SetElementDeclHandler(parser, dummy_element_decl_handler); 4438 XML_SetStartElementHandler(parser, dummy_start_element); 4439 XML_SetEndElementHandler(parser, dummy_end_element); 4440 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text)-1, 4441 XML_TRUE) == XML_STATUS_ERROR) 4442 xml_failure(parser); 4443 CharData_CheckXMLChars(&storage, expected); 4444 } 4445 END_TEST 4446 4447 static int XMLCALL 4448 external_entity_load_ignore_utf16_be(XML_Parser parser, 4449 const XML_Char *context, 4450 const XML_Char *UNUSED_P(base), 4451 const XML_Char *UNUSED_P(systemId), 4452 const XML_Char *UNUSED_P(publicId)) 4453 { 4454 const char text[] = 4455 /* <![IGNORE[<!ELEMENT e (#PCDATA)*>]]> */ 4456 "\0<\0!\0[\0I\0G\0N\0O\0R\0E\0[" 4457 "\0<\0!\0E\0L\0E\0M\0E\0N\0T\0 \0e\0 " 4458 "\0(\0#\0P\0C\0D\0A\0T\0A\0)\0*\0>\0]\0]\0>"; 4459 XML_Parser ext_parser; 4460 4461 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 4462 if (ext_parser == NULL) 4463 fail("Could not create external entity parser"); 4464 if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)sizeof(text)-1, 4465 XML_TRUE) == XML_STATUS_ERROR) 4466 xml_failure(parser); 4467 4468 XML_ParserFree(ext_parser); 4469 return XML_STATUS_OK; 4470 } 4471 4472 START_TEST(test_ignore_section_utf16_be) 4473 { 4474 const char text[] = 4475 /* <!DOCTYPE d SYSTEM 's'> */ 4476 "\0<\0!\0D\0O\0C\0T\0Y\0P\0E\0 \0d\0 " 4477 "\0S\0Y\0S\0T\0E\0M\0 \0'\0s\0'\0>\0\n" 4478 /* <d><e>&en;</e></d> */ 4479 "\0<\0d\0>\0<\0e\0>\0&\0e\0n\0;\0<\0/\0e\0>\0<\0/\0d\0>"; 4480 const XML_Char *expected = 4481 XCS("<![IGNORE[<!ELEMENT e (#PCDATA)*>]]>\n&en;"); 4482 CharData storage; 4483 4484 CharData_Init(&storage); 4485 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 4486 XML_SetUserData(parser, &storage); 4487 XML_SetExternalEntityRefHandler(parser, 4488 external_entity_load_ignore_utf16_be); 4489 XML_SetDefaultHandler(parser, accumulate_characters); 4490 XML_SetStartDoctypeDeclHandler(parser, dummy_start_doctype_handler); 4491 XML_SetEndDoctypeDeclHandler(parser, dummy_end_doctype_handler); 4492 XML_SetElementDeclHandler(parser, dummy_element_decl_handler); 4493 XML_SetStartElementHandler(parser, dummy_start_element); 4494 XML_SetEndElementHandler(parser, dummy_end_element); 4495 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text)-1, 4496 XML_TRUE) == XML_STATUS_ERROR) 4497 xml_failure(parser); 4498 CharData_CheckXMLChars(&storage, expected); 4499 } 4500 END_TEST 4501 4502 /* Test mis-formatted conditional exclusion */ 4503 START_TEST(test_bad_ignore_section) 4504 { 4505 const char *text = 4506 "<!DOCTYPE doc SYSTEM 'foo'>\n" 4507 "<doc><e>&entity;</e></doc>"; 4508 ExtFaults faults[] = { 4509 { 4510 "<![IGNORE[<!ELEM", 4511 "Broken-off declaration not faulted", 4512 NULL, 4513 XML_ERROR_SYNTAX 4514 }, 4515 { 4516 "<![IGNORE[\x01]]>", 4517 "Invalid XML character not faulted", 4518 NULL, 4519 XML_ERROR_INVALID_TOKEN 4520 }, 4521 { 4522 /* FIrst two bytes of a three-byte char */ 4523 "<![IGNORE[\xe2\x82", 4524 "Partial XML character not faulted", 4525 NULL, 4526 XML_ERROR_PARTIAL_CHAR 4527 }, 4528 { NULL, NULL, NULL, XML_ERROR_NONE } 4529 }; 4530 ExtFaults *fault; 4531 4532 for (fault = &faults[0]; fault->parse_text != NULL; fault++) { 4533 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 4534 XML_SetExternalEntityRefHandler(parser, external_entity_faulter); 4535 XML_SetUserData(parser, fault); 4536 expect_failure(text, XML_ERROR_EXTERNAL_ENTITY_HANDLING, 4537 "Incomplete IGNORE section not failed"); 4538 XML_ParserReset(parser, NULL); 4539 } 4540 } 4541 END_TEST 4542 4543 /* Test recursive parsing */ 4544 static int XMLCALL 4545 external_entity_valuer(XML_Parser parser, 4546 const XML_Char *context, 4547 const XML_Char *UNUSED_P(base), 4548 const XML_Char *systemId, 4549 const XML_Char *UNUSED_P(publicId)) 4550 { 4551 const char *text1 = 4552 "<!ELEMENT doc EMPTY>\n" 4553 "<!ENTITY % e1 SYSTEM '004-2.ent'>\n" 4554 "<!ENTITY % e2 '%e1;'>\n" 4555 "%e1;\n"; 4556 XML_Parser ext_parser; 4557 4558 if (systemId == NULL) 4559 return XML_STATUS_OK; 4560 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 4561 if (ext_parser == NULL) 4562 fail("Could not create external entity parser"); 4563 if (!xcstrcmp(systemId, XCS("004-1.ent"))) { 4564 if (_XML_Parse_SINGLE_BYTES(ext_parser, text1, (int)strlen(text1), 4565 XML_TRUE) == XML_STATUS_ERROR) 4566 xml_failure(ext_parser); 4567 } 4568 else if (!xcstrcmp(systemId, XCS("004-2.ent"))) { 4569 ExtFaults *fault = (ExtFaults *)XML_GetUserData(parser); 4570 enum XML_Status status; 4571 enum XML_Error error; 4572 4573 status = _XML_Parse_SINGLE_BYTES(ext_parser, 4574 fault->parse_text, 4575 (int)strlen(fault->parse_text), 4576 XML_TRUE); 4577 if (fault->error == XML_ERROR_NONE) { 4578 if (status == XML_STATUS_ERROR) 4579 xml_failure(ext_parser); 4580 } else { 4581 if (status != XML_STATUS_ERROR) 4582 fail(fault->fail_text); 4583 error = XML_GetErrorCode(ext_parser); 4584 if (error != fault->error && 4585 (fault->error != XML_ERROR_XML_DECL || 4586 error != XML_ERROR_TEXT_DECL)) 4587 xml_failure(ext_parser); 4588 } 4589 } 4590 4591 XML_ParserFree(ext_parser); 4592 return XML_STATUS_OK; 4593 } 4594 4595 START_TEST(test_external_entity_values) 4596 { 4597 const char *text = 4598 "<!DOCTYPE doc SYSTEM '004-1.ent'>\n" 4599 "<doc></doc>\n"; 4600 ExtFaults data_004_2[] = { 4601 { 4602 "<!ATTLIST doc a1 CDATA 'value'>", 4603 NULL, 4604 NULL, 4605 XML_ERROR_NONE 4606 }, 4607 { 4608 "<!ATTLIST $doc a1 CDATA 'value'>", 4609 "Invalid token not faulted", 4610 NULL, 4611 XML_ERROR_INVALID_TOKEN 4612 }, 4613 { 4614 "'wombat", 4615 "Unterminated string not faulted", 4616 NULL, 4617 XML_ERROR_UNCLOSED_TOKEN 4618 }, 4619 { 4620 "\xe2\x82", 4621 "Partial UTF-8 character not faulted", 4622 NULL, 4623 XML_ERROR_PARTIAL_CHAR 4624 }, 4625 { 4626 "<?xml version='1.0' encoding='utf-8'?>\n", 4627 NULL, 4628 NULL, 4629 XML_ERROR_NONE 4630 }, 4631 { 4632 "<?xml?>", 4633 "Malformed XML declaration not faulted", 4634 NULL, 4635 XML_ERROR_XML_DECL 4636 }, 4637 { 4638 /* UTF-8 BOM */ 4639 "\xEF\xBB\xBF<!ATTLIST doc a1 CDATA 'value'>", 4640 NULL, 4641 NULL, 4642 XML_ERROR_NONE 4643 }, 4644 { 4645 "<?xml version='1.0' encoding='utf-8'?>\n$", 4646 "Invalid token after text declaration not faulted", 4647 NULL, 4648 XML_ERROR_INVALID_TOKEN 4649 }, 4650 { 4651 "<?xml version='1.0' encoding='utf-8'?>\n'wombat", 4652 "Unterminated string after text decl not faulted", 4653 NULL, 4654 XML_ERROR_UNCLOSED_TOKEN 4655 }, 4656 { 4657 "<?xml version='1.0' encoding='utf-8'?>\n\xe2\x82", 4658 "Partial UTF-8 character after text decl not faulted", 4659 NULL, 4660 XML_ERROR_PARTIAL_CHAR 4661 }, 4662 { 4663 "%e1;", 4664 "Recursive parameter entity not faulted", 4665 NULL, 4666 XML_ERROR_RECURSIVE_ENTITY_REF 4667 }, 4668 { NULL, NULL, NULL, XML_ERROR_NONE } 4669 }; 4670 int i; 4671 4672 for (i = 0; data_004_2[i].parse_text != NULL; i++) { 4673 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 4674 XML_SetExternalEntityRefHandler(parser, external_entity_valuer); 4675 XML_SetUserData(parser, &data_004_2[i]); 4676 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 4677 XML_TRUE) == XML_STATUS_ERROR) 4678 xml_failure(parser); 4679 XML_ParserReset(parser, NULL); 4680 } 4681 } 4682 END_TEST 4683 4684 /* Test the recursive parse interacts with a not standalone handler */ 4685 static int XMLCALL 4686 external_entity_not_standalone(XML_Parser parser, 4687 const XML_Char *context, 4688 const XML_Char *UNUSED_P(base), 4689 const XML_Char *systemId, 4690 const XML_Char *UNUSED_P(publicId)) 4691 { 4692 const char *text1 = 4693 "<!ELEMENT doc EMPTY>\n" 4694 "<!ENTITY % e1 SYSTEM 'bar'>\n" 4695 "%e1;\n"; 4696 const char *text2 = "<!ATTLIST doc a1 CDATA 'value'>"; 4697 XML_Parser ext_parser; 4698 4699 if (systemId == NULL) 4700 return XML_STATUS_OK; 4701 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 4702 if (ext_parser == NULL) 4703 fail("Could not create external entity parser"); 4704 if (!xcstrcmp(systemId, XCS("foo"))) { 4705 XML_SetNotStandaloneHandler(ext_parser, 4706 reject_not_standalone_handler); 4707 if (_XML_Parse_SINGLE_BYTES(ext_parser, text1, (int)strlen(text1), 4708 XML_TRUE) != XML_STATUS_ERROR) 4709 fail("Expected not standalone rejection"); 4710 if (XML_GetErrorCode(ext_parser) != XML_ERROR_NOT_STANDALONE) 4711 xml_failure(ext_parser); 4712 XML_SetNotStandaloneHandler(ext_parser, NULL); 4713 XML_ParserFree(ext_parser); 4714 return XML_STATUS_ERROR; 4715 } 4716 else if (!xcstrcmp(systemId, XCS("bar"))) { 4717 if (_XML_Parse_SINGLE_BYTES(ext_parser, text2, (int)strlen(text2), 4718 XML_TRUE) == XML_STATUS_ERROR) 4719 xml_failure(ext_parser); 4720 } 4721 4722 XML_ParserFree(ext_parser); 4723 return XML_STATUS_OK; 4724 } 4725 4726 START_TEST(test_ext_entity_not_standalone) 4727 { 4728 const char *text = 4729 "<!DOCTYPE doc SYSTEM 'foo'>\n" 4730 "<doc></doc>"; 4731 4732 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 4733 XML_SetExternalEntityRefHandler(parser, external_entity_not_standalone); 4734 expect_failure(text, XML_ERROR_EXTERNAL_ENTITY_HANDLING, 4735 "Standalone rejection not caught"); 4736 } 4737 END_TEST 4738 4739 static int XMLCALL 4740 external_entity_value_aborter(XML_Parser parser, 4741 const XML_Char *context, 4742 const XML_Char *UNUSED_P(base), 4743 const XML_Char *systemId, 4744 const XML_Char *UNUSED_P(publicId)) 4745 { 4746 const char *text1 = 4747 "<!ELEMENT doc EMPTY>\n" 4748 "<!ENTITY % e1 SYSTEM '004-2.ent'>\n" 4749 "<!ENTITY % e2 '%e1;'>\n" 4750 "%e1;\n"; 4751 const char *text2 = 4752 "<?xml version='1.0' encoding='utf-8'?>"; 4753 XML_Parser ext_parser; 4754 4755 if (systemId == NULL) 4756 return XML_STATUS_OK; 4757 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 4758 if (ext_parser == NULL) 4759 fail("Could not create external entity parser"); 4760 if (!xcstrcmp(systemId, XCS("004-1.ent"))) { 4761 if (_XML_Parse_SINGLE_BYTES(ext_parser, text1, (int)strlen(text1), 4762 XML_TRUE) == XML_STATUS_ERROR) 4763 xml_failure(ext_parser); 4764 } 4765 if (!xcstrcmp(systemId, XCS("004-2.ent"))) { 4766 XML_SetXmlDeclHandler(ext_parser, entity_suspending_xdecl_handler); 4767 XML_SetUserData(ext_parser, ext_parser); 4768 if (_XML_Parse_SINGLE_BYTES(ext_parser, text2, (int)strlen(text2), 4769 XML_TRUE) != XML_STATUS_ERROR) 4770 fail("Aborted parse not faulted"); 4771 if (XML_GetErrorCode(ext_parser) != XML_ERROR_ABORTED) 4772 xml_failure(ext_parser); 4773 } 4774 4775 XML_ParserFree(ext_parser); 4776 return XML_STATUS_OK; 4777 } 4778 4779 START_TEST(test_ext_entity_value_abort) 4780 { 4781 const char *text = 4782 "<!DOCTYPE doc SYSTEM '004-1.ent'>\n" 4783 "<doc></doc>\n"; 4784 4785 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 4786 XML_SetExternalEntityRefHandler(parser, 4787 external_entity_value_aborter); 4788 resumable = XML_FALSE; 4789 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 4790 XML_TRUE) == XML_STATUS_ERROR) 4791 xml_failure(parser); 4792 } 4793 END_TEST 4794 4795 START_TEST(test_bad_public_doctype) 4796 { 4797 const char *text = 4798 "<?xml version='1.0' encoding='utf-8'?>\n" 4799 "<!DOCTYPE doc PUBLIC '{BadName}' 'test'>\n" 4800 "<doc></doc>"; 4801 4802 /* Setting a handler provokes a particular code path */ 4803 XML_SetDoctypeDeclHandler(parser, 4804 dummy_start_doctype_handler, 4805 dummy_end_doctype_handler); 4806 expect_failure(text, XML_ERROR_PUBLICID, "Bad Public ID not failed"); 4807 } 4808 END_TEST 4809 4810 /* Test based on ibm/valid/P32/ibm32v04.xml */ 4811 START_TEST(test_attribute_enum_value) 4812 { 4813 const char *text = 4814 "<?xml version='1.0' standalone='no'?>\n" 4815 "<!DOCTYPE animal SYSTEM 'test.dtd'>\n" 4816 "<animal>This is a \n <a/> \n\nyellow tiger</animal>"; 4817 ExtTest dtd_data = { 4818 "<!ELEMENT animal (#PCDATA|a)*>\n" 4819 "<!ELEMENT a EMPTY>\n" 4820 "<!ATTLIST animal xml:space (default|preserve) 'preserve'>", 4821 NULL, 4822 NULL 4823 }; 4824 const XML_Char *expected = XCS("This is a \n \n\nyellow tiger"); 4825 4826 XML_SetExternalEntityRefHandler(parser, external_entity_loader); 4827 XML_SetUserData(parser, &dtd_data); 4828 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 4829 /* An attribute list handler provokes a different code path */ 4830 XML_SetAttlistDeclHandler(parser, dummy_attlist_decl_handler); 4831 run_ext_character_check(text, &dtd_data, expected); 4832 } 4833 END_TEST 4834 4835 /* Slightly bizarrely, the library seems to silently ignore entity 4836 * definitions for predefined entities, even when they are wrong. The 4837 * language of the XML 1.0 spec is somewhat unhelpful as to what ought 4838 * to happen, so this is currently treated as acceptable. 4839 */ 4840 START_TEST(test_predefined_entity_redefinition) 4841 { 4842 const char *text = 4843 "<!DOCTYPE doc [\n" 4844 "<!ENTITY apos 'foo'>\n" 4845 "]>\n" 4846 "<doc>'</doc>"; 4847 run_character_check(text, XCS("'")); 4848 } 4849 END_TEST 4850 4851 /* Test that the parser stops processing the DTD after an unresolved 4852 * parameter entity is encountered. 4853 */ 4854 START_TEST(test_dtd_stop_processing) 4855 { 4856 const char *text = 4857 "<!DOCTYPE doc [\n" 4858 "%foo;\n" 4859 "<!ENTITY bar 'bas'>\n" 4860 "]><doc/>"; 4861 4862 XML_SetEntityDeclHandler(parser, dummy_entity_decl_handler); 4863 dummy_handler_flags = 0; 4864 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 4865 XML_TRUE) == XML_STATUS_ERROR) 4866 xml_failure(parser); 4867 if (dummy_handler_flags != 0) 4868 fail("DTD processing still going after undefined PE"); 4869 } 4870 END_TEST 4871 4872 /* Test public notations with no system ID */ 4873 START_TEST(test_public_notation_no_sysid) 4874 { 4875 const char *text = 4876 "<!DOCTYPE doc [\n" 4877 "<!NOTATION note PUBLIC 'foo'>\n" 4878 "<!ELEMENT doc EMPTY>\n" 4879 "]>\n<doc/>"; 4880 4881 dummy_handler_flags = 0; 4882 XML_SetNotationDeclHandler(parser, dummy_notation_decl_handler); 4883 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 4884 XML_TRUE) == XML_STATUS_ERROR) 4885 xml_failure(parser); 4886 if (dummy_handler_flags != DUMMY_NOTATION_DECL_HANDLER_FLAG) 4887 fail("Notation declaration handler not called"); 4888 } 4889 END_TEST 4890 4891 static void XMLCALL 4892 record_element_start_handler(void *userData, 4893 const XML_Char *name, 4894 const XML_Char **UNUSED_P(atts)) 4895 { 4896 CharData_AppendXMLChars((CharData *)userData, name, (int)xcstrlen(name)); 4897 } 4898 4899 START_TEST(test_nested_groups) 4900 { 4901 const char *text = 4902 "<!DOCTYPE doc [\n" 4903 "<!ELEMENT doc " 4904 /* Sixteen elements per line */ 4905 "(e,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?," 4906 "(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?" 4907 "))))))))))))))))))))))))))))))))>\n" 4908 "<!ELEMENT e EMPTY>" 4909 "]>\n" 4910 "<doc><e/></doc>"; 4911 CharData storage; 4912 4913 CharData_Init(&storage); 4914 XML_SetElementDeclHandler(parser, dummy_element_decl_handler); 4915 XML_SetStartElementHandler(parser, record_element_start_handler); 4916 XML_SetUserData(parser, &storage); 4917 dummy_handler_flags = 0; 4918 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 4919 XML_TRUE) == XML_STATUS_ERROR) 4920 xml_failure(parser); 4921 CharData_CheckXMLChars(&storage, XCS("doce")); 4922 if (dummy_handler_flags != DUMMY_ELEMENT_DECL_HANDLER_FLAG) 4923 fail("Element handler not fired"); 4924 } 4925 END_TEST 4926 4927 START_TEST(test_group_choice) 4928 { 4929 const char *text = 4930 "<!DOCTYPE doc [\n" 4931 "<!ELEMENT doc (a|b|c)+>\n" 4932 "<!ELEMENT a EMPTY>\n" 4933 "<!ELEMENT b (#PCDATA)>\n" 4934 "<!ELEMENT c ANY>\n" 4935 "]>\n" 4936 "<doc>\n" 4937 "<a/>\n" 4938 "<b attr='foo'>This is a foo</b>\n" 4939 "<c></c>\n" 4940 "</doc>\n"; 4941 4942 XML_SetElementDeclHandler(parser, dummy_element_decl_handler); 4943 dummy_handler_flags = 0; 4944 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 4945 XML_TRUE) == XML_STATUS_ERROR) 4946 xml_failure(parser); 4947 if (dummy_handler_flags != DUMMY_ELEMENT_DECL_HANDLER_FLAG) 4948 fail("Element handler flag not raised"); 4949 } 4950 END_TEST 4951 4952 static int XMLCALL 4953 external_entity_public(XML_Parser parser, 4954 const XML_Char *context, 4955 const XML_Char *UNUSED_P(base), 4956 const XML_Char *systemId, 4957 const XML_Char *publicId) 4958 { 4959 const char *text1 = (const char *)XML_GetUserData(parser); 4960 const char *text2 = "<!ATTLIST doc a CDATA 'value'>"; 4961 const char *text = NULL; 4962 XML_Parser ext_parser; 4963 int parse_res; 4964 4965 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 4966 if (ext_parser == NULL) 4967 return XML_STATUS_ERROR; 4968 if (systemId != NULL && !xcstrcmp(systemId, XCS("http://example.org/"))) { 4969 text = text1; 4970 } 4971 else if (publicId != NULL && !xcstrcmp(publicId, XCS("foo"))) { 4972 text = text2; 4973 } 4974 else 4975 fail("Unexpected parameters to external entity parser"); 4976 parse_res = _XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), 4977 XML_TRUE); 4978 XML_ParserFree(ext_parser); 4979 return parse_res; 4980 } 4981 4982 START_TEST(test_standalone_parameter_entity) 4983 { 4984 const char *text = 4985 "<?xml version='1.0' standalone='yes'?>\n" 4986 "<!DOCTYPE doc SYSTEM 'http://example.org/' [\n" 4987 "<!ENTITY % entity '<!ELEMENT doc (#PCDATA)>'>\n" 4988 "%entity;\n" 4989 "]>\n" 4990 "<doc></doc>"; 4991 char dtd_data[] = 4992 "<!ENTITY % e1 'foo'>\n"; 4993 4994 XML_SetUserData(parser, dtd_data); 4995 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 4996 XML_SetExternalEntityRefHandler(parser, external_entity_public); 4997 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 4998 XML_TRUE) == XML_STATUS_ERROR) 4999 xml_failure(parser); 5000 } 5001 END_TEST 5002 5003 /* Test skipping of parameter entity in an external DTD */ 5004 /* Derived from ibm/invalid/P69/ibm69i01.xml */ 5005 START_TEST(test_skipped_parameter_entity) 5006 { 5007 const char *text = 5008 "<?xml version='1.0'?>\n" 5009 "<!DOCTYPE root SYSTEM 'http://example.org/dtd.ent' [\n" 5010 "<!ELEMENT root (#PCDATA|a)* >\n" 5011 "]>\n" 5012 "<root></root>"; 5013 ExtTest dtd_data = { "%pe2;", NULL, NULL }; 5014 5015 XML_SetExternalEntityRefHandler(parser, external_entity_loader); 5016 XML_SetUserData(parser, &dtd_data); 5017 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 5018 XML_SetSkippedEntityHandler(parser, dummy_skip_handler); 5019 dummy_handler_flags = 0; 5020 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 5021 XML_TRUE) == XML_STATUS_ERROR) 5022 xml_failure(parser); 5023 if (dummy_handler_flags != DUMMY_SKIP_HANDLER_FLAG) 5024 fail("Skip handler not executed"); 5025 } 5026 END_TEST 5027 5028 /* Test recursive parameter entity definition rejected in external DTD */ 5029 START_TEST(test_recursive_external_parameter_entity) 5030 { 5031 const char *text = 5032 "<?xml version='1.0'?>\n" 5033 "<!DOCTYPE root SYSTEM 'http://example.org/dtd.ent' [\n" 5034 "<!ELEMENT root (#PCDATA|a)* >\n" 5035 "]>\n" 5036 "<root></root>"; 5037 ExtFaults dtd_data = { 5038 "<!ENTITY % pe2 '%pe2;'>\n%pe2;", 5039 "Recursive external parameter entity not faulted", 5040 NULL, 5041 XML_ERROR_RECURSIVE_ENTITY_REF 5042 }; 5043 5044 XML_SetExternalEntityRefHandler(parser, external_entity_faulter); 5045 XML_SetUserData(parser, &dtd_data); 5046 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 5047 expect_failure(text, 5048 XML_ERROR_EXTERNAL_ENTITY_HANDLING, 5049 "Recursive external parameter not spotted"); 5050 } 5051 END_TEST 5052 5053 /* Test undefined parameter entity in external entity handler */ 5054 static int XMLCALL 5055 external_entity_devaluer(XML_Parser parser, 5056 const XML_Char *context, 5057 const XML_Char *UNUSED_P(base), 5058 const XML_Char *systemId, 5059 const XML_Char *UNUSED_P(publicId)) 5060 { 5061 const char *text = 5062 "<!ELEMENT doc EMPTY>\n" 5063 "<!ENTITY % e1 SYSTEM 'bar'>\n" 5064 "%e1;\n"; 5065 XML_Parser ext_parser; 5066 intptr_t clear_handler = (intptr_t)XML_GetUserData(parser); 5067 5068 if (systemId == NULL || !xcstrcmp(systemId, XCS("bar"))) 5069 return XML_STATUS_OK; 5070 if (xcstrcmp(systemId, XCS("foo"))) 5071 fail("Unexpected system ID"); 5072 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 5073 if (ext_parser == NULL) 5074 fail("Could note create external entity parser"); 5075 if (clear_handler) 5076 XML_SetExternalEntityRefHandler(ext_parser, NULL); 5077 if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), 5078 XML_TRUE) == XML_STATUS_ERROR) 5079 xml_failure(ext_parser); 5080 5081 XML_ParserFree(ext_parser); 5082 return XML_STATUS_OK; 5083 } 5084 5085 START_TEST(test_undefined_ext_entity_in_external_dtd) 5086 { 5087 const char *text = 5088 "<!DOCTYPE doc SYSTEM 'foo'>\n" 5089 "<doc></doc>\n"; 5090 5091 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 5092 XML_SetExternalEntityRefHandler(parser, external_entity_devaluer); 5093 XML_SetUserData(parser, (void *)(intptr_t)XML_FALSE); 5094 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 5095 XML_TRUE) == XML_STATUS_ERROR) 5096 xml_failure(parser); 5097 5098 /* Now repeat without the external entity ref handler invoking 5099 * another copy of itself. 5100 */ 5101 XML_ParserReset(parser, NULL); 5102 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 5103 XML_SetExternalEntityRefHandler(parser, external_entity_devaluer); 5104 XML_SetUserData(parser, (void *)(intptr_t)XML_TRUE); 5105 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 5106 XML_TRUE) == XML_STATUS_ERROR) 5107 xml_failure(parser); 5108 } 5109 END_TEST 5110 5111 5112 static void XMLCALL 5113 aborting_xdecl_handler(void *UNUSED_P(userData), 5114 const XML_Char *UNUSED_P(version), 5115 const XML_Char *UNUSED_P(encoding), 5116 int UNUSED_P(standalone)) 5117 { 5118 XML_StopParser(parser, resumable); 5119 XML_SetXmlDeclHandler(parser, NULL); 5120 } 5121 5122 /* Test suspending the parse on receiving an XML declaration works */ 5123 START_TEST(test_suspend_xdecl) 5124 { 5125 const char *text = long_character_data_text; 5126 5127 XML_SetXmlDeclHandler(parser, aborting_xdecl_handler); 5128 resumable = XML_TRUE; 5129 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 5130 XML_TRUE) != XML_STATUS_SUSPENDED) 5131 xml_failure(parser); 5132 if (XML_GetErrorCode(parser) != XML_ERROR_NONE) 5133 xml_failure(parser); 5134 /* Attempt to start a new parse while suspended */ 5135 if (XML_Parse(parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR) 5136 fail("Attempt to parse while suspended not faulted"); 5137 if (XML_GetErrorCode(parser) != XML_ERROR_SUSPENDED) 5138 fail("Suspended parse not faulted with correct error"); 5139 } 5140 END_TEST 5141 5142 /* Test aborting the parse in an epilog works */ 5143 static void XMLCALL 5144 selective_aborting_default_handler(void *userData, 5145 const XML_Char *s, 5146 int len) 5147 { 5148 const XML_Char *match = (const XML_Char *)userData; 5149 5150 if (match == NULL || 5151 (xcstrlen(match) == (unsigned)len && 5152 !xcstrncmp(match, s, len))) { 5153 XML_StopParser(parser, resumable); 5154 XML_SetDefaultHandler(parser, NULL); 5155 } 5156 } 5157 5158 START_TEST(test_abort_epilog) 5159 { 5160 const char *text = "<doc></doc>\n\r\n"; 5161 XML_Char match[] = XCS("\r"); 5162 5163 XML_SetDefaultHandler(parser, selective_aborting_default_handler); 5164 XML_SetUserData(parser, match); 5165 resumable = XML_FALSE; 5166 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 5167 XML_TRUE) != XML_STATUS_ERROR) 5168 fail("Abort not triggered"); 5169 if (XML_GetErrorCode(parser) != XML_ERROR_ABORTED) 5170 xml_failure(parser); 5171 } 5172 END_TEST 5173 5174 /* Test a different code path for abort in the epilog */ 5175 START_TEST(test_abort_epilog_2) 5176 { 5177 const char *text = "<doc></doc>\n"; 5178 XML_Char match[] = XCS("\n"); 5179 5180 XML_SetDefaultHandler(parser, selective_aborting_default_handler); 5181 XML_SetUserData(parser, match); 5182 resumable = XML_FALSE; 5183 expect_failure(text, XML_ERROR_ABORTED, "Abort not triggered"); 5184 } 5185 END_TEST 5186 5187 /* Test suspension from the epilog */ 5188 START_TEST(test_suspend_epilog) 5189 { 5190 const char *text = "<doc></doc>\n"; 5191 XML_Char match[] = XCS("\n"); 5192 5193 XML_SetDefaultHandler(parser, selective_aborting_default_handler); 5194 XML_SetUserData(parser, match); 5195 resumable = XML_TRUE; 5196 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 5197 XML_TRUE) != XML_STATUS_SUSPENDED) 5198 xml_failure(parser); 5199 } 5200 END_TEST 5201 5202 static void XMLCALL 5203 suspending_end_handler(void *userData, 5204 const XML_Char *UNUSED_P(s)) 5205 { 5206 XML_StopParser((XML_Parser)userData, 1); 5207 } 5208 5209 START_TEST(test_suspend_in_sole_empty_tag) 5210 { 5211 const char *text = "<doc/>"; 5212 enum XML_Status rc; 5213 5214 XML_SetEndElementHandler(parser, suspending_end_handler); 5215 XML_SetUserData(parser, parser); 5216 rc = _XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 5217 XML_TRUE); 5218 if (rc == XML_STATUS_ERROR) 5219 xml_failure(parser); 5220 else if (rc != XML_STATUS_SUSPENDED) 5221 fail("Suspend not triggered"); 5222 rc = XML_ResumeParser(parser); 5223 if (rc == XML_STATUS_ERROR) 5224 xml_failure(parser); 5225 else if (rc != XML_STATUS_OK) 5226 fail("Resume failed"); 5227 } 5228 END_TEST 5229 5230 START_TEST(test_unfinished_epilog) 5231 { 5232 const char *text = "<doc></doc><"; 5233 5234 expect_failure(text, XML_ERROR_UNCLOSED_TOKEN, 5235 "Incomplete epilog entry not faulted"); 5236 } 5237 END_TEST 5238 5239 START_TEST(test_partial_char_in_epilog) 5240 { 5241 const char *text = "<doc></doc>\xe2\x82"; 5242 5243 /* First check that no fault is raised if the parse is not finished */ 5244 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 5245 XML_FALSE) == XML_STATUS_ERROR) 5246 xml_failure(parser); 5247 /* Now check that it is faulted once we finish */ 5248 if (XML_ParseBuffer(parser, 0, XML_TRUE) != XML_STATUS_ERROR) 5249 fail("Partial character in epilog not faulted"); 5250 if (XML_GetErrorCode(parser) != XML_ERROR_PARTIAL_CHAR) 5251 xml_failure(parser); 5252 } 5253 END_TEST 5254 5255 START_TEST(test_hash_collision) 5256 { 5257 /* For full coverage of the lookup routine, we need to ensure a 5258 * hash collision even though we can only tell that we have one 5259 * through breakpoint debugging or coverage statistics. The 5260 * following will cause a hash collision on machines with a 64-bit 5261 * long type; others will have to experiment. The full coverage 5262 * tests invoked from qa.sh usually provide a hash collision, but 5263 * not always. This is an attempt to provide insurance. 5264 */ 5265 #define COLLIDING_HASH_SALT (unsigned long)_SIP_ULL(0xffffffffU, 0xff99fc90U) 5266 const char * text = 5267 "<doc>\n" 5268 "<a1/><a2/><a3/><a4/><a5/><a6/><a7/><a8/>\n" 5269 "<b1></b1><b2 attr='foo'>This is a foo</b2><b3></b3><b4></b4>\n" 5270 "<b5></b5><b6></b6><b7></b7><b8></b8>\n" 5271 "<c1/><c2/><c3/><c4/><c5/><c6/><c7/><c8/>\n" 5272 "<d1/><d2/><d3/><d4/><d5/><d6/><d7/>\n" 5273 "<d8>This triggers the table growth and collides with b2</d8>\n" 5274 "</doc>\n"; 5275 5276 XML_SetHashSalt(parser, COLLIDING_HASH_SALT); 5277 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 5278 XML_TRUE) == XML_STATUS_ERROR) 5279 xml_failure(parser); 5280 } 5281 END_TEST 5282 #undef COLLIDING_HASH_SALT 5283 5284 /* Test resuming a parse suspended in entity substitution */ 5285 static void XMLCALL 5286 start_element_suspender(void *UNUSED_P(userData), 5287 const XML_Char *name, 5288 const XML_Char **UNUSED_P(atts)) 5289 { 5290 if (!xcstrcmp(name, XCS("suspend"))) 5291 XML_StopParser(parser, XML_TRUE); 5292 if (!xcstrcmp(name, XCS("abort"))) 5293 XML_StopParser(parser, XML_FALSE); 5294 } 5295 5296 START_TEST(test_suspend_resume_internal_entity) 5297 { 5298 const char *text = 5299 "<!DOCTYPE doc [\n" 5300 "<!ENTITY foo '<suspend>Hi<suspend>Ho</suspend></suspend>'>\n" 5301 "]>\n" 5302 "<doc>&foo;</doc>\n"; 5303 const XML_Char *expected1 = XCS("Hi"); 5304 const XML_Char *expected2 = XCS("HiHo"); 5305 CharData storage; 5306 5307 CharData_Init(&storage); 5308 XML_SetStartElementHandler(parser, start_element_suspender); 5309 XML_SetCharacterDataHandler(parser, accumulate_characters); 5310 XML_SetUserData(parser, &storage); 5311 if (XML_Parse(parser, text, (int)strlen(text), 5312 XML_TRUE) != XML_STATUS_SUSPENDED) 5313 xml_failure(parser); 5314 CharData_CheckXMLChars(&storage, XCS("")); 5315 if (XML_ResumeParser(parser) != XML_STATUS_SUSPENDED) 5316 xml_failure(parser); 5317 CharData_CheckXMLChars(&storage, expected1); 5318 if (XML_ResumeParser(parser) != XML_STATUS_OK) 5319 xml_failure(parser); 5320 CharData_CheckXMLChars(&storage, expected2); 5321 } 5322 END_TEST 5323 5324 /* Test syntax error is caught at parse resumption */ 5325 START_TEST(test_resume_entity_with_syntax_error) 5326 { 5327 const char *text = 5328 "<!DOCTYPE doc [\n" 5329 "<!ENTITY foo '<suspend>Hi</wombat>'>\n" 5330 "]>\n" 5331 "<doc>&foo;</doc>\n"; 5332 5333 XML_SetStartElementHandler(parser, start_element_suspender); 5334 if (XML_Parse(parser, text, (int)strlen(text), 5335 XML_TRUE) != XML_STATUS_SUSPENDED) 5336 xml_failure(parser); 5337 if (XML_ResumeParser(parser) != XML_STATUS_ERROR) 5338 fail("Syntax error in entity not faulted"); 5339 if (XML_GetErrorCode(parser) != XML_ERROR_TAG_MISMATCH) 5340 xml_failure(parser); 5341 } 5342 END_TEST 5343 5344 /* Test suspending and resuming in a parameter entity substitution */ 5345 static void XMLCALL 5346 element_decl_suspender(void *UNUSED_P(userData), 5347 const XML_Char *UNUSED_P(name), 5348 XML_Content *model) 5349 { 5350 XML_StopParser(parser, XML_TRUE); 5351 XML_FreeContentModel(parser, model); 5352 } 5353 5354 START_TEST(test_suspend_resume_parameter_entity) 5355 { 5356 const char *text = 5357 "<!DOCTYPE doc [\n" 5358 "<!ENTITY % foo '<!ELEMENT doc (#PCDATA)*>'>\n" 5359 "%foo;\n" 5360 "]>\n" 5361 "<doc>Hello, world</doc>"; 5362 const XML_Char *expected = XCS("Hello, world"); 5363 CharData storage; 5364 5365 CharData_Init(&storage); 5366 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 5367 XML_SetElementDeclHandler(parser, element_decl_suspender); 5368 XML_SetCharacterDataHandler(parser, accumulate_characters); 5369 XML_SetUserData(parser, &storage); 5370 if (XML_Parse(parser, text, (int)strlen(text), 5371 XML_TRUE) != XML_STATUS_SUSPENDED) 5372 xml_failure(parser); 5373 CharData_CheckXMLChars(&storage, XCS("")); 5374 if (XML_ResumeParser(parser) != XML_STATUS_OK) 5375 xml_failure(parser); 5376 CharData_CheckXMLChars(&storage, expected); 5377 } 5378 END_TEST 5379 5380 /* Test attempting to use parser after an error is faulted */ 5381 START_TEST(test_restart_on_error) 5382 { 5383 const char *text = "<$doc><doc></doc>"; 5384 5385 if (XML_Parse(parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR) 5386 fail("Invalid tag name not faulted"); 5387 if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_TOKEN) 5388 xml_failure(parser); 5389 if (XML_Parse(parser, NULL, 0, XML_TRUE) != XML_STATUS_ERROR) 5390 fail("Restarting invalid parse not faulted"); 5391 if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_TOKEN) 5392 xml_failure(parser); 5393 } 5394 END_TEST 5395 5396 /* Test that angle brackets in an attribute default value are faulted */ 5397 START_TEST(test_reject_lt_in_attribute_value) 5398 { 5399 const char *text = 5400 "<!DOCTYPE doc [<!ATTLIST doc a CDATA '<bar>'>]>\n" 5401 "<doc></doc>"; 5402 5403 expect_failure(text, XML_ERROR_INVALID_TOKEN, 5404 "Bad attribute default not faulted"); 5405 } 5406 END_TEST 5407 5408 START_TEST(test_reject_unfinished_param_in_att_value) 5409 { 5410 const char *text = 5411 "<!DOCTYPE doc [<!ATTLIST doc a CDATA '&foo'>]>\n" 5412 "<doc></doc>"; 5413 5414 expect_failure(text, XML_ERROR_INVALID_TOKEN, 5415 "Bad attribute default not faulted"); 5416 } 5417 END_TEST 5418 5419 START_TEST(test_trailing_cr_in_att_value) 5420 { 5421 const char *text = "<doc a='value\r'/>"; 5422 5423 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 5424 XML_TRUE) == XML_STATUS_ERROR) 5425 xml_failure(parser); 5426 } 5427 END_TEST 5428 5429 /* Try parsing a general entity within a parameter entity in a 5430 * standalone internal DTD. Covers a corner case in the parser. 5431 */ 5432 START_TEST(test_standalone_internal_entity) 5433 { 5434 const char *text = 5435 "<?xml version='1.0' standalone='yes' ?>\n" 5436 "<!DOCTYPE doc [\n" 5437 " <!ELEMENT doc (#PCDATA)>\n" 5438 " <!ENTITY % pe '<!ATTLIST doc att2 CDATA \"≥\">'>\n" 5439 " <!ENTITY ge 'AttDefaultValue'>\n" 5440 " %pe;\n" 5441 "]>\n" 5442 "<doc att2='any'/>"; 5443 5444 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 5445 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 5446 XML_TRUE) == XML_STATUS_ERROR) 5447 xml_failure(parser); 5448 } 5449 END_TEST 5450 5451 /* Test that a reference to an unknown external entity is skipped */ 5452 START_TEST(test_skipped_external_entity) 5453 { 5454 const char *text = 5455 "<!DOCTYPE doc SYSTEM 'http://example.org/'>\n" 5456 "<doc></doc>\n"; 5457 ExtTest test_data = { 5458 "<!ELEMENT doc EMPTY>\n" 5459 "<!ENTITY % e2 '%e1;'>\n", 5460 NULL, 5461 NULL 5462 }; 5463 5464 XML_SetUserData(parser, &test_data); 5465 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 5466 XML_SetExternalEntityRefHandler(parser, external_entity_loader); 5467 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 5468 XML_TRUE) == XML_STATUS_ERROR) 5469 xml_failure(parser); 5470 } 5471 END_TEST 5472 5473 /* Test a different form of unknown external entity */ 5474 typedef struct ext_hdlr_data { 5475 const char *parse_text; 5476 XML_ExternalEntityRefHandler handler; 5477 } ExtHdlrData; 5478 5479 static int XMLCALL 5480 external_entity_oneshot_loader(XML_Parser parser, 5481 const XML_Char *context, 5482 const XML_Char *UNUSED_P(base), 5483 const XML_Char *UNUSED_P(systemId), 5484 const XML_Char *UNUSED_P(publicId)) 5485 { 5486 ExtHdlrData *test_data = (ExtHdlrData *)XML_GetUserData(parser); 5487 XML_Parser ext_parser; 5488 5489 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 5490 if (ext_parser == NULL) 5491 fail("Could not create external entity parser."); 5492 /* Use the requested entity parser for further externals */ 5493 XML_SetExternalEntityRefHandler(ext_parser, test_data->handler); 5494 if ( _XML_Parse_SINGLE_BYTES(ext_parser, 5495 test_data->parse_text, 5496 (int)strlen(test_data->parse_text), 5497 XML_TRUE) == XML_STATUS_ERROR) { 5498 xml_failure(ext_parser); 5499 } 5500 5501 XML_ParserFree(ext_parser); 5502 return XML_STATUS_OK; 5503 } 5504 5505 START_TEST(test_skipped_null_loaded_ext_entity) 5506 { 5507 const char *text = 5508 "<!DOCTYPE doc SYSTEM 'http://example.org/one.ent'>\n" 5509 "<doc />"; 5510 ExtHdlrData test_data = { 5511 "<!ENTITY % pe1 SYSTEM 'http://example.org/two.ent'>\n" 5512 "<!ENTITY % pe2 '%pe1;'>\n" 5513 "%pe2;\n", 5514 external_entity_null_loader 5515 }; 5516 5517 XML_SetUserData(parser, &test_data); 5518 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 5519 XML_SetExternalEntityRefHandler(parser, external_entity_oneshot_loader); 5520 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 5521 XML_TRUE) == XML_STATUS_ERROR) 5522 xml_failure(parser); 5523 } 5524 END_TEST 5525 5526 START_TEST(test_skipped_unloaded_ext_entity) 5527 { 5528 const char *text = 5529 "<!DOCTYPE doc SYSTEM 'http://example.org/one.ent'>\n" 5530 "<doc />"; 5531 ExtHdlrData test_data = { 5532 "<!ENTITY % pe1 SYSTEM 'http://example.org/two.ent'>\n" 5533 "<!ENTITY % pe2 '%pe1;'>\n" 5534 "%pe2;\n", 5535 NULL 5536 }; 5537 5538 XML_SetUserData(parser, &test_data); 5539 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 5540 XML_SetExternalEntityRefHandler(parser, external_entity_oneshot_loader); 5541 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 5542 XML_TRUE) == XML_STATUS_ERROR) 5543 xml_failure(parser); 5544 } 5545 END_TEST 5546 5547 /* Test that a parameter entity value ending with a carriage return 5548 * has it translated internally into a newline. 5549 */ 5550 START_TEST(test_param_entity_with_trailing_cr) 5551 { 5552 #define PARAM_ENTITY_NAME "pe" 5553 #define PARAM_ENTITY_CORE_VALUE "<!ATTLIST doc att CDATA \"default\">" 5554 const char *text = 5555 "<!DOCTYPE doc SYSTEM 'http://example.org/'>\n" 5556 "<doc/>"; 5557 ExtTest test_data = { 5558 "<!ENTITY % " PARAM_ENTITY_NAME 5559 " '" PARAM_ENTITY_CORE_VALUE "\r'>\n" 5560 "%" PARAM_ENTITY_NAME ";\n", 5561 NULL, 5562 NULL 5563 }; 5564 5565 XML_SetUserData(parser, &test_data); 5566 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 5567 XML_SetExternalEntityRefHandler(parser, external_entity_loader); 5568 XML_SetEntityDeclHandler(parser, param_entity_match_handler); 5569 entity_name_to_match = XCS(PARAM_ENTITY_NAME); 5570 entity_value_to_match = XCS(PARAM_ENTITY_CORE_VALUE) XCS("\n"); 5571 entity_match_flag = ENTITY_MATCH_NOT_FOUND; 5572 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 5573 XML_TRUE) == XML_STATUS_ERROR) 5574 xml_failure(parser); 5575 if (entity_match_flag == ENTITY_MATCH_FAIL) 5576 fail("Parameter entity CR->NEWLINE conversion failed"); 5577 else if (entity_match_flag == ENTITY_MATCH_NOT_FOUND) 5578 fail("Parameter entity not parsed"); 5579 } 5580 #undef PARAM_ENTITY_NAME 5581 #undef PARAM_ENTITY_CORE_VALUE 5582 END_TEST 5583 5584 START_TEST(test_invalid_character_entity) 5585 { 5586 const char *text = 5587 "<!DOCTYPE doc [\n" 5588 " <!ENTITY entity '�'>\n" 5589 "]>\n" 5590 "<doc>&entity;</doc>"; 5591 5592 expect_failure(text, XML_ERROR_BAD_CHAR_REF, 5593 "Out of range character reference not faulted"); 5594 } 5595 END_TEST 5596 5597 START_TEST(test_invalid_character_entity_2) 5598 { 5599 const char *text = 5600 "<!DOCTYPE doc [\n" 5601 " <!ENTITY entity '&#xg0;'>\n" 5602 "]>\n" 5603 "<doc>&entity;</doc>"; 5604 5605 expect_failure(text, XML_ERROR_INVALID_TOKEN, 5606 "Out of range character reference not faulted"); 5607 } 5608 END_TEST 5609 5610 START_TEST(test_invalid_character_entity_3) 5611 { 5612 const char text[] = 5613 /* <!DOCTYPE doc [\n */ 5614 "\0<\0!\0D\0O\0C\0T\0Y\0P\0E\0 \0d\0o\0c\0 \0[\0\n" 5615 /* U+0E04 = KHO KHWAI 5616 * U+0E08 = CHO CHAN */ 5617 /* <!ENTITY entity '&\u0e04\u0e08;'>\n */ 5618 "\0<\0!\0E\0N\0T\0I\0T\0Y\0 \0e\0n\0t\0i\0t\0y\0 " 5619 "\0'\0&\x0e\x04\x0e\x08\0;\0'\0>\0\n" 5620 /* ]>\n */ 5621 "\0]\0>\0\n" 5622 /* <doc>&entity;</doc> */ 5623 "\0<\0d\0o\0c\0>\0&\0e\0n\0t\0i\0t\0y\0;\0<\0/\0d\0o\0c\0>"; 5624 5625 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text)-1, 5626 XML_TRUE) != XML_STATUS_ERROR) 5627 fail("Invalid start of entity name not faulted"); 5628 if (XML_GetErrorCode(parser) != XML_ERROR_UNDEFINED_ENTITY) 5629 xml_failure(parser); 5630 } 5631 END_TEST 5632 5633 START_TEST(test_invalid_character_entity_4) 5634 { 5635 const char *text = 5636 "<!DOCTYPE doc [\n" 5637 " <!ENTITY entity '�'>\n" /* = � */ 5638 "]>\n" 5639 "<doc>&entity;</doc>"; 5640 5641 expect_failure(text, XML_ERROR_BAD_CHAR_REF, 5642 "Out of range character reference not faulted"); 5643 } 5644 END_TEST 5645 5646 5647 /* Test that processing instructions are picked up by a default handler */ 5648 START_TEST(test_pi_handled_in_default) 5649 { 5650 const char *text = "<?test processing instruction?>\n<doc/>"; 5651 const XML_Char *expected = XCS("<?test processing instruction?>\n<doc/>"); 5652 CharData storage; 5653 5654 CharData_Init(&storage); 5655 XML_SetDefaultHandler(parser, accumulate_characters); 5656 XML_SetUserData(parser, &storage); 5657 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 5658 XML_TRUE)== XML_STATUS_ERROR) 5659 xml_failure(parser); 5660 CharData_CheckXMLChars(&storage, expected); 5661 } 5662 END_TEST 5663 5664 5665 /* Test that comments are picked up by a default handler */ 5666 START_TEST(test_comment_handled_in_default) 5667 { 5668 const char *text = "<!-- This is a comment -->\n<doc/>"; 5669 const XML_Char *expected = XCS("<!-- This is a comment -->\n<doc/>"); 5670 CharData storage; 5671 5672 CharData_Init(&storage); 5673 XML_SetDefaultHandler(parser, accumulate_characters); 5674 XML_SetUserData(parser, &storage); 5675 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 5676 XML_TRUE) == XML_STATUS_ERROR) 5677 xml_failure(parser); 5678 CharData_CheckXMLChars(&storage, expected); 5679 } 5680 END_TEST 5681 5682 /* Test PIs that look almost but not quite like XML declarations */ 5683 static void XMLCALL 5684 accumulate_pi_characters(void *userData, 5685 const XML_Char *target, 5686 const XML_Char *data) 5687 { 5688 CharData *storage = (CharData *)userData; 5689 5690 CharData_AppendXMLChars(storage, target, -1); 5691 CharData_AppendXMLChars(storage, XCS(": "), 2); 5692 CharData_AppendXMLChars(storage, data, -1); 5693 CharData_AppendXMLChars(storage, XCS("\n"), 1); 5694 } 5695 5696 START_TEST(test_pi_yml) 5697 { 5698 const char *text = "<?yml something like data?><doc/>"; 5699 const XML_Char *expected = XCS("yml: something like data\n"); 5700 CharData storage; 5701 5702 CharData_Init(&storage); 5703 XML_SetProcessingInstructionHandler(parser, accumulate_pi_characters); 5704 XML_SetUserData(parser, &storage); 5705 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 5706 XML_TRUE) == XML_STATUS_ERROR) 5707 xml_failure(parser); 5708 CharData_CheckXMLChars(&storage, expected); 5709 } 5710 END_TEST 5711 5712 START_TEST(test_pi_xnl) 5713 { 5714 const char *text = "<?xnl nothing like data?><doc/>"; 5715 const XML_Char *expected = XCS("xnl: nothing like data\n"); 5716 CharData storage; 5717 5718 CharData_Init(&storage); 5719 XML_SetProcessingInstructionHandler(parser, accumulate_pi_characters); 5720 XML_SetUserData(parser, &storage); 5721 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 5722 XML_TRUE) == XML_STATUS_ERROR) 5723 xml_failure(parser); 5724 CharData_CheckXMLChars(&storage, expected); 5725 } 5726 END_TEST 5727 5728 START_TEST(test_pi_xmm) 5729 { 5730 const char *text = "<?xmm everything like data?><doc/>"; 5731 const XML_Char *expected = XCS("xmm: everything like data\n"); 5732 CharData storage; 5733 5734 CharData_Init(&storage); 5735 XML_SetProcessingInstructionHandler(parser, accumulate_pi_characters); 5736 XML_SetUserData(parser, &storage); 5737 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 5738 XML_TRUE) == XML_STATUS_ERROR) 5739 xml_failure(parser); 5740 CharData_CheckXMLChars(&storage, expected); 5741 } 5742 END_TEST 5743 5744 START_TEST(test_utf16_pi) 5745 { 5746 const char text[] = 5747 /* <?{KHO KHWAI}{CHO CHAN}?> 5748 * where {KHO KHWAI} = U+0E04 5749 * and {CHO CHAN} = U+0E08 5750 */ 5751 "<\0?\0\x04\x0e\x08\x0e?\0>\0" 5752 /* <q/> */ 5753 "<\0q\0/\0>\0"; 5754 #ifdef XML_UNICODE 5755 const XML_Char *expected = XCS("\x0e04\x0e08: \n"); 5756 #else 5757 const XML_Char *expected = XCS("\xe0\xb8\x84\xe0\xb8\x88: \n"); 5758 #endif 5759 CharData storage; 5760 5761 CharData_Init(&storage); 5762 XML_SetProcessingInstructionHandler(parser, accumulate_pi_characters); 5763 XML_SetUserData(parser, &storage); 5764 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text)-1, 5765 XML_TRUE) == XML_STATUS_ERROR) 5766 xml_failure(parser); 5767 CharData_CheckXMLChars(&storage, expected); 5768 } 5769 END_TEST 5770 5771 START_TEST(test_utf16_be_pi) 5772 { 5773 const char text[] = 5774 /* <?{KHO KHWAI}{CHO CHAN}?> 5775 * where {KHO KHWAI} = U+0E04 5776 * and {CHO CHAN} = U+0E08 5777 */ 5778 "\0<\0?\x0e\x04\x0e\x08\0?\0>" 5779 /* <q/> */ 5780 "\0<\0q\0/\0>"; 5781 #ifdef XML_UNICODE 5782 const XML_Char *expected = XCS("\x0e04\x0e08: \n"); 5783 #else 5784 const XML_Char *expected = XCS("\xe0\xb8\x84\xe0\xb8\x88: \n"); 5785 #endif 5786 CharData storage; 5787 5788 CharData_Init(&storage); 5789 XML_SetProcessingInstructionHandler(parser, accumulate_pi_characters); 5790 XML_SetUserData(parser, &storage); 5791 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text)-1, 5792 XML_TRUE) == XML_STATUS_ERROR) 5793 xml_failure(parser); 5794 CharData_CheckXMLChars(&storage, expected); 5795 } 5796 END_TEST 5797 5798 /* Test that comments can be picked up and translated */ 5799 static void XMLCALL 5800 accumulate_comment(void *userData, 5801 const XML_Char *data) 5802 { 5803 CharData *storage = (CharData *)userData; 5804 5805 CharData_AppendXMLChars(storage, data, -1); 5806 } 5807 5808 START_TEST(test_utf16_be_comment) 5809 { 5810 const char text[] = 5811 /* <!-- Comment A --> */ 5812 "\0<\0!\0-\0-\0 \0C\0o\0m\0m\0e\0n\0t\0 \0A\0 \0-\0-\0>\0\n" 5813 /* <doc/> */ 5814 "\0<\0d\0o\0c\0/\0>"; 5815 const XML_Char *expected = XCS(" Comment A "); 5816 CharData storage; 5817 5818 CharData_Init(&storage); 5819 XML_SetCommentHandler(parser, accumulate_comment); 5820 XML_SetUserData(parser, &storage); 5821 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text)-1, 5822 XML_TRUE) == XML_STATUS_ERROR) 5823 xml_failure(parser); 5824 CharData_CheckXMLChars(&storage, expected); 5825 } 5826 END_TEST 5827 5828 START_TEST(test_utf16_le_comment) 5829 { 5830 const char text[] = 5831 /* <!-- Comment B --> */ 5832 "<\0!\0-\0-\0 \0C\0o\0m\0m\0e\0n\0t\0 \0B\0 \0-\0-\0>\0\n\0" 5833 /* <doc/> */ 5834 "<\0d\0o\0c\0/\0>\0"; 5835 const XML_Char *expected = XCS(" Comment B "); 5836 CharData storage; 5837 5838 CharData_Init(&storage); 5839 XML_SetCommentHandler(parser, accumulate_comment); 5840 XML_SetUserData(parser, &storage); 5841 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text)-1, 5842 XML_TRUE) == XML_STATUS_ERROR) 5843 xml_failure(parser); 5844 CharData_CheckXMLChars(&storage, expected); 5845 } 5846 END_TEST 5847 5848 /* Test that the unknown encoding handler with map entries that expect 5849 * conversion but no conversion function is faulted 5850 */ 5851 static int XMLCALL 5852 failing_converter(void *UNUSED_P(data), const char *UNUSED_P(s)) 5853 { 5854 /* Always claim to have failed */ 5855 return -1; 5856 } 5857 5858 static int XMLCALL 5859 prefix_converter(void *UNUSED_P(data), const char *s) 5860 { 5861 /* If the first byte is 0xff, raise an error */ 5862 if (s[0] == (char)-1) 5863 return -1; 5864 /* Just add the low bits of the first byte to the second */ 5865 return (s[1] + (s[0] & 0x7f)) & 0x01ff; 5866 } 5867 5868 static int XMLCALL 5869 MiscEncodingHandler(void *data, 5870 const XML_Char *encoding, 5871 XML_Encoding *info) 5872 { 5873 int i; 5874 int high_map = -2; /* Assume a 2-byte sequence */ 5875 5876 if (!xcstrcmp(encoding, XCS("invalid-9")) || 5877 !xcstrcmp(encoding, XCS("ascii-like")) || 5878 !xcstrcmp(encoding, XCS("invalid-len")) || 5879 !xcstrcmp(encoding, XCS("invalid-a")) || 5880 !xcstrcmp(encoding, XCS("invalid-surrogate")) || 5881 !xcstrcmp(encoding, XCS("invalid-high"))) 5882 high_map = -1; 5883 5884 for (i = 0; i < 128; ++i) 5885 info->map[i] = i; 5886 for (; i < 256; ++i) 5887 info->map[i] = high_map; 5888 5889 /* If required, put an invalid value in the ASCII entries */ 5890 if (!xcstrcmp(encoding, XCS("invalid-9"))) 5891 info->map[9] = 5; 5892 /* If required, have a top-bit set character starts a 5-byte sequence */ 5893 if (!xcstrcmp(encoding, XCS("invalid-len"))) 5894 info->map[0x81] = -5; 5895 /* If required, make a top-bit set character a valid ASCII character */ 5896 if (!xcstrcmp(encoding, XCS("invalid-a"))) 5897 info->map[0x82] = 'a'; 5898 /* If required, give a top-bit set character a forbidden value, 5899 * what would otherwise be the first of a surrogate pair. 5900 */ 5901 if (!xcstrcmp(encoding, XCS("invalid-surrogate"))) 5902 info->map[0x83] = 0xd801; 5903 /* If required, give a top-bit set character too high a value */ 5904 if (!xcstrcmp(encoding, XCS("invalid-high"))) 5905 info->map[0x84] = 0x010101; 5906 5907 info->data = data; 5908 info->release = NULL; 5909 if (!xcstrcmp(encoding, XCS("failing-conv"))) 5910 info->convert = failing_converter; 5911 else if (!xcstrcmp(encoding, XCS("prefix-conv"))) 5912 info->convert = prefix_converter; 5913 else 5914 info->convert = NULL; 5915 return XML_STATUS_OK; 5916 } 5917 5918 START_TEST(test_missing_encoding_conversion_fn) 5919 { 5920 const char *text = 5921 "<?xml version='1.0' encoding='no-conv'?>\n" 5922 "<doc>\x81</doc>"; 5923 5924 XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL); 5925 /* MiscEncodingHandler sets up an encoding with every top-bit-set 5926 * character introducing a two-byte sequence. For this, it 5927 * requires a convert function. The above function call doesn't 5928 * pass one through, so when BadEncodingHandler actually gets 5929 * called it should supply an invalid encoding. 5930 */ 5931 expect_failure(text, XML_ERROR_UNKNOWN_ENCODING, 5932 "Encoding with missing convert() not faulted"); 5933 } 5934 END_TEST 5935 5936 START_TEST(test_failing_encoding_conversion_fn) 5937 { 5938 const char *text = 5939 "<?xml version='1.0' encoding='failing-conv'?>\n" 5940 "<doc>\x81</doc>"; 5941 5942 XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL); 5943 /* BadEncodingHandler sets up an encoding with every top-bit-set 5944 * character introducing a two-byte sequence. For this, it 5945 * requires a convert function. The above function call passes 5946 * one that insists all possible sequences are invalid anyway. 5947 */ 5948 expect_failure(text, XML_ERROR_INVALID_TOKEN, 5949 "Encoding with failing convert() not faulted"); 5950 } 5951 END_TEST 5952 5953 /* Test unknown encoding conversions */ 5954 START_TEST(test_unknown_encoding_success) 5955 { 5956 const char *text = 5957 "<?xml version='1.0' encoding='prefix-conv'?>\n" 5958 /* Equivalent to <eoc>Hello, world</eoc> */ 5959 "<\x81\x64\x80oc>Hello, world</\x81\x64\x80oc>"; 5960 5961 XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL); 5962 run_character_check(text, XCS("Hello, world")); 5963 } 5964 END_TEST 5965 5966 /* Test bad name character in unknown encoding */ 5967 START_TEST(test_unknown_encoding_bad_name) 5968 { 5969 const char *text = 5970 "<?xml version='1.0' encoding='prefix-conv'?>\n" 5971 "<\xff\x64oc>Hello, world</\xff\x64oc>"; 5972 5973 XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL); 5974 expect_failure(text, XML_ERROR_INVALID_TOKEN, 5975 "Bad name start in unknown encoding not faulted"); 5976 } 5977 END_TEST 5978 5979 /* Test bad mid-name character in unknown encoding */ 5980 START_TEST(test_unknown_encoding_bad_name_2) 5981 { 5982 const char *text = 5983 "<?xml version='1.0' encoding='prefix-conv'?>\n" 5984 "<d\xffoc>Hello, world</d\xffoc>"; 5985 5986 XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL); 5987 expect_failure(text, XML_ERROR_INVALID_TOKEN, 5988 "Bad name in unknown encoding not faulted"); 5989 } 5990 END_TEST 5991 5992 /* Test element name that is long enough to fill the conversion buffer 5993 * in an unknown encoding, finishing with an encoded character. 5994 */ 5995 START_TEST(test_unknown_encoding_long_name_1) 5996 { 5997 const char *text = 5998 "<?xml version='1.0' encoding='prefix-conv'?>\n" 5999 "<abcdefghabcdefghabcdefghijkl\x80m\x80n\x80o\x80p>" 6000 "Hi" 6001 "</abcdefghabcdefghabcdefghijkl\x80m\x80n\x80o\x80p>"; 6002 const XML_Char *expected = XCS("abcdefghabcdefghabcdefghijklmnop"); 6003 CharData storage; 6004 6005 CharData_Init(&storage); 6006 XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL); 6007 XML_SetStartElementHandler(parser, record_element_start_handler); 6008 XML_SetUserData(parser, &storage); 6009 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 6010 XML_TRUE) == XML_STATUS_ERROR) 6011 xml_failure(parser); 6012 CharData_CheckXMLChars(&storage, expected); 6013 } 6014 END_TEST 6015 6016 /* Test element name that is long enough to fill the conversion buffer 6017 * in an unknown encoding, finishing with an simple character. 6018 */ 6019 START_TEST(test_unknown_encoding_long_name_2) 6020 { 6021 const char *text = 6022 "<?xml version='1.0' encoding='prefix-conv'?>\n" 6023 "<abcdefghabcdefghabcdefghijklmnop>" 6024 "Hi" 6025 "</abcdefghabcdefghabcdefghijklmnop>"; 6026 const XML_Char *expected = XCS("abcdefghabcdefghabcdefghijklmnop"); 6027 CharData storage; 6028 6029 CharData_Init(&storage); 6030 XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL); 6031 XML_SetStartElementHandler(parser, record_element_start_handler); 6032 XML_SetUserData(parser, &storage); 6033 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 6034 XML_TRUE) == XML_STATUS_ERROR) 6035 xml_failure(parser); 6036 CharData_CheckXMLChars(&storage, expected); 6037 } 6038 END_TEST 6039 6040 START_TEST(test_invalid_unknown_encoding) 6041 { 6042 const char *text = 6043 "<?xml version='1.0' encoding='invalid-9'?>\n" 6044 "<doc>Hello world</doc>"; 6045 6046 XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL); 6047 expect_failure(text, XML_ERROR_UNKNOWN_ENCODING, 6048 "Invalid unknown encoding not faulted"); 6049 } 6050 END_TEST 6051 6052 START_TEST(test_unknown_ascii_encoding_ok) 6053 { 6054 const char *text = 6055 "<?xml version='1.0' encoding='ascii-like'?>\n" 6056 "<doc>Hello, world</doc>"; 6057 6058 XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL); 6059 run_character_check(text, XCS("Hello, world")); 6060 } 6061 END_TEST 6062 6063 START_TEST(test_unknown_ascii_encoding_fail) 6064 { 6065 const char *text = 6066 "<?xml version='1.0' encoding='ascii-like'?>\n" 6067 "<doc>Hello, \x80 world</doc>"; 6068 6069 XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL); 6070 expect_failure(text, XML_ERROR_INVALID_TOKEN, 6071 "Invalid character not faulted"); 6072 } 6073 END_TEST 6074 6075 START_TEST(test_unknown_encoding_invalid_length) 6076 { 6077 const char *text = 6078 "<?xml version='1.0' encoding='invalid-len'?>\n" 6079 "<doc>Hello, world</doc>"; 6080 6081 XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL); 6082 expect_failure(text, XML_ERROR_UNKNOWN_ENCODING, 6083 "Invalid unknown encoding not faulted"); 6084 } 6085 END_TEST 6086 6087 START_TEST(test_unknown_encoding_invalid_topbit) 6088 { 6089 const char *text = 6090 "<?xml version='1.0' encoding='invalid-a'?>\n" 6091 "<doc>Hello, world</doc>"; 6092 6093 XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL); 6094 expect_failure(text, XML_ERROR_UNKNOWN_ENCODING, 6095 "Invalid unknown encoding not faulted"); 6096 } 6097 END_TEST 6098 6099 START_TEST(test_unknown_encoding_invalid_surrogate) 6100 { 6101 const char *text = 6102 "<?xml version='1.0' encoding='invalid-surrogate'?>\n" 6103 "<doc>Hello, \x82 world</doc>"; 6104 6105 XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL); 6106 expect_failure(text, XML_ERROR_INVALID_TOKEN, 6107 "Invalid unknown encoding not faulted"); 6108 } 6109 END_TEST 6110 6111 START_TEST(test_unknown_encoding_invalid_high) 6112 { 6113 const char *text = 6114 "<?xml version='1.0' encoding='invalid-high'?>\n" 6115 "<doc>Hello, world</doc>"; 6116 6117 XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL); 6118 expect_failure(text, XML_ERROR_UNKNOWN_ENCODING, 6119 "Invalid unknown encoding not faulted"); 6120 } 6121 END_TEST 6122 6123 START_TEST(test_unknown_encoding_invalid_attr_value) 6124 { 6125 const char *text = 6126 "<?xml version='1.0' encoding='prefix-conv'?>\n" 6127 "<doc attr='\xff\x30'/>"; 6128 6129 XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL); 6130 expect_failure(text, XML_ERROR_INVALID_TOKEN, 6131 "Invalid attribute valid not faulted"); 6132 } 6133 END_TEST 6134 6135 /* Test an external entity parser set to use latin-1 detects UTF-16 6136 * BOMs correctly. 6137 */ 6138 enum ee_parse_flags { 6139 EE_PARSE_NONE = 0x00, 6140 EE_PARSE_FULL_BUFFER = 0x01 6141 }; 6142 6143 typedef struct ExtTest2 { 6144 const char *parse_text; 6145 int parse_len; 6146 const XML_Char *encoding; 6147 CharData *storage; 6148 enum ee_parse_flags flags; 6149 } ExtTest2; 6150 6151 static int XMLCALL 6152 external_entity_loader2(XML_Parser parser, 6153 const XML_Char *context, 6154 const XML_Char *UNUSED_P(base), 6155 const XML_Char *UNUSED_P(systemId), 6156 const XML_Char *UNUSED_P(publicId)) 6157 { 6158 ExtTest2 *test_data = (ExtTest2 *)XML_GetUserData(parser); 6159 XML_Parser extparser; 6160 6161 extparser = XML_ExternalEntityParserCreate(parser, context, NULL); 6162 if (extparser == NULL) 6163 fail("Coulr not create external entity parser"); 6164 if (test_data->encoding != NULL) { 6165 if (!XML_SetEncoding(extparser, test_data->encoding)) 6166 fail("XML_SetEncoding() ignored for external entity"); 6167 } 6168 if (test_data->flags & EE_PARSE_FULL_BUFFER) { 6169 if (XML_Parse(extparser, 6170 test_data->parse_text, 6171 test_data->parse_len, 6172 XML_TRUE) == XML_STATUS_ERROR) { 6173 xml_failure(extparser); 6174 } 6175 } 6176 else if (_XML_Parse_SINGLE_BYTES(extparser, 6177 test_data->parse_text, 6178 test_data->parse_len, 6179 XML_TRUE) == XML_STATUS_ERROR) { 6180 xml_failure(extparser); 6181 } 6182 6183 XML_ParserFree(extparser); 6184 return XML_STATUS_OK; 6185 } 6186 6187 /* Test that UTF-16 BOM does not select UTF-16 given explicit encoding */ 6188 static void XMLCALL 6189 ext2_accumulate_characters(void *userData, const XML_Char *s, int len) 6190 { 6191 ExtTest2 *test_data = (ExtTest2 *)userData; 6192 accumulate_characters(test_data->storage, s, len); 6193 } 6194 6195 START_TEST(test_ext_entity_latin1_utf16le_bom) 6196 { 6197 const char *text = 6198 "<!DOCTYPE doc [\n" 6199 " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n" 6200 "]>\n" 6201 "<doc>&en;</doc>"; 6202 ExtTest2 test_data = { 6203 /* If UTF-16, 0xfeff is the BOM and 0x204c is black left bullet */ 6204 /* If Latin-1, 0xff = Y-diaeresis, 0xfe = lowercase thorn, 6205 * 0x4c = L and 0x20 is a space 6206 */ 6207 "\xff\xfe\x4c\x20", 6208 4, 6209 XCS("iso-8859-1"), 6210 NULL, 6211 EE_PARSE_NONE 6212 }; 6213 #ifdef XML_UNICODE 6214 const XML_Char *expected = XCS("\x00ff\x00feL "); 6215 #else 6216 /* In UTF-8, y-diaeresis is 0xc3 0xbf, lowercase thorn is 0xc3 0xbe */ 6217 const XML_Char *expected = XCS("\xc3\xbf\xc3\xbeL "); 6218 #endif 6219 CharData storage; 6220 6221 6222 CharData_Init(&storage); 6223 test_data.storage = &storage; 6224 XML_SetExternalEntityRefHandler(parser, external_entity_loader2); 6225 XML_SetUserData(parser, &test_data); 6226 XML_SetCharacterDataHandler(parser, ext2_accumulate_characters); 6227 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 6228 XML_TRUE) == XML_STATUS_ERROR) 6229 xml_failure(parser); 6230 CharData_CheckXMLChars(&storage, expected); 6231 } 6232 END_TEST 6233 6234 START_TEST(test_ext_entity_latin1_utf16be_bom) 6235 { 6236 const char *text = 6237 "<!DOCTYPE doc [\n" 6238 " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n" 6239 "]>\n" 6240 "<doc>&en;</doc>"; 6241 ExtTest2 test_data = { 6242 /* If UTF-16, 0xfeff is the BOM and 0x204c is black left bullet */ 6243 /* If Latin-1, 0xff = Y-diaeresis, 0xfe = lowercase thorn, 6244 * 0x4c = L and 0x20 is a space 6245 */ 6246 "\xfe\xff\x20\x4c", 6247 4, 6248 XCS("iso-8859-1"), 6249 NULL, 6250 EE_PARSE_NONE 6251 }; 6252 #ifdef XML_UNICODE 6253 const XML_Char *expected = XCS("\x00fe\x00ff L"); 6254 #else 6255 /* In UTF-8, y-diaeresis is 0xc3 0xbf, lowercase thorn is 0xc3 0xbe */ 6256 const XML_Char *expected = XCS("\xc3\xbe\xc3\xbf L"); 6257 #endif 6258 CharData storage; 6259 6260 6261 CharData_Init(&storage); 6262 test_data.storage = &storage; 6263 XML_SetExternalEntityRefHandler(parser, external_entity_loader2); 6264 XML_SetUserData(parser, &test_data); 6265 XML_SetCharacterDataHandler(parser, ext2_accumulate_characters); 6266 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 6267 XML_TRUE) == XML_STATUS_ERROR) 6268 xml_failure(parser); 6269 CharData_CheckXMLChars(&storage, expected); 6270 } 6271 END_TEST 6272 6273 6274 /* Parsing the full buffer rather than a byte at a time makes a 6275 * difference to the encoding scanning code, so repeat the above tests 6276 * without breaking them down by byte. 6277 */ 6278 START_TEST(test_ext_entity_latin1_utf16le_bom2) 6279 { 6280 const char *text = 6281 "<!DOCTYPE doc [\n" 6282 " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n" 6283 "]>\n" 6284 "<doc>&en;</doc>"; 6285 ExtTest2 test_data = { 6286 /* If UTF-16, 0xfeff is the BOM and 0x204c is black left bullet */ 6287 /* If Latin-1, 0xff = Y-diaeresis, 0xfe = lowercase thorn, 6288 * 0x4c = L and 0x20 is a space 6289 */ 6290 "\xff\xfe\x4c\x20", 6291 4, 6292 XCS("iso-8859-1"), 6293 NULL, 6294 EE_PARSE_FULL_BUFFER 6295 }; 6296 #ifdef XML_UNICODE 6297 const XML_Char *expected = XCS("\x00ff\x00feL "); 6298 #else 6299 /* In UTF-8, y-diaeresis is 0xc3 0xbf, lowercase thorn is 0xc3 0xbe */ 6300 const XML_Char *expected = XCS("\xc3\xbf\xc3\xbeL "); 6301 #endif 6302 CharData storage; 6303 6304 6305 CharData_Init(&storage); 6306 test_data.storage = &storage; 6307 XML_SetExternalEntityRefHandler(parser, external_entity_loader2); 6308 XML_SetUserData(parser, &test_data); 6309 XML_SetCharacterDataHandler(parser, ext2_accumulate_characters); 6310 if (XML_Parse(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR) 6311 xml_failure(parser); 6312 CharData_CheckXMLChars(&storage, expected); 6313 } 6314 END_TEST 6315 6316 START_TEST(test_ext_entity_latin1_utf16be_bom2) 6317 { 6318 const char *text = 6319 "<!DOCTYPE doc [\n" 6320 " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n" 6321 "]>\n" 6322 "<doc>&en;</doc>"; 6323 ExtTest2 test_data = { 6324 /* If UTF-16, 0xfeff is the BOM and 0x204c is black left bullet */ 6325 /* If Latin-1, 0xff = Y-diaeresis, 0xfe = lowercase thorn, 6326 * 0x4c = L and 0x20 is a space 6327 */ 6328 "\xfe\xff\x20\x4c", 6329 4, 6330 XCS("iso-8859-1"), 6331 NULL, 6332 EE_PARSE_FULL_BUFFER 6333 }; 6334 #ifdef XML_UNICODE 6335 const XML_Char *expected = XCS("\x00fe\x00ff L"); 6336 #else 6337 /* In UTF-8, y-diaeresis is 0xc3 0xbf, lowercase thorn is 0xc3 0xbe */ 6338 const XML_Char *expected = "\xc3\xbe\xc3\xbf L"; 6339 #endif 6340 CharData storage; 6341 6342 6343 CharData_Init(&storage); 6344 test_data.storage = &storage; 6345 XML_SetExternalEntityRefHandler(parser, external_entity_loader2); 6346 XML_SetUserData(parser, &test_data); 6347 XML_SetCharacterDataHandler(parser, ext2_accumulate_characters); 6348 if (XML_Parse(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR) 6349 xml_failure(parser); 6350 CharData_CheckXMLChars(&storage, expected); 6351 } 6352 END_TEST 6353 6354 /* Test little-endian UTF-16 given an explicit big-endian encoding */ 6355 START_TEST(test_ext_entity_utf16_be) 6356 { 6357 const char *text = 6358 "<!DOCTYPE doc [\n" 6359 " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n" 6360 "]>\n" 6361 "<doc>&en;</doc>"; 6362 ExtTest2 test_data = { 6363 "<\0e\0/\0>\0", 6364 8, 6365 XCS("utf-16be"), 6366 NULL, 6367 EE_PARSE_NONE 6368 }; 6369 #ifdef XML_UNICODE 6370 const XML_Char *expected = XCS("\x3c00\x6500\x2f00\x3e00"); 6371 #else 6372 const XML_Char *expected = 6373 XCS("\xe3\xb0\x80" /* U+3C00 */ 6374 "\xe6\x94\x80" /* U+6500 */ 6375 "\xe2\xbc\x80" /* U+2F00 */ 6376 "\xe3\xb8\x80"); /* U+3E00 */ 6377 #endif 6378 CharData storage; 6379 6380 CharData_Init(&storage); 6381 test_data.storage = &storage; 6382 XML_SetExternalEntityRefHandler(parser, external_entity_loader2); 6383 XML_SetUserData(parser, &test_data); 6384 XML_SetCharacterDataHandler(parser, ext2_accumulate_characters); 6385 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 6386 XML_TRUE) == XML_STATUS_ERROR) 6387 xml_failure(parser); 6388 CharData_CheckXMLChars(&storage, expected); 6389 } 6390 END_TEST 6391 6392 /* Test big-endian UTF-16 given an explicit little-endian encoding */ 6393 START_TEST(test_ext_entity_utf16_le) 6394 { 6395 const char *text = 6396 "<!DOCTYPE doc [\n" 6397 " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n" 6398 "]>\n" 6399 "<doc>&en;</doc>"; 6400 ExtTest2 test_data = { 6401 "\0<\0e\0/\0>", 6402 8, 6403 XCS("utf-16le"), 6404 NULL, 6405 EE_PARSE_NONE 6406 }; 6407 #ifdef XML_UNICODE 6408 const XML_Char *expected = XCS("\x3c00\x6500\x2f00\x3e00"); 6409 #else 6410 const XML_Char *expected = 6411 XCS("\xe3\xb0\x80" /* U+3C00 */ 6412 "\xe6\x94\x80" /* U+6500 */ 6413 "\xe2\xbc\x80" /* U+2F00 */ 6414 "\xe3\xb8\x80"); /* U+3E00 */ 6415 #endif 6416 CharData storage; 6417 6418 CharData_Init(&storage); 6419 test_data.storage = &storage; 6420 XML_SetExternalEntityRefHandler(parser, external_entity_loader2); 6421 XML_SetUserData(parser, &test_data); 6422 XML_SetCharacterDataHandler(parser, ext2_accumulate_characters); 6423 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 6424 XML_TRUE) == XML_STATUS_ERROR) 6425 xml_failure(parser); 6426 CharData_CheckXMLChars(&storage, expected); 6427 } 6428 END_TEST 6429 6430 /* Test little-endian UTF-16 given no explicit encoding. 6431 * The existing default encoding (UTF-8) is assumed to hold without a 6432 * BOM to contradict it, so the entity value will in fact provoke an 6433 * error because 0x00 is not a valid XML character. We parse the 6434 * whole buffer in one go rather than feeding it in byte by byte to 6435 * exercise different code paths in the initial scanning routines. 6436 */ 6437 typedef struct ExtFaults2 { 6438 const char *parse_text; 6439 int parse_len; 6440 const char *fail_text; 6441 const XML_Char *encoding; 6442 enum XML_Error error; 6443 } ExtFaults2; 6444 6445 static int XMLCALL 6446 external_entity_faulter2(XML_Parser parser, 6447 const XML_Char *context, 6448 const XML_Char *UNUSED_P(base), 6449 const XML_Char *UNUSED_P(systemId), 6450 const XML_Char *UNUSED_P(publicId)) 6451 { 6452 ExtFaults2 *test_data = (ExtFaults2 *)XML_GetUserData(parser); 6453 XML_Parser extparser; 6454 6455 extparser = XML_ExternalEntityParserCreate(parser, context, NULL); 6456 if (extparser == NULL) 6457 fail("Could not create external entity parser"); 6458 if (test_data->encoding != NULL) { 6459 if (!XML_SetEncoding(extparser, test_data->encoding)) 6460 fail("XML_SetEncoding() ignored for external entity"); 6461 } 6462 if (XML_Parse(extparser, 6463 test_data->parse_text, 6464 test_data->parse_len, 6465 XML_TRUE) != XML_STATUS_ERROR) 6466 fail(test_data->fail_text); 6467 if (XML_GetErrorCode(extparser) != test_data->error) 6468 xml_failure(extparser); 6469 6470 XML_ParserFree(extparser); 6471 return XML_STATUS_ERROR; 6472 } 6473 6474 START_TEST(test_ext_entity_utf16_unknown) 6475 { 6476 const char *text = 6477 "<!DOCTYPE doc [\n" 6478 " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n" 6479 "]>\n" 6480 "<doc>&en;</doc>"; 6481 ExtFaults2 test_data = { 6482 "a\0b\0c\0", 6483 6, 6484 "Invalid character in entity not faulted", 6485 NULL, 6486 XML_ERROR_INVALID_TOKEN 6487 }; 6488 6489 XML_SetExternalEntityRefHandler(parser, external_entity_faulter2); 6490 XML_SetUserData(parser, &test_data); 6491 expect_failure(text, XML_ERROR_EXTERNAL_ENTITY_HANDLING, 6492 "Invalid character should not have been accepted"); 6493 } 6494 END_TEST 6495 6496 /* Test not-quite-UTF-8 BOM (0xEF 0xBB 0xBF) */ 6497 START_TEST(test_ext_entity_utf8_non_bom) 6498 { 6499 const char *text = 6500 "<!DOCTYPE doc [\n" 6501 " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n" 6502 "]>\n" 6503 "<doc>&en;</doc>"; 6504 ExtTest2 test_data = { 6505 "\xef\xbb\x80", /* Arabic letter DAD medial form, U+FEC0 */ 6506 3, 6507 NULL, 6508 NULL, 6509 EE_PARSE_NONE 6510 }; 6511 #ifdef XML_UNICODE 6512 const XML_Char *expected = XCS("\xfec0"); 6513 #else 6514 const XML_Char *expected = XCS("\xef\xbb\x80"); 6515 #endif 6516 CharData storage; 6517 6518 CharData_Init(&storage); 6519 test_data.storage = &storage; 6520 XML_SetExternalEntityRefHandler(parser, external_entity_loader2); 6521 XML_SetUserData(parser, &test_data); 6522 XML_SetCharacterDataHandler(parser, ext2_accumulate_characters); 6523 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 6524 XML_TRUE) == XML_STATUS_ERROR) 6525 xml_failure(parser); 6526 CharData_CheckXMLChars(&storage, expected); 6527 } 6528 END_TEST 6529 6530 /* Test that UTF-8 in a CDATA section is correctly passed through */ 6531 START_TEST(test_utf8_in_cdata_section) 6532 { 6533 const char *text = "<doc><![CDATA[one \xc3\xa9 two]]></doc>"; 6534 #ifdef XML_UNICODE 6535 const XML_Char *expected = XCS("one \x00e9 two"); 6536 #else 6537 const XML_Char *expected = XCS("one \xc3\xa9 two"); 6538 #endif 6539 6540 run_character_check(text, expected); 6541 } 6542 END_TEST 6543 6544 /* Test that little-endian UTF-16 in a CDATA section is handled */ 6545 START_TEST(test_utf8_in_cdata_section_2) 6546 { 6547 const char *text = "<doc><![CDATA[\xc3\xa9]\xc3\xa9two]]></doc>"; 6548 #ifdef XML_UNICODE 6549 const XML_Char *expected = XCS("\x00e9]\x00e9two"); 6550 #else 6551 const XML_Char *expected = XCS("\xc3\xa9]\xc3\xa9two"); 6552 #endif 6553 6554 run_character_check(text, expected); 6555 } 6556 END_TEST 6557 6558 /* Test trailing spaces in elements are accepted */ 6559 static void XMLCALL 6560 record_element_end_handler(void *userData, 6561 const XML_Char *name) 6562 { 6563 CharData *storage = (CharData *)userData; 6564 6565 CharData_AppendXMLChars(storage, XCS("/"), 1); 6566 CharData_AppendXMLChars(storage, name, -1); 6567 } 6568 6569 START_TEST(test_trailing_spaces_in_elements) 6570 { 6571 const char *text = "<doc >Hi</doc >"; 6572 const XML_Char *expected = XCS("doc/doc"); 6573 CharData storage; 6574 6575 CharData_Init(&storage); 6576 XML_SetElementHandler(parser, record_element_start_handler, 6577 record_element_end_handler); 6578 XML_SetUserData(parser, &storage); 6579 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 6580 XML_TRUE) == XML_STATUS_ERROR) 6581 xml_failure(parser); 6582 CharData_CheckXMLChars(&storage, expected); 6583 } 6584 END_TEST 6585 6586 START_TEST(test_utf16_attribute) 6587 { 6588 const char text[] = 6589 /* <d {KHO KHWAI}{CHO CHAN}='a'/> 6590 * where {KHO KHWAI} = U+0E04 = 0xe0 0xb8 0x84 in UTF-8 6591 * and {CHO CHAN} = U+0E08 = 0xe0 0xb8 0x88 in UTF-8 6592 */ 6593 "<\0d\0 \0\x04\x0e\x08\x0e=\0'\0a\0'\0/\0>\0"; 6594 const XML_Char *expected = XCS("a"); 6595 CharData storage; 6596 6597 CharData_Init(&storage); 6598 XML_SetStartElementHandler(parser, accumulate_attribute); 6599 XML_SetUserData(parser, &storage); 6600 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text)-1, 6601 XML_TRUE) == XML_STATUS_ERROR) 6602 xml_failure(parser); 6603 CharData_CheckXMLChars(&storage, expected); 6604 } 6605 END_TEST 6606 6607 START_TEST(test_utf16_second_attr) 6608 { 6609 /* <d a='1' {KHO KHWAI}{CHO CHAN}='2'/> 6610 * where {KHO KHWAI} = U+0E04 = 0xe0 0xb8 0x84 in UTF-8 6611 * and {CHO CHAN} = U+0E08 = 0xe0 0xb8 0x88 in UTF-8 6612 */ 6613 const char text[] = 6614 "<\0d\0 \0a\0=\0'\0\x31\0'\0 \0" 6615 "\x04\x0e\x08\x0e=\0'\0\x32\0'\0/\0>\0"; 6616 const XML_Char *expected = XCS("1"); 6617 CharData storage; 6618 6619 CharData_Init(&storage); 6620 XML_SetStartElementHandler(parser, accumulate_attribute); 6621 XML_SetUserData(parser, &storage); 6622 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text)-1, 6623 XML_TRUE) == XML_STATUS_ERROR) 6624 xml_failure(parser); 6625 CharData_CheckXMLChars(&storage, expected); 6626 } 6627 END_TEST 6628 6629 START_TEST(test_attr_after_solidus) 6630 { 6631 const char *text = "<doc attr1='a' / attr2='b'>"; 6632 6633 expect_failure(text, XML_ERROR_INVALID_TOKEN, 6634 "Misplaced / not faulted"); 6635 } 6636 END_TEST 6637 6638 static void XMLCALL 6639 accumulate_entity_decl(void *userData, 6640 const XML_Char *entityName, 6641 int UNUSED_P(is_parameter_entity), 6642 const XML_Char *value, 6643 int value_length, 6644 const XML_Char *UNUSED_P(base), 6645 const XML_Char *UNUSED_P(systemId), 6646 const XML_Char *UNUSED_P(publicId), 6647 const XML_Char *UNUSED_P(notationName)) 6648 { 6649 CharData *storage = (CharData *)userData; 6650 6651 CharData_AppendXMLChars(storage, entityName, -1); 6652 CharData_AppendXMLChars(storage, XCS("="), 1); 6653 CharData_AppendXMLChars(storage, value, value_length); 6654 CharData_AppendXMLChars(storage, XCS("\n"), 1); 6655 } 6656 6657 6658 START_TEST(test_utf16_pe) 6659 { 6660 /* <!DOCTYPE doc [ 6661 * <!ENTITY % {KHO KHWAI}{CHO CHAN} '<!ELEMENT doc (#PCDATA)>'> 6662 * %{KHO KHWAI}{CHO CHAN}; 6663 * ]> 6664 * <doc></doc> 6665 * 6666 * where {KHO KHWAI} = U+0E04 = 0xe0 0xb8 0x84 in UTF-8 6667 * and {CHO CHAN} = U+0E08 = 0xe0 0xb8 0x88 in UTF-8 6668 */ 6669 const char text[] = 6670 "\0<\0!\0D\0O\0C\0T\0Y\0P\0E\0 \0d\0o\0c\0 \0[\0\n" 6671 "\0<\0!\0E\0N\0T\0I\0T\0Y\0 \0%\0 \x0e\x04\x0e\x08\0 " 6672 "\0'\0<\0!\0E\0L\0E\0M\0E\0N\0T\0 " 6673 "\0d\0o\0c\0 \0(\0#\0P\0C\0D\0A\0T\0A\0)\0>\0'\0>\0\n" 6674 "\0%\x0e\x04\x0e\x08\0;\0\n" 6675 "\0]\0>\0\n" 6676 "\0<\0d\0o\0c\0>\0<\0/\0d\0o\0c\0>"; 6677 #ifdef XML_UNICODE 6678 const XML_Char *expected = 6679 XCS("\x0e04\x0e08=<!ELEMENT doc (#PCDATA)>\n"); 6680 #else 6681 const XML_Char *expected = 6682 XCS("\xe0\xb8\x84\xe0\xb8\x88=<!ELEMENT doc (#PCDATA)>\n"); 6683 #endif 6684 CharData storage; 6685 6686 CharData_Init(&storage); 6687 XML_SetUserData(parser, &storage); 6688 XML_SetEntityDeclHandler(parser, accumulate_entity_decl); 6689 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text)-1, 6690 XML_TRUE) == XML_STATUS_ERROR) 6691 xml_failure(parser); 6692 CharData_CheckXMLChars(&storage, expected); 6693 } 6694 END_TEST 6695 6696 /* Test that duff attribute description keywords are rejected */ 6697 START_TEST(test_bad_attr_desc_keyword) 6698 { 6699 const char *text = 6700 "<!DOCTYPE doc [\n" 6701 " <!ATTLIST doc attr CDATA #!IMPLIED>\n" 6702 "]>\n" 6703 "<doc />"; 6704 6705 expect_failure(text, XML_ERROR_INVALID_TOKEN, 6706 "Bad keyword !IMPLIED not faulted"); 6707 } 6708 END_TEST 6709 6710 /* Test that an invalid attribute description keyword consisting of 6711 * UTF-16 characters with their top bytes non-zero are correctly 6712 * faulted 6713 */ 6714 START_TEST(test_bad_attr_desc_keyword_utf16) 6715 { 6716 /* <!DOCTYPE d [ 6717 * <!ATTLIST d a CDATA #{KHO KHWAI}{CHO CHAN}> 6718 * ]><d/> 6719 * 6720 * where {KHO KHWAI} = U+0E04 = 0xe0 0xb8 0x84 in UTF-8 6721 * and {CHO CHAN} = U+0E08 = 0xe0 0xb8 0x88 in UTF-8 6722 */ 6723 const char text[] = 6724 "\0<\0!\0D\0O\0C\0T\0Y\0P\0E\0 \0d\0 \0[\0\n" 6725 "\0<\0!\0A\0T\0T\0L\0I\0S\0T\0 \0d\0 \0a\0 \0C\0D\0A\0T\0A\0 " 6726 "\0#\x0e\x04\x0e\x08\0>\0\n" 6727 "\0]\0>\0<\0d\0/\0>"; 6728 6729 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text)-1, 6730 XML_TRUE) != XML_STATUS_ERROR) 6731 fail("Invalid UTF16 attribute keyword not faulted"); 6732 if (XML_GetErrorCode(parser) != XML_ERROR_SYNTAX) 6733 xml_failure(parser); 6734 } 6735 END_TEST 6736 6737 /* Test that invalid syntax in a <!DOCTYPE> is rejected. Do this 6738 * using prefix-encoding (see above) to trigger specific code paths 6739 */ 6740 START_TEST(test_bad_doctype) 6741 { 6742 const char *text = 6743 "<?xml version='1.0' encoding='prefix-conv'?>\n" 6744 "<!DOCTYPE doc [ \x80\x44 ]><doc/>"; 6745 6746 XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL); 6747 expect_failure(text, XML_ERROR_SYNTAX, 6748 "Invalid bytes in DOCTYPE not faulted"); 6749 } 6750 END_TEST 6751 6752 START_TEST(test_bad_doctype_utf16) 6753 { 6754 const char text[] = 6755 /* <!DOCTYPE doc [ \x06f2 ]><doc/> 6756 * 6757 * U+06F2 = EXTENDED ARABIC-INDIC DIGIT TWO, a valid number 6758 * (name character) but not a valid letter (name start character) 6759 */ 6760 "\0<\0!\0D\0O\0C\0T\0Y\0P\0E\0 \0d\0o\0c\0 \0[\0 " 6761 "\x06\xf2" 6762 "\0 \0]\0>\0<\0d\0o\0c\0/\0>"; 6763 6764 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text)-1, 6765 XML_TRUE) != XML_STATUS_ERROR) 6766 fail("Invalid bytes in DOCTYPE not faulted"); 6767 if (XML_GetErrorCode(parser) != XML_ERROR_SYNTAX) 6768 xml_failure(parser); 6769 } 6770 END_TEST 6771 6772 START_TEST(test_bad_doctype_plus) 6773 { 6774 const char *text = 6775 "<!DOCTYPE 1+ [ <!ENTITY foo 'bar'> ]>\n" 6776 "<1+>&foo;</1+>"; 6777 6778 expect_failure(text, XML_ERROR_INVALID_TOKEN, 6779 "'+' in document name not faulted"); 6780 } 6781 END_TEST 6782 6783 START_TEST(test_bad_doctype_star) 6784 { 6785 const char *text = 6786 "<!DOCTYPE 1* [ <!ENTITY foo 'bar'> ]>\n" 6787 "<1*>&foo;</1*>"; 6788 6789 expect_failure(text, XML_ERROR_INVALID_TOKEN, 6790 "'*' in document name not faulted"); 6791 } 6792 END_TEST 6793 6794 START_TEST(test_bad_doctype_query) 6795 { 6796 const char *text = 6797 "<!DOCTYPE 1? [ <!ENTITY foo 'bar'> ]>\n" 6798 "<1?>&foo;</1?>"; 6799 6800 expect_failure(text, XML_ERROR_INVALID_TOKEN, 6801 "'?' in document name not faulted"); 6802 } 6803 END_TEST 6804 6805 START_TEST(test_unknown_encoding_bad_ignore) 6806 { 6807 const char *text = 6808 "<?xml version='1.0' encoding='prefix-conv'?>" 6809 "<!DOCTYPE doc SYSTEM 'foo'>" 6810 "<doc><e>&entity;</e></doc>"; 6811 ExtFaults fault = { 6812 "<![IGNORE[<!ELEMENT \xffG (#PCDATA)*>]]>", 6813 "Invalid character not faulted", 6814 XCS("prefix-conv"), 6815 XML_ERROR_INVALID_TOKEN 6816 }; 6817 6818 XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL); 6819 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 6820 XML_SetExternalEntityRefHandler(parser, external_entity_faulter); 6821 XML_SetUserData(parser, &fault); 6822 expect_failure(text, XML_ERROR_EXTERNAL_ENTITY_HANDLING, 6823 "Bad IGNORE section with unknown encoding not failed"); 6824 } 6825 END_TEST 6826 6827 START_TEST(test_entity_in_utf16_be_attr) 6828 { 6829 const char text[] = 6830 /* <e a='ä ä'></e> */ 6831 "\0<\0e\0 \0a\0=\0'\0&\0#\0\x32\0\x32\0\x38\0;\0 " 6832 "\0&\0#\0x\0\x30\0\x30\0E\0\x34\0;\0'\0>\0<\0/\0e\0>"; 6833 #ifdef XML_UNICODE 6834 const XML_Char *expected = XCS("\x00e4 \x00e4"); 6835 #else 6836 const XML_Char *expected = XCS("\xc3\xa4 \xc3\xa4"); 6837 #endif 6838 CharData storage; 6839 6840 CharData_Init(&storage); 6841 XML_SetUserData(parser, &storage); 6842 XML_SetStartElementHandler(parser, accumulate_attribute); 6843 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text)-1, 6844 XML_TRUE) == XML_STATUS_ERROR) 6845 xml_failure(parser); 6846 CharData_CheckXMLChars(&storage, expected); 6847 } 6848 END_TEST 6849 6850 START_TEST(test_entity_in_utf16_le_attr) 6851 { 6852 const char text[] = 6853 /* <e a='ä ä'></e> */ 6854 "<\0e\0 \0a\0=\0'\0&\0#\0\x32\0\x32\0\x38\0;\0 \0" 6855 "&\0#\0x\0\x30\0\x30\0E\0\x34\0;\0'\0>\0<\0/\0e\0>\0"; 6856 #ifdef XML_UNICODE 6857 const XML_Char *expected = XCS("\x00e4 \x00e4"); 6858 #else 6859 const XML_Char *expected = XCS("\xc3\xa4 \xc3\xa4"); 6860 #endif 6861 CharData storage; 6862 6863 CharData_Init(&storage); 6864 XML_SetUserData(parser, &storage); 6865 XML_SetStartElementHandler(parser, accumulate_attribute); 6866 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text)-1, 6867 XML_TRUE) == XML_STATUS_ERROR) 6868 xml_failure(parser); 6869 CharData_CheckXMLChars(&storage, expected); 6870 } 6871 END_TEST 6872 6873 START_TEST(test_entity_public_utf16_be) 6874 { 6875 const char text[] = 6876 /* <!DOCTYPE d [ */ 6877 "\0<\0!\0D\0O\0C\0T\0Y\0P\0E\0 \0d\0 \0[\0\n" 6878 /* <!ENTITY % e PUBLIC 'foo' 'bar.ent'> */ 6879 "\0<\0!\0E\0N\0T\0I\0T\0Y\0 \0%\0 \0e\0 \0P\0U\0B\0L\0I\0C\0 " 6880 "\0'\0f\0o\0o\0'\0 \0'\0b\0a\0r\0.\0e\0n\0t\0'\0>\0\n" 6881 /* %e; */ 6882 "\0%\0e\0;\0\n" 6883 /* ]> */ 6884 "\0]\0>\0\n" 6885 /* <d>&j;</d> */ 6886 "\0<\0d\0>\0&\0j\0;\0<\0/\0d\0>"; 6887 ExtTest2 test_data = { 6888 /* <!ENTITY j 'baz'> */ 6889 "\0<\0!\0E\0N\0T\0I\0T\0Y\0 \0j\0 \0'\0b\0a\0z\0'\0>", 6890 34, 6891 NULL, 6892 NULL, 6893 EE_PARSE_NONE 6894 }; 6895 const XML_Char *expected = XCS("baz"); 6896 CharData storage; 6897 6898 CharData_Init(&storage); 6899 test_data.storage = &storage; 6900 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 6901 XML_SetExternalEntityRefHandler(parser, external_entity_loader2); 6902 XML_SetUserData(parser, &test_data); 6903 XML_SetCharacterDataHandler(parser, ext2_accumulate_characters); 6904 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text)-1, 6905 XML_TRUE) == XML_STATUS_ERROR) 6906 xml_failure(parser); 6907 CharData_CheckXMLChars(&storage, expected); 6908 } 6909 END_TEST 6910 6911 START_TEST(test_entity_public_utf16_le) 6912 { 6913 const char text[] = 6914 /* <!DOCTYPE d [ */ 6915 "<\0!\0D\0O\0C\0T\0Y\0P\0E\0 \0d\0 \0[\0\n\0" 6916 /* <!ENTITY % e PUBLIC 'foo' 'bar.ent'> */ 6917 "<\0!\0E\0N\0T\0I\0T\0Y\0 \0%\0 \0e\0 \0P\0U\0B\0L\0I\0C\0 \0" 6918 "'\0f\0o\0o\0'\0 \0'\0b\0a\0r\0.\0e\0n\0t\0'\0>\0\n\0" 6919 /* %e; */ 6920 "%\0e\0;\0\n\0" 6921 /* ]> */ 6922 "]\0>\0\n\0" 6923 /* <d>&j;</d> */ 6924 "<\0d\0>\0&\0j\0;\0<\0/\0d\0>\0"; 6925 ExtTest2 test_data = { 6926 /* <!ENTITY j 'baz'> */ 6927 "<\0!\0E\0N\0T\0I\0T\0Y\0 \0j\0 \0'\0b\0a\0z\0'\0>\0", 6928 34, 6929 NULL, 6930 NULL, 6931 EE_PARSE_NONE 6932 }; 6933 const XML_Char *expected = XCS("baz"); 6934 CharData storage; 6935 6936 CharData_Init(&storage); 6937 test_data.storage = &storage; 6938 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 6939 XML_SetExternalEntityRefHandler(parser, external_entity_loader2); 6940 XML_SetUserData(parser, &test_data); 6941 XML_SetCharacterDataHandler(parser, ext2_accumulate_characters); 6942 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text)-1, 6943 XML_TRUE) == XML_STATUS_ERROR) 6944 xml_failure(parser); 6945 CharData_CheckXMLChars(&storage, expected); 6946 } 6947 END_TEST 6948 6949 /* Test that a doctype with neither an internal nor external subset is 6950 * faulted 6951 */ 6952 START_TEST(test_short_doctype) 6953 { 6954 const char *text = "<!DOCTYPE doc></doc>"; 6955 expect_failure(text, XML_ERROR_INVALID_TOKEN, 6956 "DOCTYPE without subset not rejected"); 6957 } 6958 END_TEST 6959 6960 START_TEST(test_short_doctype_2) 6961 { 6962 const char *text = "<!DOCTYPE doc PUBLIC></doc>"; 6963 expect_failure(text, XML_ERROR_SYNTAX, 6964 "DOCTYPE without Public ID not rejected"); 6965 } 6966 END_TEST 6967 6968 START_TEST(test_short_doctype_3) 6969 { 6970 const char *text = "<!DOCTYPE doc SYSTEM></doc>"; 6971 expect_failure(text, XML_ERROR_SYNTAX, 6972 "DOCTYPE without System ID not rejected"); 6973 } 6974 END_TEST 6975 6976 START_TEST(test_long_doctype) 6977 { 6978 const char *text = "<!DOCTYPE doc PUBLIC 'foo' 'bar' 'baz'></doc>"; 6979 expect_failure(text, XML_ERROR_SYNTAX, 6980 "DOCTYPE with extra ID not rejected"); 6981 } 6982 END_TEST 6983 6984 START_TEST(test_bad_entity) 6985 { 6986 const char *text = 6987 "<!DOCTYPE doc [\n" 6988 " <!ENTITY foo PUBLIC>\n" 6989 "]>\n" 6990 "<doc/>"; 6991 expect_failure(text, XML_ERROR_SYNTAX, 6992 "ENTITY without Public ID is not rejected"); 6993 } 6994 END_TEST 6995 6996 /* Test unquoted value is faulted */ 6997 START_TEST(test_bad_entity_2) 6998 { 6999 const char *text = 7000 "<!DOCTYPE doc [\n" 7001 " <!ENTITY % foo bar>\n" 7002 "]>\n" 7003 "<doc/>"; 7004 expect_failure(text, XML_ERROR_SYNTAX, 7005 "ENTITY without Public ID is not rejected"); 7006 } 7007 END_TEST 7008 7009 START_TEST(test_bad_entity_3) 7010 { 7011 const char *text = 7012 "<!DOCTYPE doc [\n" 7013 " <!ENTITY % foo PUBLIC>\n" 7014 "]>\n" 7015 "<doc/>"; 7016 expect_failure(text, XML_ERROR_SYNTAX, 7017 "Parameter ENTITY without Public ID is not rejected"); 7018 } 7019 END_TEST 7020 7021 START_TEST(test_bad_entity_4) 7022 { 7023 const char *text = 7024 "<!DOCTYPE doc [\n" 7025 " <!ENTITY % foo SYSTEM>\n" 7026 "]>\n" 7027 "<doc/>"; 7028 expect_failure(text, XML_ERROR_SYNTAX, 7029 "Parameter ENTITY without Public ID is not rejected"); 7030 } 7031 END_TEST 7032 7033 START_TEST(test_bad_notation) 7034 { 7035 const char *text = 7036 "<!DOCTYPE doc [\n" 7037 " <!NOTATION n SYSTEM>\n" 7038 "]>\n" 7039 "<doc/>"; 7040 expect_failure(text, XML_ERROR_SYNTAX, 7041 "Notation without System ID is not rejected"); 7042 } 7043 END_TEST 7044 7045 /* Test for issue #11, wrongly suppressed default handler */ 7046 typedef struct default_check { 7047 const XML_Char *expected; 7048 const int expectedLen; 7049 XML_Bool seen; 7050 } DefaultCheck; 7051 7052 static void XMLCALL 7053 checking_default_handler(void *userData, 7054 const XML_Char *s, 7055 int len) 7056 { 7057 DefaultCheck *data = (DefaultCheck *)userData; 7058 int i; 7059 7060 for (i = 0; data[i].expected != NULL; i++) { 7061 if (data[i].expectedLen == len && 7062 !memcmp(data[i].expected, s, len * sizeof(XML_Char))) { 7063 data[i].seen = XML_TRUE; 7064 break; 7065 } 7066 } 7067 } 7068 7069 START_TEST(test_default_doctype_handler) 7070 { 7071 const char *text = 7072 "<!DOCTYPE doc PUBLIC 'pubname' 'test.dtd' [\n" 7073 " <!ENTITY foo 'bar'>\n" 7074 "]>\n" 7075 "<doc>&foo;</doc>"; 7076 DefaultCheck test_data[] = { 7077 { 7078 XCS("'pubname'"), 7079 9, 7080 XML_FALSE 7081 }, 7082 { 7083 XCS("'test.dtd'"), 7084 10, 7085 XML_FALSE 7086 }, 7087 { NULL, 0, XML_FALSE } 7088 }; 7089 int i; 7090 7091 XML_SetUserData(parser, &test_data); 7092 XML_SetDefaultHandler(parser, checking_default_handler); 7093 XML_SetEntityDeclHandler(parser, dummy_entity_decl_handler); 7094 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 7095 XML_TRUE) == XML_STATUS_ERROR) 7096 xml_failure(parser); 7097 for (i = 0; test_data[i].expected != NULL; i++) 7098 if (!test_data[i].seen) 7099 fail("Default handler not run for public !DOCTYPE"); 7100 } 7101 END_TEST 7102 7103 START_TEST(test_empty_element_abort) 7104 { 7105 const char *text = "<abort/>"; 7106 7107 XML_SetStartElementHandler(parser, start_element_suspender); 7108 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 7109 XML_TRUE) != XML_STATUS_ERROR) 7110 fail("Expected to error on abort"); 7111 } 7112 END_TEST 7113 7114 /* 7115 * Namespaces tests. 7116 */ 7117 7118 static void 7119 namespace_setup(void) 7120 { 7121 parser = XML_ParserCreateNS(NULL, XCS(' ')); 7122 if (parser == NULL) 7123 fail("Parser not created."); 7124 } 7125 7126 static void 7127 namespace_teardown(void) 7128 { 7129 basic_teardown(); 7130 } 7131 7132 /* Check that an element name and attribute name match the expected values. 7133 The expected values are passed as an array reference of string pointers 7134 provided as the userData argument; the first is the expected 7135 element name, and the second is the expected attribute name. 7136 */ 7137 static int triplet_start_flag = XML_FALSE; 7138 static int triplet_end_flag = XML_FALSE; 7139 7140 static void XMLCALL 7141 triplet_start_checker(void *userData, const XML_Char *name, 7142 const XML_Char **atts) 7143 { 7144 XML_Char **elemstr = (XML_Char **)userData; 7145 char buffer[1024]; 7146 if (xcstrcmp(elemstr[0], name) != 0) { 7147 sprintf(buffer, "unexpected start string: '%" XML_FMT_STR "'", name); 7148 fail(buffer); 7149 } 7150 if (xcstrcmp(elemstr[1], atts[0]) != 0) { 7151 sprintf(buffer, "unexpected attribute string: '%" XML_FMT_STR "'", 7152 atts[0]); 7153 fail(buffer); 7154 } 7155 triplet_start_flag = XML_TRUE; 7156 } 7157 7158 /* Check that the element name passed to the end-element handler matches 7159 the expected value. The expected value is passed as the first element 7160 in an array of strings passed as the userData argument. 7161 */ 7162 static void XMLCALL 7163 triplet_end_checker(void *userData, const XML_Char *name) 7164 { 7165 XML_Char **elemstr = (XML_Char **)userData; 7166 if (xcstrcmp(elemstr[0], name) != 0) { 7167 char buffer[1024]; 7168 sprintf(buffer, "unexpected end string: '%" XML_FMT_STR "'", name); 7169 fail(buffer); 7170 } 7171 triplet_end_flag = XML_TRUE; 7172 } 7173 7174 START_TEST(test_return_ns_triplet) 7175 { 7176 const char *text = 7177 "<foo:e xmlns:foo='http://example.org/' bar:a='12'\n" 7178 " xmlns:bar='http://example.org/'>"; 7179 const char *epilog = "</foo:e>"; 7180 const XML_Char *elemstr[] = { 7181 XCS("http://example.org/ e foo"), 7182 XCS("http://example.org/ a bar") 7183 }; 7184 XML_SetReturnNSTriplet(parser, XML_TRUE); 7185 XML_SetUserData(parser, (void *)elemstr); 7186 XML_SetElementHandler(parser, triplet_start_checker, 7187 triplet_end_checker); 7188 XML_SetNamespaceDeclHandler(parser, 7189 dummy_start_namespace_decl_handler, 7190 dummy_end_namespace_decl_handler); 7191 triplet_start_flag = XML_FALSE; 7192 triplet_end_flag = XML_FALSE; 7193 dummy_handler_flags = 0; 7194 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 7195 XML_FALSE) == XML_STATUS_ERROR) 7196 xml_failure(parser); 7197 if (!triplet_start_flag) 7198 fail("triplet_start_checker not invoked"); 7199 /* Check that unsetting "return triplets" fails while still parsing */ 7200 XML_SetReturnNSTriplet(parser, XML_FALSE); 7201 if (_XML_Parse_SINGLE_BYTES(parser, epilog, (int)strlen(epilog), 7202 XML_TRUE) == XML_STATUS_ERROR) 7203 xml_failure(parser); 7204 if (!triplet_end_flag) 7205 fail("triplet_end_checker not invoked"); 7206 if (dummy_handler_flags != (DUMMY_START_NS_DECL_HANDLER_FLAG | 7207 DUMMY_END_NS_DECL_HANDLER_FLAG)) 7208 fail("Namespace handlers not called"); 7209 } 7210 END_TEST 7211 7212 static void XMLCALL 7213 overwrite_start_checker(void *userData, const XML_Char *name, 7214 const XML_Char **atts) 7215 { 7216 CharData *storage = (CharData *) userData; 7217 CharData_AppendXMLChars(storage, XCS("start "), 6); 7218 CharData_AppendXMLChars(storage, name, -1); 7219 while (*atts != NULL) { 7220 CharData_AppendXMLChars(storage, XCS("\nattribute "), 11); 7221 CharData_AppendXMLChars(storage, *atts, -1); 7222 atts += 2; 7223 } 7224 CharData_AppendXMLChars(storage, XCS("\n"), 1); 7225 } 7226 7227 static void XMLCALL 7228 overwrite_end_checker(void *userData, const XML_Char *name) 7229 { 7230 CharData *storage = (CharData *) userData; 7231 CharData_AppendXMLChars(storage, XCS("end "), 4); 7232 CharData_AppendXMLChars(storage, name, -1); 7233 CharData_AppendXMLChars(storage, XCS("\n"), 1); 7234 } 7235 7236 static void 7237 run_ns_tagname_overwrite_test(const char *text, const XML_Char *result) 7238 { 7239 CharData storage; 7240 CharData_Init(&storage); 7241 XML_SetUserData(parser, &storage); 7242 XML_SetElementHandler(parser, 7243 overwrite_start_checker, overwrite_end_checker); 7244 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR) 7245 xml_failure(parser); 7246 CharData_CheckXMLChars(&storage, result); 7247 } 7248 7249 /* Regression test for SF bug #566334. */ 7250 START_TEST(test_ns_tagname_overwrite) 7251 { 7252 const char *text = 7253 "<n:e xmlns:n='http://example.org/'>\n" 7254 " <n:f n:attr='foo'/>\n" 7255 " <n:g n:attr2='bar'/>\n" 7256 "</n:e>"; 7257 const XML_Char *result = 7258 XCS("start http://example.org/ e\n") 7259 XCS("start http://example.org/ f\n") 7260 XCS("attribute http://example.org/ attr\n") 7261 XCS("end http://example.org/ f\n") 7262 XCS("start http://example.org/ g\n") 7263 XCS("attribute http://example.org/ attr2\n") 7264 XCS("end http://example.org/ g\n") 7265 XCS("end http://example.org/ e\n"); 7266 run_ns_tagname_overwrite_test(text, result); 7267 } 7268 END_TEST 7269 7270 /* Regression test for SF bug #566334. */ 7271 START_TEST(test_ns_tagname_overwrite_triplet) 7272 { 7273 const char *text = 7274 "<n:e xmlns:n='http://example.org/'>\n" 7275 " <n:f n:attr='foo'/>\n" 7276 " <n:g n:attr2='bar'/>\n" 7277 "</n:e>"; 7278 const XML_Char *result = 7279 XCS("start http://example.org/ e n\n") 7280 XCS("start http://example.org/ f n\n") 7281 XCS("attribute http://example.org/ attr n\n") 7282 XCS("end http://example.org/ f n\n") 7283 XCS("start http://example.org/ g n\n") 7284 XCS("attribute http://example.org/ attr2 n\n") 7285 XCS("end http://example.org/ g n\n") 7286 XCS("end http://example.org/ e n\n"); 7287 XML_SetReturnNSTriplet(parser, XML_TRUE); 7288 run_ns_tagname_overwrite_test(text, result); 7289 } 7290 END_TEST 7291 7292 7293 /* Regression test for SF bug #620343. */ 7294 static void XMLCALL 7295 start_element_fail(void *UNUSED_P(userData), 7296 const XML_Char *UNUSED_P(name), const XML_Char **UNUSED_P(atts)) 7297 { 7298 /* We should never get here. */ 7299 fail("should never reach start_element_fail()"); 7300 } 7301 7302 static void XMLCALL 7303 start_ns_clearing_start_element(void *userData, 7304 const XML_Char *UNUSED_P(prefix), 7305 const XML_Char *UNUSED_P(uri)) 7306 { 7307 XML_SetStartElementHandler((XML_Parser) userData, NULL); 7308 } 7309 7310 START_TEST(test_start_ns_clears_start_element) 7311 { 7312 /* This needs to use separate start/end tags; using the empty tag 7313 syntax doesn't cause the problematic path through Expat to be 7314 taken. 7315 */ 7316 const char *text = "<e xmlns='http://example.org/'></e>"; 7317 7318 XML_SetStartElementHandler(parser, start_element_fail); 7319 XML_SetStartNamespaceDeclHandler(parser, start_ns_clearing_start_element); 7320 XML_SetEndNamespaceDeclHandler(parser, dummy_end_namespace_decl_handler); 7321 XML_UseParserAsHandlerArg(parser); 7322 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR) 7323 xml_failure(parser); 7324 } 7325 END_TEST 7326 7327 /* Regression test for SF bug #616863. */ 7328 static int XMLCALL 7329 external_entity_handler(XML_Parser parser, 7330 const XML_Char *context, 7331 const XML_Char *UNUSED_P(base), 7332 const XML_Char *UNUSED_P(systemId), 7333 const XML_Char *UNUSED_P(publicId)) 7334 { 7335 intptr_t callno = 1 + (intptr_t)XML_GetUserData(parser); 7336 const char *text; 7337 XML_Parser p2; 7338 7339 if (callno == 1) 7340 text = ("<!ELEMENT doc (e+)>\n" 7341 "<!ATTLIST doc xmlns CDATA #IMPLIED>\n" 7342 "<!ELEMENT e EMPTY>\n"); 7343 else 7344 text = ("<?xml version='1.0' encoding='us-ascii'?>" 7345 "<e/>"); 7346 7347 XML_SetUserData(parser, (void *) callno); 7348 p2 = XML_ExternalEntityParserCreate(parser, context, NULL); 7349 if (_XML_Parse_SINGLE_BYTES(p2, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR) { 7350 xml_failure(p2); 7351 return XML_STATUS_ERROR; 7352 } 7353 XML_ParserFree(p2); 7354 return XML_STATUS_OK; 7355 } 7356 7357 START_TEST(test_default_ns_from_ext_subset_and_ext_ge) 7358 { 7359 const char *text = 7360 "<?xml version='1.0'?>\n" 7361 "<!DOCTYPE doc SYSTEM 'http://example.org/doc.dtd' [\n" 7362 " <!ENTITY en SYSTEM 'http://example.org/entity.ent'>\n" 7363 "]>\n" 7364 "<doc xmlns='http://example.org/ns1'>\n" 7365 "&en;\n" 7366 "</doc>"; 7367 7368 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 7369 XML_SetExternalEntityRefHandler(parser, external_entity_handler); 7370 /* We actually need to set this handler to tickle this bug. */ 7371 XML_SetStartElementHandler(parser, dummy_start_element); 7372 XML_SetUserData(parser, NULL); 7373 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR) 7374 xml_failure(parser); 7375 } 7376 END_TEST 7377 7378 /* Regression test #1 for SF bug #673791. */ 7379 START_TEST(test_ns_prefix_with_empty_uri_1) 7380 { 7381 const char *text = 7382 "<doc xmlns:prefix='http://example.org/'>\n" 7383 " <e xmlns:prefix=''/>\n" 7384 "</doc>"; 7385 7386 expect_failure(text, 7387 XML_ERROR_UNDECLARING_PREFIX, 7388 "Did not report re-setting namespace" 7389 " URI with prefix to ''."); 7390 } 7391 END_TEST 7392 7393 /* Regression test #2 for SF bug #673791. */ 7394 START_TEST(test_ns_prefix_with_empty_uri_2) 7395 { 7396 const char *text = 7397 "<?xml version='1.0'?>\n" 7398 "<docelem xmlns:pre=''/>"; 7399 7400 expect_failure(text, 7401 XML_ERROR_UNDECLARING_PREFIX, 7402 "Did not report setting namespace URI with prefix to ''."); 7403 } 7404 END_TEST 7405 7406 /* Regression test #3 for SF bug #673791. */ 7407 START_TEST(test_ns_prefix_with_empty_uri_3) 7408 { 7409 const char *text = 7410 "<!DOCTYPE doc [\n" 7411 " <!ELEMENT doc EMPTY>\n" 7412 " <!ATTLIST doc\n" 7413 " xmlns:prefix CDATA ''>\n" 7414 "]>\n" 7415 "<doc/>"; 7416 7417 expect_failure(text, 7418 XML_ERROR_UNDECLARING_PREFIX, 7419 "Didn't report attr default setting NS w/ prefix to ''."); 7420 } 7421 END_TEST 7422 7423 /* Regression test #4 for SF bug #673791. */ 7424 START_TEST(test_ns_prefix_with_empty_uri_4) 7425 { 7426 const char *text = 7427 "<!DOCTYPE doc [\n" 7428 " <!ELEMENT prefix:doc EMPTY>\n" 7429 " <!ATTLIST prefix:doc\n" 7430 " xmlns:prefix CDATA 'http://example.org/'>\n" 7431 "]>\n" 7432 "<prefix:doc/>"; 7433 /* Packaged info expected by the end element handler; 7434 the weird structuring lets us re-use the triplet_end_checker() 7435 function also used for another test. */ 7436 const XML_Char *elemstr[] = { 7437 XCS("http://example.org/ doc prefix") 7438 }; 7439 XML_SetReturnNSTriplet(parser, XML_TRUE); 7440 XML_SetUserData(parser, (void *)elemstr); 7441 XML_SetEndElementHandler(parser, triplet_end_checker); 7442 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR) 7443 xml_failure(parser); 7444 } 7445 END_TEST 7446 7447 /* Test with non-xmlns prefix */ 7448 START_TEST(test_ns_unbound_prefix) 7449 { 7450 const char *text = 7451 "<!DOCTYPE doc [\n" 7452 " <!ELEMENT prefix:doc EMPTY>\n" 7453 " <!ATTLIST prefix:doc\n" 7454 " notxmlns:prefix CDATA 'http://example.org/'>\n" 7455 "]>\n" 7456 "<prefix:doc/>"; 7457 7458 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 7459 XML_TRUE) != XML_STATUS_ERROR) 7460 fail("Unbound prefix incorrectly passed"); 7461 if (XML_GetErrorCode(parser) != XML_ERROR_UNBOUND_PREFIX) 7462 xml_failure(parser); 7463 } 7464 END_TEST 7465 7466 START_TEST(test_ns_default_with_empty_uri) 7467 { 7468 const char *text = 7469 "<doc xmlns='http://example.org/'>\n" 7470 " <e xmlns=''/>\n" 7471 "</doc>"; 7472 /* Add some handlers to exercise extra code paths */ 7473 XML_SetStartNamespaceDeclHandler(parser, 7474 dummy_start_namespace_decl_handler); 7475 XML_SetEndNamespaceDeclHandler(parser, 7476 dummy_end_namespace_decl_handler); 7477 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR) 7478 xml_failure(parser); 7479 } 7480 END_TEST 7481 7482 /* Regression test for SF bug #692964: two prefixes for one namespace. */ 7483 START_TEST(test_ns_duplicate_attrs_diff_prefixes) 7484 { 7485 const char *text = 7486 "<doc xmlns:a='http://example.org/a'\n" 7487 " xmlns:b='http://example.org/a'\n" 7488 " a:a='v' b:a='v' />"; 7489 expect_failure(text, 7490 XML_ERROR_DUPLICATE_ATTRIBUTE, 7491 "did not report multiple attributes with same URI+name"); 7492 } 7493 END_TEST 7494 7495 START_TEST(test_ns_duplicate_hashes) 7496 { 7497 /* The hash of an attribute is calculated as the hash of its URI 7498 * concatenated with a space followed by its name (after the 7499 * colon). We wish to generate attributes with the same hash 7500 * value modulo the attribute table size so that we can check that 7501 * the attribute hash table works correctly. The attribute hash 7502 * table size will be the smallest power of two greater than the 7503 * number of attributes, but at least eight. There is 7504 * unfortunately no programmatic way of getting the hash or the 7505 * table size at user level, but the test code coverage percentage 7506 * will drop if the hashes cease to point to the same row. 7507 * 7508 * The cunning plan is to have few enough attributes to have a 7509 * reliable table size of 8, and have the single letter attribute 7510 * names be 8 characters apart, producing a hash which will be the 7511 * same modulo 8. 7512 */ 7513 const char *text = 7514 "<doc xmlns:a='http://example.org/a'\n" 7515 " a:a='v' a:i='w' />"; 7516 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 7517 XML_TRUE) == XML_STATUS_ERROR) 7518 xml_failure(parser); 7519 } 7520 END_TEST 7521 7522 /* Regression test for SF bug #695401: unbound prefix. */ 7523 START_TEST(test_ns_unbound_prefix_on_attribute) 7524 { 7525 const char *text = "<doc a:attr=''/>"; 7526 expect_failure(text, 7527 XML_ERROR_UNBOUND_PREFIX, 7528 "did not report unbound prefix on attribute"); 7529 } 7530 END_TEST 7531 7532 /* Regression test for SF bug #695401: unbound prefix. */ 7533 START_TEST(test_ns_unbound_prefix_on_element) 7534 { 7535 const char *text = "<a:doc/>"; 7536 expect_failure(text, 7537 XML_ERROR_UNBOUND_PREFIX, 7538 "did not report unbound prefix on element"); 7539 } 7540 END_TEST 7541 7542 /* Test that the parsing status is correctly reset by XML_ParserReset(). 7543 * We usE test_return_ns_triplet() for our example parse to improve 7544 * coverage of tidying up code executed. 7545 */ 7546 START_TEST(test_ns_parser_reset) 7547 { 7548 XML_ParsingStatus status; 7549 7550 XML_GetParsingStatus(parser, &status); 7551 if (status.parsing != XML_INITIALIZED) 7552 fail("parsing status doesn't start INITIALIZED"); 7553 test_return_ns_triplet(); 7554 XML_GetParsingStatus(parser, &status); 7555 if (status.parsing != XML_FINISHED) 7556 fail("parsing status doesn't end FINISHED"); 7557 XML_ParserReset(parser, NULL); 7558 XML_GetParsingStatus(parser, &status); 7559 if (status.parsing != XML_INITIALIZED) 7560 fail("parsing status doesn't reset to INITIALIZED"); 7561 } 7562 END_TEST 7563 7564 /* Test that long element names with namespaces are handled correctly */ 7565 START_TEST(test_ns_long_element) 7566 { 7567 const char *text = 7568 "<foo:thisisalongenoughelementnametotriggerareallocation\n" 7569 " xmlns:foo='http://example.org/' bar:a='12'\n" 7570 " xmlns:bar='http://example.org/'>" 7571 "</foo:thisisalongenoughelementnametotriggerareallocation>"; 7572 const XML_Char *elemstr[] = { 7573 XCS("http://example.org/") 7574 XCS(" thisisalongenoughelementnametotriggerareallocation foo"), 7575 XCS("http://example.org/ a bar") 7576 }; 7577 7578 XML_SetReturnNSTriplet(parser, XML_TRUE); 7579 XML_SetUserData(parser, (void *)elemstr); 7580 XML_SetElementHandler(parser, 7581 triplet_start_checker, 7582 triplet_end_checker); 7583 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 7584 XML_TRUE) == XML_STATUS_ERROR) 7585 xml_failure(parser); 7586 } 7587 END_TEST 7588 7589 /* Test mixed population of prefixed and unprefixed attributes */ 7590 START_TEST(test_ns_mixed_prefix_atts) 7591 { 7592 const char *text = 7593 "<e a='12' bar:b='13'\n" 7594 " xmlns:bar='http://example.org/'>" 7595 "</e>"; 7596 7597 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 7598 XML_TRUE) == XML_STATUS_ERROR) 7599 xml_failure(parser); 7600 } 7601 END_TEST 7602 7603 /* Test having a long namespaced element name inside a short one. 7604 * This exercises some internal buffer reallocation that is shared 7605 * across elements with the same namespace URI. 7606 */ 7607 START_TEST(test_ns_extend_uri_buffer) 7608 { 7609 const char *text = 7610 "<foo:e xmlns:foo='http://example.org/'>" 7611 " <foo:thisisalongenoughnametotriggerallocationaction" 7612 " foo:a='12' />" 7613 "</foo:e>"; 7614 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 7615 XML_TRUE) == XML_STATUS_ERROR) 7616 xml_failure(parser); 7617 } 7618 END_TEST 7619 7620 /* Test that xmlns is correctly rejected as an attribute in the xmlns 7621 * namespace, but not in other namespaces 7622 */ 7623 START_TEST(test_ns_reserved_attributes) 7624 { 7625 const char *text1 = 7626 "<foo:e xmlns:foo='http://example.org/' xmlns:xmlns='12' />"; 7627 const char *text2 = 7628 "<foo:e xmlns:foo='http://example.org/' foo:xmlns='12' />"; 7629 expect_failure(text1, XML_ERROR_RESERVED_PREFIX_XMLNS, 7630 "xmlns not rejected as an attribute"); 7631 XML_ParserReset(parser, NULL); 7632 if (_XML_Parse_SINGLE_BYTES(parser, text2, (int)strlen(text2), 7633 XML_TRUE) == XML_STATUS_ERROR) 7634 xml_failure(parser); 7635 } 7636 END_TEST 7637 7638 /* Test more reserved attributes */ 7639 START_TEST(test_ns_reserved_attributes_2) 7640 { 7641 const char *text1 = 7642 "<foo:e xmlns:foo='http://example.org/'" 7643 " xmlns:xml='http://example.org/' />"; 7644 const char *text2 = 7645 "<foo:e xmlns:foo='http://www.w3.org/XML/1998/namespace' />"; 7646 const char *text3 = 7647 "<foo:e xmlns:foo='http://www.w3.org/2000/xmlns/' />"; 7648 7649 expect_failure(text1, XML_ERROR_RESERVED_PREFIX_XML, 7650 "xml not rejected as an attribute"); 7651 XML_ParserReset(parser, NULL); 7652 expect_failure(text2, XML_ERROR_RESERVED_NAMESPACE_URI, 7653 "Use of w3.org URL not faulted"); 7654 XML_ParserReset(parser, NULL); 7655 expect_failure(text3, XML_ERROR_RESERVED_NAMESPACE_URI, 7656 "Use of w3.org xmlns URL not faulted"); 7657 } 7658 END_TEST 7659 7660 /* Test string pool handling of namespace names of 2048 characters */ 7661 /* Exercises a particular string pool growth path */ 7662 START_TEST(test_ns_extremely_long_prefix) 7663 { 7664 /* C99 compilers are only required to support 4095-character 7665 * strings, so the following needs to be split in two to be safe 7666 * for all compilers. 7667 */ 7668 const char *text1 = 7669 "<doc " 7670 /* 64 character on each line */ 7671 /* ...gives a total length of 2048 */ 7672 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7673 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7674 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7675 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7676 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7677 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7678 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7679 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7680 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7681 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7682 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7683 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7684 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7685 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7686 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7687 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7688 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7689 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7690 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7691 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7692 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7693 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7694 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7695 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7696 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7697 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7698 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7699 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7700 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7701 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7702 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7703 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7704 ":a='12'"; 7705 const char *text2 = 7706 " xmlns:" 7707 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7708 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7709 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7710 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7711 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7712 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7713 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7714 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7715 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7716 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7717 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7718 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7719 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7720 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7721 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7722 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7723 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7724 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7725 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7726 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7727 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7728 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7729 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7730 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7731 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7732 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7733 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7734 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7735 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7736 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7737 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7738 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 7739 "='foo'\n>" 7740 "</doc>"; 7741 7742 if (_XML_Parse_SINGLE_BYTES(parser, text1, (int)strlen(text1), 7743 XML_FALSE) == XML_STATUS_ERROR) 7744 xml_failure(parser); 7745 if (_XML_Parse_SINGLE_BYTES(parser, text2, (int)strlen(text2), 7746 XML_TRUE) == XML_STATUS_ERROR) 7747 xml_failure(parser); 7748 } 7749 END_TEST 7750 7751 /* Test unknown encoding handlers in namespace setup */ 7752 START_TEST(test_ns_unknown_encoding_success) 7753 { 7754 const char *text = 7755 "<?xml version='1.0' encoding='prefix-conv'?>\n" 7756 "<foo:e xmlns:foo='http://example.org/'>Hi</foo:e>"; 7757 7758 XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL); 7759 run_character_check(text, XCS("Hi")); 7760 } 7761 END_TEST 7762 7763 /* Test that too many colons are rejected */ 7764 START_TEST(test_ns_double_colon) 7765 { 7766 const char *text = 7767 "<foo:e xmlns:foo='http://example.org/' foo:a:b='bar' />"; 7768 7769 expect_failure(text, XML_ERROR_INVALID_TOKEN, 7770 "Double colon in attribute name not faulted"); 7771 } 7772 END_TEST 7773 7774 START_TEST(test_ns_double_colon_element) 7775 { 7776 const char *text = 7777 "<foo:bar:e xmlns:foo='http://example.org/' />"; 7778 7779 expect_failure(text, XML_ERROR_INVALID_TOKEN, 7780 "Double colon in element name not faulted"); 7781 } 7782 END_TEST 7783 7784 /* Test that non-name characters after a colon are rejected */ 7785 START_TEST(test_ns_bad_attr_leafname) 7786 { 7787 const char *text = 7788 "<foo:e xmlns:foo='http://example.org/' foo:?ar='baz' />"; 7789 7790 expect_failure(text, XML_ERROR_INVALID_TOKEN, 7791 "Invalid character in leafname not faulted"); 7792 } 7793 END_TEST 7794 7795 START_TEST(test_ns_bad_element_leafname) 7796 { 7797 const char *text = 7798 "<foo:?oc xmlns:foo='http://example.org/' />"; 7799 7800 expect_failure(text, XML_ERROR_INVALID_TOKEN, 7801 "Invalid character in element leafname not faulted"); 7802 } 7803 END_TEST 7804 7805 /* Test high-byte-set UTF-16 characters are valid in a leafname */ 7806 START_TEST(test_ns_utf16_leafname) 7807 { 7808 const char text[] = 7809 /* <n:e xmlns:n='URI' n:{KHO KHWAI}='a' /> 7810 * where {KHO KHWAI} = U+0E04 = 0xe0 0xb8 0x84 in UTF-8 7811 */ 7812 "<\0n\0:\0e\0 \0x\0m\0l\0n\0s\0:\0n\0=\0'\0U\0R\0I\0'\0 \0" 7813 "n\0:\0\x04\x0e=\0'\0a\0'\0 \0/\0>\0"; 7814 const XML_Char *expected = XCS("a"); 7815 CharData storage; 7816 7817 CharData_Init(&storage); 7818 XML_SetStartElementHandler(parser, accumulate_attribute); 7819 XML_SetUserData(parser, &storage); 7820 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text)-1, 7821 XML_TRUE) == XML_STATUS_ERROR) 7822 xml_failure(parser); 7823 CharData_CheckXMLChars(&storage, expected); 7824 } 7825 END_TEST 7826 7827 START_TEST(test_ns_utf16_element_leafname) 7828 { 7829 const char text[] = 7830 /* <n:{KHO KHWAI} xmlns:n='URI'/> 7831 * where {KHO KHWAI} = U+0E04 = 0xe0 0xb8 0x84 in UTF-8 7832 */ 7833 "\0<\0n\0:\x0e\x04\0 \0x\0m\0l\0n\0s\0:\0n\0=\0'\0U\0R\0I\0'\0/\0>"; 7834 #ifdef XML_UNICODE 7835 const XML_Char *expected = XCS("URI \x0e04"); 7836 #else 7837 const XML_Char *expected = XCS("URI \xe0\xb8\x84"); 7838 #endif 7839 CharData storage; 7840 7841 CharData_Init(&storage); 7842 XML_SetStartElementHandler(parser, start_element_event_handler); 7843 XML_SetUserData(parser, &storage); 7844 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text)-1, 7845 XML_TRUE) == XML_STATUS_ERROR) 7846 xml_failure(parser); 7847 CharData_CheckXMLChars(&storage, expected); 7848 } 7849 END_TEST 7850 7851 START_TEST(test_ns_utf16_doctype) 7852 { 7853 const char text[] = 7854 /* <!DOCTYPE foo:{KHO KHWAI} [ <!ENTITY bar 'baz'> ]>\n 7855 * where {KHO KHWAI} = U+0E04 = 0xe0 0xb8 0x84 in UTF-8 7856 */ 7857 "\0<\0!\0D\0O\0C\0T\0Y\0P\0E\0 \0f\0o\0o\0:\x0e\x04\0 " 7858 "\0[\0 \0<\0!\0E\0N\0T\0I\0T\0Y\0 \0b\0a\0r\0 \0'\0b\0a\0z\0'\0>\0 " 7859 "\0]\0>\0\n" 7860 /* <foo:{KHO KHWAI} xmlns:foo='URI'>&bar;</foo:{KHO KHWAI}> */ 7861 "\0<\0f\0o\0o\0:\x0e\x04\0 " 7862 "\0x\0m\0l\0n\0s\0:\0f\0o\0o\0=\0'\0U\0R\0I\0'\0>" 7863 "\0&\0b\0a\0r\0;" 7864 "\0<\0/\0f\0o\0o\0:\x0e\x04\0>"; 7865 #ifdef XML_UNICODE 7866 const XML_Char *expected = XCS("URI \x0e04"); 7867 #else 7868 const XML_Char *expected = XCS("URI \xe0\xb8\x84"); 7869 #endif 7870 CharData storage; 7871 7872 CharData_Init(&storage); 7873 XML_SetUserData(parser, &storage); 7874 XML_SetStartElementHandler(parser, start_element_event_handler); 7875 XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL); 7876 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text)-1, 7877 XML_TRUE) == XML_STATUS_ERROR) 7878 xml_failure(parser); 7879 CharData_CheckXMLChars(&storage, expected); 7880 } 7881 END_TEST 7882 7883 START_TEST(test_ns_invalid_doctype) 7884 { 7885 const char *text = 7886 "<!DOCTYPE foo:!bad [ <!ENTITY bar 'baz' ]>\n" 7887 "<foo:!bad>&bar;</foo:!bad>"; 7888 7889 expect_failure(text, XML_ERROR_INVALID_TOKEN, 7890 "Invalid character in document local name not faulted"); 7891 } 7892 END_TEST 7893 7894 START_TEST(test_ns_double_colon_doctype) 7895 { 7896 const char *text = 7897 "<!DOCTYPE foo:a:doc [ <!ENTITY bar 'baz' ]>\n" 7898 "<foo:a:doc>&bar;</foo:a:doc>"; 7899 7900 expect_failure(text, XML_ERROR_SYNTAX, 7901 "Double colon in document name not faulted"); 7902 } 7903 END_TEST 7904 7905 /* Control variable; the number of times duff_allocator() will successfully allocate */ 7906 #define ALLOC_ALWAYS_SUCCEED (-1) 7907 #define REALLOC_ALWAYS_SUCCEED (-1) 7908 7909 static intptr_t allocation_count = ALLOC_ALWAYS_SUCCEED; 7910 static intptr_t reallocation_count = REALLOC_ALWAYS_SUCCEED; 7911 7912 /* Crocked allocator for allocation failure tests */ 7913 static void *duff_allocator(size_t size) 7914 { 7915 if (allocation_count == 0) 7916 return NULL; 7917 if (allocation_count != ALLOC_ALWAYS_SUCCEED) 7918 allocation_count--; 7919 return malloc(size); 7920 } 7921 7922 /* Crocked reallocator for allocation failure tests */ 7923 static void *duff_reallocator(void *ptr, size_t size) 7924 { 7925 if (reallocation_count == 0) 7926 return NULL; 7927 if (reallocation_count != REALLOC_ALWAYS_SUCCEED) 7928 reallocation_count--; 7929 return realloc(ptr, size); 7930 } 7931 7932 /* Test that a failure to allocate the parser structure fails gracefully */ 7933 START_TEST(test_misc_alloc_create_parser) 7934 { 7935 XML_Memory_Handling_Suite memsuite = { duff_allocator, realloc, free }; 7936 unsigned int i; 7937 const unsigned int max_alloc_count = 10; 7938 7939 /* Something this simple shouldn't need more than 10 allocations */ 7940 for (i = 0; i < max_alloc_count; i++) 7941 { 7942 allocation_count = i; 7943 parser = XML_ParserCreate_MM(NULL, &memsuite, NULL); 7944 if (parser != NULL) 7945 break; 7946 } 7947 if (i == 0) 7948 fail("Parser unexpectedly ignored failing allocator"); 7949 else if (i == max_alloc_count) 7950 fail("Parser not created with max allocation count"); 7951 } 7952 END_TEST 7953 7954 /* Test memory allocation failures for a parser with an encoding */ 7955 START_TEST(test_misc_alloc_create_parser_with_encoding) 7956 { 7957 XML_Memory_Handling_Suite memsuite = { duff_allocator, realloc, free }; 7958 unsigned int i; 7959 const unsigned int max_alloc_count = 10; 7960 7961 /* Try several levels of allocation */ 7962 for (i = 0; i < max_alloc_count; i++) { 7963 allocation_count = i; 7964 parser = XML_ParserCreate_MM(XCS("us-ascii"), &memsuite, NULL); 7965 if (parser != NULL) 7966 break; 7967 } 7968 if (i == 0) 7969 fail("Parser ignored failing allocator"); 7970 else if (i == max_alloc_count) 7971 fail("Parser not created with max allocation count"); 7972 } 7973 END_TEST 7974 7975 /* Test that freeing a NULL parser doesn't cause an explosion. 7976 * (Not actually tested anywhere else) 7977 */ 7978 START_TEST(test_misc_null_parser) 7979 { 7980 XML_ParserFree(NULL); 7981 } 7982 END_TEST 7983 7984 /* Test that XML_ErrorString rejects out-of-range codes */ 7985 START_TEST(test_misc_error_string) 7986 { 7987 if (XML_ErrorString((enum XML_Error)-1) != NULL) 7988 fail("Negative error code not rejected"); 7989 if (XML_ErrorString((enum XML_Error)100) != NULL) 7990 fail("Large error code not rejected"); 7991 } 7992 END_TEST 7993 7994 /* Test the version information is consistent */ 7995 7996 /* Since we are working in XML_LChars (potentially 16-bits), we 7997 * can't use the standard C library functions for character 7998 * manipulation and have to roll our own. 7999 */ 8000 static int 8001 parse_version(const XML_LChar *version_text, 8002 XML_Expat_Version *version_struct) 8003 { 8004 while (*version_text != 0x00) { 8005 if (*version_text >= ASCII_0 && *version_text <= ASCII_9) 8006 break; 8007 version_text++; 8008 } 8009 if (*version_text == 0x00) 8010 return XML_FALSE; 8011 8012 /* version_struct->major = strtoul(version_text, 10, &version_text) */ 8013 version_struct->major = 0; 8014 while (*version_text >= ASCII_0 && *version_text <= ASCII_9) { 8015 version_struct->major = 8016 10 * version_struct->major + (*version_text++ - ASCII_0); 8017 } 8018 if (*version_text++ != ASCII_PERIOD) 8019 return XML_FALSE; 8020 8021 /* Now for the minor version number */ 8022 version_struct->minor = 0; 8023 while (*version_text >= ASCII_0 && *version_text <= ASCII_9) { 8024 version_struct->minor = 8025 10 * version_struct->minor + (*version_text++ - ASCII_0); 8026 } 8027 if (*version_text++ != ASCII_PERIOD) 8028 return XML_FALSE; 8029 8030 /* Finally the micro version number */ 8031 version_struct->micro = 0; 8032 while (*version_text >= ASCII_0 && *version_text <= ASCII_9) { 8033 version_struct->micro = 8034 10 * version_struct->micro + (*version_text++ - ASCII_0); 8035 } 8036 if (*version_text != 0x00) 8037 return XML_FALSE; 8038 return XML_TRUE; 8039 } 8040 8041 static int 8042 versions_equal(const XML_Expat_Version *first, 8043 const XML_Expat_Version *second) 8044 { 8045 return (first->major == second->major && 8046 first->minor == second->minor && 8047 first->micro == second->micro); 8048 } 8049 8050 START_TEST(test_misc_version) 8051 { 8052 XML_Expat_Version read_version = XML_ExpatVersionInfo(); 8053 /* Silence compiler warning with the following assignment */ 8054 XML_Expat_Version parsed_version = { 0, 0, 0 }; 8055 const XML_LChar *version_text = XML_ExpatVersion(); 8056 8057 if (version_text == NULL) 8058 fail("Could not obtain version text"); 8059 if (!parse_version(version_text, &parsed_version)) 8060 fail("Unable to parse version text"); 8061 if (!versions_equal(&read_version, &parsed_version)) 8062 fail("Version mismatch"); 8063 8064 #if ! defined(XML_UNICODE) || defined(XML_UNICODE_WCHAR_T) 8065 if (xcstrcmp(version_text, XCS("expat_2.2.6"))) /* needs bump on releases */ 8066 fail("XML_*_VERSION in expat.h out of sync?\n"); 8067 #else 8068 /* If we have XML_UNICODE defined but not XML_UNICODE_WCHAR_T 8069 * then XML_LChar is defined as char, for some reason. 8070 */ 8071 if (strcmp(version_text, "expat_2.2.5")) /* needs bump on releases */ 8072 fail("XML_*_VERSION in expat.h out of sync?\n"); 8073 #endif /* ! defined(XML_UNICODE) || defined(XML_UNICODE_WCHAR_T) */ 8074 } 8075 END_TEST 8076 8077 /* Test feature information */ 8078 START_TEST(test_misc_features) 8079 { 8080 const XML_Feature *features = XML_GetFeatureList(); 8081 8082 /* Prevent problems with double-freeing parsers */ 8083 parser = NULL; 8084 if (features == NULL) 8085 fail("Failed to get feature information"); 8086 /* Loop through the features checking what we can */ 8087 while (features->feature != XML_FEATURE_END) { 8088 switch(features->feature) { 8089 case XML_FEATURE_SIZEOF_XML_CHAR: 8090 if (features->value != sizeof(XML_Char)) 8091 fail("Incorrect size of XML_Char"); 8092 break; 8093 case XML_FEATURE_SIZEOF_XML_LCHAR: 8094 if (features->value != sizeof(XML_LChar)) 8095 fail("Incorrect size of XML_LChar"); 8096 break; 8097 default: 8098 break; 8099 } 8100 features++; 8101 } 8102 } 8103 END_TEST 8104 8105 /* Regression test for GitHub Issue #17: memory leak parsing attribute 8106 * values with mixed bound and unbound namespaces. 8107 */ 8108 START_TEST(test_misc_attribute_leak) 8109 { 8110 const char *text = "<D xmlns:L=\"D\" l:a='' L:a=''/>"; 8111 XML_Memory_Handling_Suite memsuite = { 8112 tracking_malloc, 8113 tracking_realloc, 8114 tracking_free 8115 }; 8116 8117 parser = XML_ParserCreate_MM(XCS("UTF-8"), &memsuite, XCS("\n")); 8118 expect_failure(text, XML_ERROR_UNBOUND_PREFIX, 8119 "Unbound prefixes not found"); 8120 XML_ParserFree(parser); 8121 /* Prevent the teardown trying to double free */ 8122 parser = NULL; 8123 8124 if (!tracking_report()) 8125 fail("Memory leak found"); 8126 } 8127 END_TEST 8128 8129 /* Test parser created for UTF-16LE is successful */ 8130 START_TEST(test_misc_utf16le) 8131 { 8132 const char text[] = 8133 /* <?xml version='1.0'?><q>Hi</q> */ 8134 "<\0?\0x\0m\0l\0 \0" 8135 "v\0e\0r\0s\0i\0o\0n\0=\0'\0\x31\0.\0\x30\0'\0?\0>\0" 8136 "<\0q\0>\0H\0i\0<\0/\0q\0>\0"; 8137 const XML_Char *expected = XCS("Hi"); 8138 CharData storage; 8139 8140 parser = XML_ParserCreate(XCS("UTF-16LE")); 8141 if (parser == NULL) 8142 fail("Parser not created"); 8143 8144 CharData_Init(&storage); 8145 XML_SetUserData(parser, &storage); 8146 XML_SetCharacterDataHandler(parser, accumulate_characters); 8147 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text)-1, 8148 XML_TRUE) == XML_STATUS_ERROR) 8149 xml_failure(parser); 8150 CharData_CheckXMLChars(&storage, expected); 8151 } 8152 END_TEST 8153 8154 8155 static void 8156 alloc_setup(void) 8157 { 8158 XML_Memory_Handling_Suite memsuite = { 8159 duff_allocator, 8160 duff_reallocator, 8161 free 8162 }; 8163 8164 /* Ensure the parser creation will go through */ 8165 allocation_count = ALLOC_ALWAYS_SUCCEED; 8166 reallocation_count = REALLOC_ALWAYS_SUCCEED; 8167 parser = XML_ParserCreate_MM(NULL, &memsuite, NULL); 8168 if (parser == NULL) 8169 fail("Parser not created"); 8170 } 8171 8172 static void 8173 alloc_teardown(void) 8174 { 8175 basic_teardown(); 8176 } 8177 8178 8179 /* Test the effects of allocation failures on xml declaration processing */ 8180 START_TEST(test_alloc_parse_xdecl) 8181 { 8182 const char *text = 8183 "<?xml version='1.0' encoding='utf-8'?>\n" 8184 "<doc>Hello, world</doc>"; 8185 int i; 8186 const int max_alloc_count = 15; 8187 8188 for (i = 0; i < max_alloc_count; i++) { 8189 allocation_count = i; 8190 XML_SetXmlDeclHandler(parser, dummy_xdecl_handler); 8191 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 8192 XML_TRUE) != XML_STATUS_ERROR) 8193 break; 8194 /* Resetting the parser is insufficient, because some memory 8195 * allocations are cached within the parser. Instead we use 8196 * the teardown and setup routines to ensure that we have the 8197 * right sort of parser back in our hands. 8198 */ 8199 alloc_teardown(); 8200 alloc_setup(); 8201 } 8202 if (i == 0) 8203 fail("Parse succeeded despite failing allocator"); 8204 if (i == max_alloc_count) 8205 fail("Parse failed with max allocations"); 8206 } 8207 END_TEST 8208 8209 /* As above, but with an encoding big enough to cause storing the 8210 * version information to expand the string pool being used. 8211 */ 8212 static int XMLCALL 8213 long_encoding_handler(void *UNUSED_P(userData), 8214 const XML_Char *UNUSED_P(encoding), 8215 XML_Encoding *info) 8216 { 8217 int i; 8218 8219 for (i = 0; i < 256; i++) 8220 info->map[i] = i; 8221 info->data = NULL; 8222 info->convert = NULL; 8223 info->release = NULL; 8224 return XML_STATUS_OK; 8225 } 8226 8227 START_TEST(test_alloc_parse_xdecl_2) 8228 { 8229 const char *text = 8230 "<?xml version='1.0' encoding='" 8231 /* Each line is 64 characters */ 8232 "ThisIsAStupidlyLongEncodingNameIntendedToTriggerPoolGrowth123456" 8233 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 8234 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 8235 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 8236 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 8237 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 8238 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 8239 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 8240 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 8241 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 8242 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 8243 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 8244 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 8245 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 8246 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 8247 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMN" 8248 "'?>" 8249 "<doc>Hello, world</doc>"; 8250 int i; 8251 const int max_alloc_count = 20; 8252 8253 for (i = 0; i < max_alloc_count; i++) { 8254 allocation_count = i; 8255 XML_SetXmlDeclHandler(parser, dummy_xdecl_handler); 8256 XML_SetUnknownEncodingHandler(parser, long_encoding_handler, NULL); 8257 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 8258 XML_TRUE) != XML_STATUS_ERROR) 8259 break; 8260 /* See comment in test_alloc_parse_xdecl() */ 8261 alloc_teardown(); 8262 alloc_setup(); 8263 } 8264 if (i == 0) 8265 fail("Parse succeeded despite failing allocator"); 8266 if (i == max_alloc_count) 8267 fail("Parse failed with max allocations"); 8268 } 8269 END_TEST 8270 8271 /* Test the effects of allocation failures on a straightforward parse */ 8272 START_TEST(test_alloc_parse_pi) 8273 { 8274 const char *text = 8275 "<?xml version='1.0' encoding='utf-8'?>\n" 8276 "<?pi unknown?>\n" 8277 "<doc>" 8278 "Hello, world" 8279 "</doc>"; 8280 int i; 8281 const int max_alloc_count = 15; 8282 8283 for (i = 0; i < max_alloc_count; i++) { 8284 allocation_count = i; 8285 XML_SetProcessingInstructionHandler(parser, dummy_pi_handler); 8286 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 8287 XML_TRUE) != XML_STATUS_ERROR) 8288 break; 8289 /* See comment in test_alloc_parse_xdecl() */ 8290 alloc_teardown(); 8291 alloc_setup(); 8292 } 8293 if (i == 0) 8294 fail("Parse succeeded despite failing allocator"); 8295 if (i == max_alloc_count) 8296 fail("Parse failed with max allocations"); 8297 } 8298 END_TEST 8299 8300 START_TEST(test_alloc_parse_pi_2) 8301 { 8302 const char *text = 8303 "<?xml version='1.0' encoding='utf-8'?>\n" 8304 "<doc>" 8305 "Hello, world" 8306 "<?pi unknown?>\n" 8307 "</doc>"; 8308 int i; 8309 const int max_alloc_count = 15; 8310 8311 for (i = 0; i < max_alloc_count; i++) { 8312 allocation_count = i; 8313 XML_SetProcessingInstructionHandler(parser, dummy_pi_handler); 8314 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 8315 XML_TRUE) != XML_STATUS_ERROR) 8316 break; 8317 /* See comment in test_alloc_parse_xdecl() */ 8318 alloc_teardown(); 8319 alloc_setup(); 8320 } 8321 if (i == 0) 8322 fail("Parse succeeded despite failing allocator"); 8323 if (i == max_alloc_count) 8324 fail("Parse failed with max allocations"); 8325 } 8326 END_TEST 8327 8328 START_TEST(test_alloc_parse_pi_3) 8329 { 8330 const char *text = 8331 "<?" 8332 /* 64 characters per line */ 8333 "This processing instruction should be long enough to ensure that" 8334 "it triggers the growth of an internal string pool when the " 8335 "allocator fails at a cruicial moment FGHIJKLMNOPABCDEFGHIJKLMNOP" 8336 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 8337 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 8338 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 8339 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 8340 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 8341 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 8342 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 8343 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 8344 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 8345 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 8346 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 8347 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 8348 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 8349 "Q?><doc/>"; 8350 int i; 8351 const int max_alloc_count = 20; 8352 8353 for (i = 0; i < max_alloc_count; i++) { 8354 allocation_count = i; 8355 XML_SetProcessingInstructionHandler(parser, dummy_pi_handler); 8356 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 8357 XML_TRUE) != XML_STATUS_ERROR) 8358 break; 8359 /* See comment in test_alloc_parse_xdecl() */ 8360 alloc_teardown(); 8361 alloc_setup(); 8362 } 8363 if (i == 0) 8364 fail("Parse succeeded despite failing allocator"); 8365 if (i == max_alloc_count) 8366 fail("Parse failed with max allocations"); 8367 } 8368 END_TEST 8369 8370 START_TEST(test_alloc_parse_comment) 8371 { 8372 const char *text = 8373 "<?xml version='1.0' encoding='utf-8'?>\n" 8374 "<!-- Test parsing this comment -->" 8375 "<doc>Hi</doc>"; 8376 int i; 8377 const int max_alloc_count = 15; 8378 8379 for (i = 0; i < max_alloc_count; i++) { 8380 allocation_count = i; 8381 XML_SetCommentHandler(parser, dummy_comment_handler); 8382 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 8383 XML_TRUE) != XML_STATUS_ERROR) 8384 break; 8385 /* See comment in test_alloc_parse_xdecl() */ 8386 alloc_teardown(); 8387 alloc_setup(); 8388 } 8389 if (i == 0) 8390 fail("Parse succeeded despite failing allocator"); 8391 if (i == max_alloc_count) 8392 fail("Parse failed with max allocations"); 8393 } 8394 END_TEST 8395 8396 START_TEST(test_alloc_parse_comment_2) 8397 { 8398 const char *text = 8399 "<?xml version='1.0' encoding='utf-8'?>\n" 8400 "<doc>" 8401 "Hello, world" 8402 "<!-- Parse this comment too -->" 8403 "</doc>"; 8404 int i; 8405 const int max_alloc_count = 15; 8406 8407 for (i = 0; i < max_alloc_count; i++) { 8408 allocation_count = i; 8409 XML_SetCommentHandler(parser, dummy_comment_handler); 8410 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 8411 XML_TRUE) != XML_STATUS_ERROR) 8412 break; 8413 /* See comment in test_alloc_parse_xdecl() */ 8414 alloc_teardown(); 8415 alloc_setup(); 8416 } 8417 if (i == 0) 8418 fail("Parse succeeded despite failing allocator"); 8419 if (i == max_alloc_count) 8420 fail("Parse failed with max allocations"); 8421 } 8422 END_TEST 8423 8424 static int XMLCALL 8425 external_entity_duff_loader(XML_Parser parser, 8426 const XML_Char *context, 8427 const XML_Char *UNUSED_P(base), 8428 const XML_Char *UNUSED_P(systemId), 8429 const XML_Char *UNUSED_P(publicId)) 8430 { 8431 XML_Parser new_parser; 8432 unsigned int i; 8433 const unsigned int max_alloc_count = 10; 8434 8435 /* Try a few different allocation levels */ 8436 for (i = 0; i < max_alloc_count; i++) 8437 { 8438 allocation_count = i; 8439 new_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 8440 if (new_parser != NULL) 8441 { 8442 XML_ParserFree(new_parser); 8443 break; 8444 } 8445 } 8446 if (i == 0) 8447 fail("External parser creation ignored failing allocator"); 8448 else if (i == max_alloc_count) 8449 fail("Extern parser not created with max allocation count"); 8450 8451 /* Make sure other random allocation doesn't now fail */ 8452 allocation_count = ALLOC_ALWAYS_SUCCEED; 8453 8454 /* Make sure the failure code path is executed too */ 8455 return XML_STATUS_ERROR; 8456 } 8457 8458 /* Test that external parser creation running out of memory is 8459 * correctly reported. Based on the external entity test cases. 8460 */ 8461 START_TEST(test_alloc_create_external_parser) 8462 { 8463 const char *text = 8464 "<?xml version='1.0' encoding='us-ascii'?>\n" 8465 "<!DOCTYPE doc SYSTEM 'foo'>\n" 8466 "<doc>&entity;</doc>"; 8467 char foo_text[] = 8468 "<!ELEMENT doc (#PCDATA)*>"; 8469 8470 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 8471 XML_SetUserData(parser, foo_text); 8472 XML_SetExternalEntityRefHandler(parser, 8473 external_entity_duff_loader); 8474 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR) { 8475 fail("External parser allocator returned success incorrectly"); 8476 } 8477 } 8478 END_TEST 8479 8480 /* More external parser memory allocation testing */ 8481 START_TEST(test_alloc_run_external_parser) 8482 { 8483 const char *text = 8484 "<?xml version='1.0' encoding='us-ascii'?>\n" 8485 "<!DOCTYPE doc SYSTEM 'foo'>\n" 8486 "<doc>&entity;</doc>"; 8487 char foo_text[] = 8488 "<!ELEMENT doc (#PCDATA)*>"; 8489 unsigned int i; 8490 const unsigned int max_alloc_count = 15; 8491 8492 for (i = 0; i < max_alloc_count; i++) { 8493 XML_SetParamEntityParsing(parser, 8494 XML_PARAM_ENTITY_PARSING_ALWAYS); 8495 XML_SetUserData(parser, foo_text); 8496 XML_SetExternalEntityRefHandler(parser, 8497 external_entity_null_loader); 8498 allocation_count = i; 8499 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR) 8500 break; 8501 /* See comment in test_alloc_parse_xdecl() */ 8502 alloc_teardown(); 8503 alloc_setup(); 8504 } 8505 if (i == 0) 8506 fail("Parsing ignored failing allocator"); 8507 else if (i == max_alloc_count) 8508 fail("Parsing failed with allocation count 10"); 8509 } 8510 END_TEST 8511 8512 8513 static int XMLCALL 8514 external_entity_dbl_handler(XML_Parser parser, 8515 const XML_Char *context, 8516 const XML_Char *UNUSED_P(base), 8517 const XML_Char *UNUSED_P(systemId), 8518 const XML_Char *UNUSED_P(publicId)) 8519 { 8520 intptr_t callno = (intptr_t)XML_GetUserData(parser); 8521 const char *text; 8522 XML_Parser new_parser; 8523 int i; 8524 const int max_alloc_count = 20; 8525 8526 if (callno == 0) { 8527 /* First time through, check how many calls to malloc occur */ 8528 text = ("<!ELEMENT doc (e+)>\n" 8529 "<!ATTLIST doc xmlns CDATA #IMPLIED>\n" 8530 "<!ELEMENT e EMPTY>\n"); 8531 allocation_count = 10000; 8532 new_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 8533 if (new_parser == NULL) { 8534 fail("Unable to allocate first external parser"); 8535 return XML_STATUS_ERROR; 8536 } 8537 /* Stash the number of calls in the user data */ 8538 XML_SetUserData(parser, (void *)(intptr_t)(10000 - allocation_count)); 8539 } else { 8540 text = ("<?xml version='1.0' encoding='us-ascii'?>" 8541 "<e/>"); 8542 /* Try at varying levels to exercise more code paths */ 8543 for (i = 0; i < max_alloc_count; i++) { 8544 allocation_count = callno + i; 8545 new_parser = XML_ExternalEntityParserCreate(parser, 8546 context, 8547 NULL); 8548 if (new_parser != NULL) 8549 break; 8550 } 8551 if (i == 0) { 8552 fail("Second external parser unexpectedly created"); 8553 XML_ParserFree(new_parser); 8554 return XML_STATUS_ERROR; 8555 } 8556 else if (i == max_alloc_count) { 8557 fail("Second external parser not created"); 8558 return XML_STATUS_ERROR; 8559 } 8560 } 8561 8562 allocation_count = ALLOC_ALWAYS_SUCCEED; 8563 if (_XML_Parse_SINGLE_BYTES(new_parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR) { 8564 xml_failure(new_parser); 8565 return XML_STATUS_ERROR; 8566 } 8567 XML_ParserFree(new_parser); 8568 return XML_STATUS_OK; 8569 } 8570 8571 /* Test that running out of memory in dtdCopy is correctly reported. 8572 * Based on test_default_ns_from_ext_subset_and_ext_ge() 8573 */ 8574 START_TEST(test_alloc_dtd_copy_default_atts) 8575 { 8576 const char *text = 8577 "<?xml version='1.0'?>\n" 8578 "<!DOCTYPE doc SYSTEM 'http://example.org/doc.dtd' [\n" 8579 " <!ENTITY en SYSTEM 'http://example.org/entity.ent'>\n" 8580 "]>\n" 8581 "<doc xmlns='http://example.org/ns1'>\n" 8582 "&en;\n" 8583 "</doc>"; 8584 8585 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 8586 XML_SetExternalEntityRefHandler(parser, 8587 external_entity_dbl_handler); 8588 XML_SetUserData(parser, NULL); 8589 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR) 8590 xml_failure(parser); 8591 } 8592 END_TEST 8593 8594 8595 static int XMLCALL 8596 external_entity_dbl_handler_2(XML_Parser parser, 8597 const XML_Char *context, 8598 const XML_Char *UNUSED_P(base), 8599 const XML_Char *UNUSED_P(systemId), 8600 const XML_Char *UNUSED_P(publicId)) 8601 { 8602 intptr_t callno = (intptr_t)XML_GetUserData(parser); 8603 const char *text; 8604 XML_Parser new_parser; 8605 enum XML_Status rv; 8606 8607 if (callno == 0) { 8608 /* Try different allocation levels for whole exercise */ 8609 text = ("<!ELEMENT doc (e+)>\n" 8610 "<!ATTLIST doc xmlns CDATA #IMPLIED>\n" 8611 "<!ELEMENT e EMPTY>\n"); 8612 XML_SetUserData(parser, (void *)(intptr_t)1); 8613 new_parser = XML_ExternalEntityParserCreate(parser, 8614 context, 8615 NULL); 8616 if (new_parser == NULL) 8617 return XML_STATUS_ERROR; 8618 rv = _XML_Parse_SINGLE_BYTES(new_parser, text, (int)strlen(text), 8619 XML_TRUE); 8620 } else { 8621 /* Just run through once */ 8622 text = ("<?xml version='1.0' encoding='us-ascii'?>" 8623 "<e/>"); 8624 new_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 8625 if (new_parser == NULL) 8626 return XML_STATUS_ERROR; 8627 rv =_XML_Parse_SINGLE_BYTES(new_parser, text, (int)strlen(text), 8628 XML_TRUE); 8629 } 8630 XML_ParserFree(new_parser); 8631 if (rv == XML_STATUS_ERROR) 8632 return XML_STATUS_ERROR; 8633 return XML_STATUS_OK; 8634 } 8635 8636 /* Test more external entity allocation failure paths */ 8637 START_TEST(test_alloc_external_entity) 8638 { 8639 const char *text = 8640 "<?xml version='1.0'?>\n" 8641 "<!DOCTYPE doc SYSTEM 'http://example.org/doc.dtd' [\n" 8642 " <!ENTITY en SYSTEM 'http://example.org/entity.ent'>\n" 8643 "]>\n" 8644 "<doc xmlns='http://example.org/ns1'>\n" 8645 "&en;\n" 8646 "</doc>"; 8647 int i; 8648 const int alloc_test_max_repeats = 50; 8649 8650 for (i = 0; i < alloc_test_max_repeats; i++) { 8651 allocation_count = -1; 8652 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 8653 XML_SetExternalEntityRefHandler(parser, 8654 external_entity_dbl_handler_2); 8655 XML_SetUserData(parser, NULL); 8656 allocation_count = i; 8657 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 8658 XML_TRUE) == XML_STATUS_OK) 8659 break; 8660 /* See comment in test_alloc_parse_xdecl() */ 8661 alloc_teardown(); 8662 alloc_setup(); 8663 } 8664 allocation_count = -1; 8665 if (i == 0) 8666 fail("External entity parsed despite duff allocator"); 8667 if (i == alloc_test_max_repeats) 8668 fail("External entity not parsed at max allocation count"); 8669 } 8670 END_TEST 8671 8672 /* Test more allocation failure paths */ 8673 static int XMLCALL 8674 external_entity_alloc_set_encoding(XML_Parser parser, 8675 const XML_Char *context, 8676 const XML_Char *UNUSED_P(base), 8677 const XML_Char *UNUSED_P(systemId), 8678 const XML_Char *UNUSED_P(publicId)) 8679 { 8680 /* As for external_entity_loader() */ 8681 const char *text = 8682 "<?xml encoding='iso-8859-3'?>" 8683 "\xC3\xA9"; 8684 XML_Parser ext_parser; 8685 enum XML_Status status; 8686 8687 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 8688 if (ext_parser == NULL) 8689 return XML_STATUS_ERROR; 8690 if (!XML_SetEncoding(ext_parser, XCS("utf-8"))) { 8691 XML_ParserFree(ext_parser); 8692 return XML_STATUS_ERROR; 8693 } 8694 status = _XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), 8695 XML_TRUE); 8696 XML_ParserFree(ext_parser); 8697 if (status == XML_STATUS_ERROR) 8698 return XML_STATUS_ERROR; 8699 return XML_STATUS_OK; 8700 } 8701 8702 START_TEST(test_alloc_ext_entity_set_encoding) 8703 { 8704 const char *text = 8705 "<!DOCTYPE doc [\n" 8706 " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n" 8707 "]>\n" 8708 "<doc>&en;</doc>"; 8709 int i; 8710 const int max_allocation_count = 30; 8711 8712 for (i = 0; i < max_allocation_count; i++) { 8713 XML_SetExternalEntityRefHandler(parser, 8714 external_entity_alloc_set_encoding); 8715 allocation_count = i; 8716 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 8717 XML_TRUE) == XML_STATUS_OK) 8718 break; 8719 allocation_count = -1; 8720 /* See comment in test_alloc_parse_xdecl() */ 8721 alloc_teardown(); 8722 alloc_setup(); 8723 } 8724 if (i == 0) 8725 fail("Encoding check succeeded despite failing allocator"); 8726 if (i == max_allocation_count) 8727 fail("Encoding failed at max allocation count"); 8728 } 8729 END_TEST 8730 8731 static int XMLCALL 8732 unknown_released_encoding_handler(void *UNUSED_P(data), 8733 const XML_Char *encoding, 8734 XML_Encoding *info) 8735 { 8736 if (!xcstrcmp(encoding, XCS("unsupported-encoding"))) { 8737 int i; 8738 8739 for (i = 0; i < 256; i++) 8740 info->map[i] = i; 8741 info->data = NULL; 8742 info->convert = NULL; 8743 info->release = dummy_release; 8744 return XML_STATUS_OK; 8745 } 8746 return XML_STATUS_ERROR; 8747 } 8748 8749 /* Test the effects of allocation failure in internal entities. 8750 * Based on test_unknown_encoding_internal_entity 8751 */ 8752 START_TEST(test_alloc_internal_entity) 8753 { 8754 const char *text = 8755 "<?xml version='1.0' encoding='unsupported-encoding'?>\n" 8756 "<!DOCTYPE test [<!ENTITY foo 'bar'>]>\n" 8757 "<test a='&foo;'/>"; 8758 unsigned int i; 8759 const unsigned int max_alloc_count = 20; 8760 8761 for (i = 0; i < max_alloc_count; i++) { 8762 allocation_count = i; 8763 XML_SetUnknownEncodingHandler(parser, 8764 unknown_released_encoding_handler, 8765 NULL); 8766 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR) 8767 break; 8768 /* See comment in test_alloc_parse_xdecl() */ 8769 alloc_teardown(); 8770 alloc_setup(); 8771 } 8772 if (i == 0) 8773 fail("Internal entity worked despite failing allocations"); 8774 else if (i == max_alloc_count) 8775 fail("Internal entity failed at max allocation count"); 8776 } 8777 END_TEST 8778 8779 8780 /* Test the robustness against allocation failure of element handling 8781 * Based on test_dtd_default_handling(). 8782 */ 8783 START_TEST(test_alloc_dtd_default_handling) 8784 { 8785 const char *text = 8786 "<!DOCTYPE doc [\n" 8787 "<!ENTITY e SYSTEM 'http://example.org/e'>\n" 8788 "<!NOTATION n SYSTEM 'http://example.org/n'>\n" 8789 "<!ENTITY e1 SYSTEM 'http://example.org/e' NDATA n>\n" 8790 "<!ELEMENT doc (#PCDATA)>\n" 8791 "<!ATTLIST doc a CDATA #IMPLIED>\n" 8792 "<?pi in dtd?>\n" 8793 "<!--comment in dtd-->\n" 8794 "]>\n" 8795 "<doc><![CDATA[text in doc]]></doc>"; 8796 const XML_Char *expected = XCS("\n\n\n\n\n\n\n\n\n<doc>text in doc</doc>"); 8797 CharData storage; 8798 int i; 8799 const int max_alloc_count = 25; 8800 8801 for (i = 0; i < max_alloc_count; i++) { 8802 allocation_count = i; 8803 dummy_handler_flags = 0; 8804 XML_SetDefaultHandler(parser, accumulate_characters); 8805 XML_SetDoctypeDeclHandler(parser, 8806 dummy_start_doctype_handler, 8807 dummy_end_doctype_handler); 8808 XML_SetEntityDeclHandler(parser, dummy_entity_decl_handler); 8809 XML_SetNotationDeclHandler(parser, dummy_notation_decl_handler); 8810 XML_SetElementDeclHandler(parser, dummy_element_decl_handler); 8811 XML_SetAttlistDeclHandler(parser, dummy_attlist_decl_handler); 8812 XML_SetProcessingInstructionHandler(parser, dummy_pi_handler); 8813 XML_SetCommentHandler(parser, dummy_comment_handler); 8814 XML_SetCdataSectionHandler(parser, 8815 dummy_start_cdata_handler, 8816 dummy_end_cdata_handler); 8817 XML_SetUnparsedEntityDeclHandler( 8818 parser, 8819 dummy_unparsed_entity_decl_handler); 8820 CharData_Init(&storage); 8821 XML_SetUserData(parser, &storage); 8822 XML_SetCharacterDataHandler(parser, accumulate_characters); 8823 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 8824 XML_TRUE) != XML_STATUS_ERROR) 8825 break; 8826 /* See comment in test_alloc_parse_xdecl() */ 8827 alloc_teardown(); 8828 alloc_setup(); 8829 } 8830 if (i == 0) 8831 fail("Default DTD parsed despite allocation failures"); 8832 if (i == max_alloc_count) 8833 fail("Default DTD not parsed with maximum alloc count"); 8834 CharData_CheckXMLChars(&storage, expected); 8835 if (dummy_handler_flags != (DUMMY_START_DOCTYPE_HANDLER_FLAG | 8836 DUMMY_END_DOCTYPE_HANDLER_FLAG | 8837 DUMMY_ENTITY_DECL_HANDLER_FLAG | 8838 DUMMY_NOTATION_DECL_HANDLER_FLAG | 8839 DUMMY_ELEMENT_DECL_HANDLER_FLAG | 8840 DUMMY_ATTLIST_DECL_HANDLER_FLAG | 8841 DUMMY_COMMENT_HANDLER_FLAG | 8842 DUMMY_PI_HANDLER_FLAG | 8843 DUMMY_START_CDATA_HANDLER_FLAG | 8844 DUMMY_END_CDATA_HANDLER_FLAG | 8845 DUMMY_UNPARSED_ENTITY_DECL_HANDLER_FLAG)) 8846 fail("Not all handlers were called"); 8847 } 8848 END_TEST 8849 8850 /* Test robustness of XML_SetEncoding() with a failing allocator */ 8851 START_TEST(test_alloc_explicit_encoding) 8852 { 8853 int i; 8854 const int max_alloc_count = 5; 8855 8856 for (i = 0; i < max_alloc_count; i++) { 8857 allocation_count = i; 8858 if (XML_SetEncoding(parser, XCS("us-ascii")) == XML_STATUS_OK) 8859 break; 8860 } 8861 if (i == 0) 8862 fail("Encoding set despite failing allocator"); 8863 else if (i == max_alloc_count) 8864 fail("Encoding not set at max allocation count"); 8865 } 8866 END_TEST 8867 8868 /* Test robustness of XML_SetBase against a failing allocator */ 8869 START_TEST(test_alloc_set_base) 8870 { 8871 const XML_Char *new_base = XCS("/local/file/name.xml"); 8872 int i; 8873 const int max_alloc_count = 5; 8874 8875 for (i = 0; i < max_alloc_count; i++) { 8876 allocation_count = i; 8877 if (XML_SetBase(parser, new_base) == XML_STATUS_OK) 8878 break; 8879 } 8880 if (i == 0) 8881 fail("Base set despite failing allocator"); 8882 else if (i == max_alloc_count) 8883 fail("Base not set with max allocation count"); 8884 } 8885 END_TEST 8886 8887 /* Test buffer extension in the face of a duff reallocator */ 8888 START_TEST(test_alloc_realloc_buffer) 8889 { 8890 const char *text = get_buffer_test_text; 8891 void *buffer; 8892 int i; 8893 const int max_realloc_count = 10; 8894 8895 /* Get a smallish buffer */ 8896 for (i = 0; i < max_realloc_count; i++) { 8897 reallocation_count = i; 8898 buffer = XML_GetBuffer(parser, 1536); 8899 if (buffer == NULL) 8900 fail("1.5K buffer reallocation failed"); 8901 memcpy(buffer, text, strlen(text)); 8902 if (XML_ParseBuffer(parser, (int)strlen(text), 8903 XML_FALSE) == XML_STATUS_OK) 8904 break; 8905 /* See comment in test_alloc_parse_xdecl() */ 8906 alloc_teardown(); 8907 alloc_setup(); 8908 } 8909 reallocation_count = -1; 8910 if (i == 0) 8911 fail("Parse succeeded with no reallocation"); 8912 else if (i == max_realloc_count) 8913 fail("Parse failed with max reallocation count"); 8914 } 8915 END_TEST 8916 8917 /* Same test for external entity parsers */ 8918 static int XMLCALL 8919 external_entity_reallocator(XML_Parser parser, 8920 const XML_Char *context, 8921 const XML_Char *UNUSED_P(base), 8922 const XML_Char *UNUSED_P(systemId), 8923 const XML_Char *UNUSED_P(publicId)) 8924 { 8925 const char *text = get_buffer_test_text; 8926 XML_Parser ext_parser; 8927 void *buffer; 8928 enum XML_Status status; 8929 8930 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 8931 if (ext_parser == NULL) 8932 fail("Could not create external entity parser"); 8933 8934 reallocation_count = (intptr_t)XML_GetUserData(parser); 8935 buffer = XML_GetBuffer(ext_parser, 1536); 8936 if (buffer == NULL) 8937 fail("Buffer allocation failed"); 8938 memcpy(buffer, text, strlen(text)); 8939 status = XML_ParseBuffer(ext_parser, (int)strlen(text), XML_FALSE); 8940 reallocation_count = -1; 8941 XML_ParserFree(ext_parser); 8942 return (status == XML_STATUS_OK) ? XML_STATUS_OK : XML_STATUS_ERROR; 8943 } 8944 8945 START_TEST(test_alloc_ext_entity_realloc_buffer) 8946 { 8947 const char *text = 8948 "<!DOCTYPE doc [\n" 8949 " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n" 8950 "]>\n" 8951 "<doc>&en;</doc>"; 8952 int i; 8953 const int max_realloc_count = 10; 8954 8955 for (i = 0; i < max_realloc_count; i++) { 8956 XML_SetExternalEntityRefHandler(parser, 8957 external_entity_reallocator); 8958 XML_SetUserData(parser, (void *)(intptr_t)i); 8959 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 8960 XML_TRUE) == XML_STATUS_OK) 8961 break; 8962 /* See comment in test_alloc_parse_xdecl() */ 8963 alloc_teardown(); 8964 alloc_setup(); 8965 } 8966 if (i == 0) 8967 fail("Succeeded with no reallocations"); 8968 if (i == max_realloc_count) 8969 fail("Failed with max reallocations"); 8970 } 8971 END_TEST 8972 8973 /* Test elements with many attributes are handled correctly */ 8974 START_TEST(test_alloc_realloc_many_attributes) 8975 { 8976 const char *text = 8977 "<!DOCTYPE doc [\n" 8978 "<!ATTLIST doc za CDATA 'default'>\n" 8979 "<!ATTLIST doc zb CDATA 'def2'>\n" 8980 "<!ATTLIST doc zc CDATA 'def3'>\n" 8981 "]>\n" 8982 "<doc a='1'" 8983 " b='2'" 8984 " c='3'" 8985 " d='4'" 8986 " e='5'" 8987 " f='6'" 8988 " g='7'" 8989 " h='8'" 8990 " i='9'" 8991 " j='10'" 8992 " k='11'" 8993 " l='12'" 8994 " m='13'" 8995 " n='14'" 8996 " p='15'" 8997 " q='16'" 8998 " r='17'" 8999 " s='18'>" 9000 "</doc>"; 9001 int i; 9002 const int max_realloc_count = 10; 9003 9004 for (i = 0; i < max_realloc_count; i++) { 9005 reallocation_count = i; 9006 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 9007 XML_TRUE) != XML_STATUS_ERROR) 9008 break; 9009 /* See comment in test_alloc_parse_xdecl() */ 9010 alloc_teardown(); 9011 alloc_setup(); 9012 } 9013 if (i == 0) 9014 fail("Parse succeeded despite no reallocations"); 9015 if (i == max_realloc_count) 9016 fail("Parse failed at max reallocations"); 9017 } 9018 END_TEST 9019 9020 /* Test handling of a public entity with failing allocator */ 9021 START_TEST(test_alloc_public_entity_value) 9022 { 9023 const char *text = 9024 "<!DOCTYPE doc SYSTEM 'http://example.org/'>\n" 9025 "<doc></doc>\n"; 9026 char dtd_text[] = 9027 "<!ELEMENT doc EMPTY>\n" 9028 "<!ENTITY % e1 PUBLIC 'foo' 'bar.ent'>\n" 9029 "<!ENTITY % " 9030 /* Each line is 64 characters */ 9031 "ThisIsAStupidlyLongParameterNameIntendedToTriggerPoolGrowth12345" 9032 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9033 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9034 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9035 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9036 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9037 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9038 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9039 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9040 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9041 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9042 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9043 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9044 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9045 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9046 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9047 " '%e1;'>\n" 9048 "%e1;\n"; 9049 int i; 9050 const int max_alloc_count = 50; 9051 9052 for (i = 0; i < max_alloc_count; i++) { 9053 allocation_count = i; 9054 dummy_handler_flags = 0; 9055 XML_SetUserData(parser, dtd_text); 9056 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 9057 XML_SetExternalEntityRefHandler(parser, external_entity_public); 9058 /* Provoke a particular code path */ 9059 XML_SetEntityDeclHandler(parser, dummy_entity_decl_handler); 9060 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 9061 XML_TRUE) != XML_STATUS_ERROR) 9062 break; 9063 /* See comment in test_alloc_parse_xdecl() */ 9064 alloc_teardown(); 9065 alloc_setup(); 9066 } 9067 if (i == 0) 9068 fail("Parsing worked despite failing allocation"); 9069 if (i == max_alloc_count) 9070 fail("Parsing failed at max allocation count"); 9071 if (dummy_handler_flags != DUMMY_ENTITY_DECL_HANDLER_FLAG) 9072 fail("Entity declaration handler not called"); 9073 } 9074 END_TEST 9075 9076 START_TEST(test_alloc_realloc_subst_public_entity_value) 9077 { 9078 const char *text = 9079 "<!DOCTYPE doc SYSTEM 'http://example.org/'>\n" 9080 "<doc></doc>\n"; 9081 char dtd_text[] = 9082 "<!ELEMENT doc EMPTY>\n" 9083 "<!ENTITY % " 9084 /* Each line is 64 characters */ 9085 "ThisIsAStupidlyLongParameterNameIntendedToTriggerPoolGrowth12345" 9086 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9087 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9088 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9089 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9090 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9091 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9092 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9093 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9094 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9095 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9096 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9097 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9098 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9099 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9100 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9101 " PUBLIC 'foo' 'bar.ent'>\n" 9102 "%ThisIsAStupidlyLongParameterNameIntendedToTriggerPoolGrowth12345" 9103 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9104 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9105 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9106 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9107 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9108 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9109 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9110 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9111 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9112 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9113 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9114 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9115 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9116 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9117 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP;"; 9118 int i; 9119 const int max_realloc_count = 10; 9120 9121 for (i = 0; i < max_realloc_count; i++) { 9122 reallocation_count = i; 9123 XML_SetUserData(parser, dtd_text); 9124 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 9125 XML_SetExternalEntityRefHandler(parser, external_entity_public); 9126 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 9127 XML_TRUE) != XML_STATUS_ERROR) 9128 break; 9129 /* See comment in test_alloc_parse_xdecl() */ 9130 alloc_teardown(); 9131 alloc_setup(); 9132 } 9133 if (i == 0) 9134 fail("Parsing worked despite failing reallocation"); 9135 if (i == max_realloc_count) 9136 fail("Parsing failed at max reallocation count"); 9137 } 9138 END_TEST 9139 9140 START_TEST(test_alloc_parse_public_doctype) 9141 { 9142 const char *text = 9143 "<?xml version='1.0' encoding='utf-8'?>\n" 9144 "<!DOCTYPE doc PUBLIC '" 9145 /* 64 characters per line */ 9146 "http://example.com/a/long/enough/name/to/trigger/pool/growth/zz/" 9147 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9148 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9149 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9150 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9151 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9152 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9153 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9154 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9155 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9156 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9157 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9158 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9159 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9160 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9161 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9162 "' 'test'>\n" 9163 "<doc></doc>"; 9164 int i; 9165 const int max_alloc_count = 25; 9166 9167 for (i = 0; i < max_alloc_count; i++) { 9168 allocation_count = i; 9169 dummy_handler_flags = 0; 9170 XML_SetDoctypeDeclHandler(parser, 9171 dummy_start_doctype_decl_handler, 9172 dummy_end_doctype_decl_handler); 9173 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 9174 XML_TRUE) != XML_STATUS_ERROR) 9175 break; 9176 /* See comment in test_alloc_parse_xdecl() */ 9177 alloc_teardown(); 9178 alloc_setup(); 9179 } 9180 if (i == 0) 9181 fail("Parse succeeded despite failing allocator"); 9182 if (i == max_alloc_count) 9183 fail("Parse failed at maximum allocation count"); 9184 if (dummy_handler_flags != (DUMMY_START_DOCTYPE_DECL_HANDLER_FLAG | 9185 DUMMY_END_DOCTYPE_DECL_HANDLER_FLAG)) 9186 fail("Doctype handler functions not called"); 9187 } 9188 END_TEST 9189 9190 START_TEST(test_alloc_parse_public_doctype_long_name) 9191 { 9192 const char *text = 9193 "<?xml version='1.0' encoding='utf-8'?>\n" 9194 "<!DOCTYPE doc PUBLIC 'http://example.com/foo' '" 9195 /* 64 characters per line */ 9196 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP" 9197 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP" 9198 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP" 9199 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP" 9200 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP" 9201 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP" 9202 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP" 9203 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP" 9204 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP" 9205 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP" 9206 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP" 9207 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP" 9208 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP" 9209 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP" 9210 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP" 9211 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP" 9212 "'>\n" 9213 "<doc></doc>"; 9214 int i; 9215 const int max_alloc_count = 25; 9216 9217 for (i = 0; i < max_alloc_count; i++) { 9218 allocation_count = i; 9219 XML_SetDoctypeDeclHandler(parser, 9220 dummy_start_doctype_decl_handler, 9221 dummy_end_doctype_decl_handler); 9222 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 9223 XML_TRUE) != XML_STATUS_ERROR) 9224 break; 9225 /* See comment in test_alloc_parse_xdecl() */ 9226 alloc_teardown(); 9227 alloc_setup(); 9228 } 9229 if (i == 0) 9230 fail("Parse succeeded despite failing allocator"); 9231 if (i == max_alloc_count) 9232 fail("Parse failed at maximum allocation count"); 9233 } 9234 END_TEST 9235 9236 static int XMLCALL 9237 external_entity_alloc(XML_Parser parser, 9238 const XML_Char *context, 9239 const XML_Char *UNUSED_P(base), 9240 const XML_Char *UNUSED_P(systemId), 9241 const XML_Char *UNUSED_P(publicId)) 9242 { 9243 const char *text = (const char *)XML_GetUserData(parser); 9244 XML_Parser ext_parser; 9245 int parse_res; 9246 9247 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); 9248 if (ext_parser == NULL) 9249 return XML_STATUS_ERROR; 9250 parse_res = _XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), 9251 XML_TRUE); 9252 XML_ParserFree(ext_parser); 9253 return parse_res; 9254 } 9255 9256 /* Test foreign DTD handling */ 9257 START_TEST(test_alloc_set_foreign_dtd) 9258 { 9259 const char *text1 = 9260 "<?xml version='1.0' encoding='us-ascii'?>\n" 9261 "<doc>&entity;</doc>"; 9262 char text2[] = "<!ELEMENT doc (#PCDATA)*>"; 9263 int i; 9264 const int max_alloc_count = 25; 9265 9266 for (i = 0; i < max_alloc_count; i++) { 9267 allocation_count = i; 9268 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 9269 XML_SetUserData(parser, &text2); 9270 XML_SetExternalEntityRefHandler(parser, external_entity_alloc); 9271 if (XML_UseForeignDTD(parser, XML_TRUE) != XML_ERROR_NONE) 9272 fail("Could not set foreign DTD"); 9273 if (_XML_Parse_SINGLE_BYTES(parser, text1, (int)strlen(text1), 9274 XML_TRUE) != XML_STATUS_ERROR) 9275 break; 9276 /* See comment in test_alloc_parse_xdecl() */ 9277 alloc_teardown(); 9278 alloc_setup(); 9279 } 9280 if (i == 0) 9281 fail("Parse succeeded despite failing allocator"); 9282 if (i == max_alloc_count) 9283 fail("Parse failed at maximum allocation count"); 9284 } 9285 END_TEST 9286 9287 /* Test based on ibm/valid/P32/ibm32v04.xml */ 9288 START_TEST(test_alloc_attribute_enum_value) 9289 { 9290 const char *text = 9291 "<?xml version='1.0' standalone='no'?>\n" 9292 "<!DOCTYPE animal SYSTEM 'test.dtd'>\n" 9293 "<animal>This is a \n <a/> \n\nyellow tiger</animal>"; 9294 char dtd_text[] = 9295 "<!ELEMENT animal (#PCDATA|a)*>\n" 9296 "<!ELEMENT a EMPTY>\n" 9297 "<!ATTLIST animal xml:space (default|preserve) 'preserve'>"; 9298 int i; 9299 const int max_alloc_count = 30; 9300 9301 for (i = 0; i < max_alloc_count; i++) { 9302 allocation_count = i; 9303 XML_SetExternalEntityRefHandler(parser, external_entity_alloc); 9304 XML_SetUserData(parser, dtd_text); 9305 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 9306 /* An attribute list handler provokes a different code path */ 9307 XML_SetAttlistDeclHandler(parser, dummy_attlist_decl_handler); 9308 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 9309 XML_TRUE) != XML_STATUS_ERROR) 9310 break; 9311 /* See comment in test_alloc_parse_xdecl() */ 9312 alloc_teardown(); 9313 alloc_setup(); 9314 } 9315 if (i == 0) 9316 fail("Parse succeeded despite failing allocator"); 9317 if (i == max_alloc_count) 9318 fail("Parse failed at maximum allocation count"); 9319 } 9320 END_TEST 9321 9322 /* Test attribute enums sufficient to overflow the string pool */ 9323 START_TEST(test_alloc_realloc_attribute_enum_value) 9324 { 9325 const char *text = 9326 "<?xml version='1.0' standalone='no'?>\n" 9327 "<!DOCTYPE animal SYSTEM 'test.dtd'>\n" 9328 "<animal>This is a yellow tiger</animal>"; 9329 /* We wish to define a collection of attribute enums that will 9330 * cause the string pool storing them to have to expand. This 9331 * means more than 1024 bytes, including the parentheses and 9332 * separator bars. 9333 */ 9334 char dtd_text[] = 9335 "<!ELEMENT animal (#PCDATA)*>\n" 9336 "<!ATTLIST animal thing " 9337 "(default" 9338 /* Each line is 64 characters */ 9339 "|ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9340 "|BBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9341 "|CBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9342 "|DBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9343 "|EBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9344 "|FBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9345 "|GBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9346 "|HBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9347 "|IBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9348 "|JBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9349 "|KBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9350 "|LBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9351 "|MBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9352 "|NBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9353 "|OBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9354 "|PBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO)" 9355 " 'default'>"; 9356 int i; 9357 const int max_realloc_count = 10; 9358 9359 for (i = 0; i < max_realloc_count; i++) { 9360 reallocation_count = i; 9361 XML_SetExternalEntityRefHandler(parser, external_entity_alloc); 9362 XML_SetUserData(parser, dtd_text); 9363 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 9364 /* An attribute list handler provokes a different code path */ 9365 XML_SetAttlistDeclHandler(parser, dummy_attlist_decl_handler); 9366 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 9367 XML_TRUE) != XML_STATUS_ERROR) 9368 break; 9369 /* See comment in test_alloc_parse_xdecl() */ 9370 alloc_teardown(); 9371 alloc_setup(); 9372 } 9373 if (i == 0) 9374 fail("Parse succeeded despite failing reallocator"); 9375 if (i == max_realloc_count) 9376 fail("Parse failed at maximum reallocation count"); 9377 } 9378 END_TEST 9379 9380 /* Test attribute enums in a #IMPLIED attribute forcing pool growth */ 9381 START_TEST(test_alloc_realloc_implied_attribute) 9382 { 9383 /* Forcing this particular code path is a balancing act. The 9384 * addition of the closing parenthesis and terminal NUL must be 9385 * what pushes the string of enums over the 1024-byte limit, 9386 * otherwise a different code path will pick up the realloc. 9387 */ 9388 const char *text = 9389 "<!DOCTYPE doc [\n" 9390 "<!ELEMENT doc EMPTY>\n" 9391 "<!ATTLIST doc a " 9392 /* Each line is 64 characters */ 9393 "(ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9394 "|BBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9395 "|CBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9396 "|DBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9397 "|EBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9398 "|FBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9399 "|GBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9400 "|HBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9401 "|IBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9402 "|JBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9403 "|KBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9404 "|LBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9405 "|MBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9406 "|NBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9407 "|OBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9408 "|PBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMN)" 9409 " #IMPLIED>\n" 9410 "]><doc/>"; 9411 int i; 9412 const int max_realloc_count = 10; 9413 9414 for (i = 0; i < max_realloc_count; i++) { 9415 reallocation_count = i; 9416 XML_SetAttlistDeclHandler(parser, dummy_attlist_decl_handler); 9417 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 9418 XML_TRUE) != XML_STATUS_ERROR) 9419 break; 9420 /* See comment in test_alloc_parse_xdecl() */ 9421 alloc_teardown(); 9422 alloc_setup(); 9423 } 9424 if (i == 0) 9425 fail("Parse succeeded despite failing reallocator"); 9426 if (i == max_realloc_count) 9427 fail("Parse failed at maximum reallocation count"); 9428 } 9429 END_TEST 9430 9431 /* Test attribute enums in a defaulted attribute forcing pool growth */ 9432 START_TEST(test_alloc_realloc_default_attribute) 9433 { 9434 /* Forcing this particular code path is a balancing act. The 9435 * addition of the closing parenthesis and terminal NUL must be 9436 * what pushes the string of enums over the 1024-byte limit, 9437 * otherwise a different code path will pick up the realloc. 9438 */ 9439 const char *text = 9440 "<!DOCTYPE doc [\n" 9441 "<!ELEMENT doc EMPTY>\n" 9442 "<!ATTLIST doc a " 9443 /* Each line is 64 characters */ 9444 "(ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9445 "|BBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9446 "|CBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9447 "|DBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9448 "|EBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9449 "|FBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9450 "|GBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9451 "|HBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9452 "|IBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9453 "|JBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9454 "|KBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9455 "|LBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9456 "|MBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9457 "|NBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9458 "|OBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 9459 "|PBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMN)" 9460 " 'ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO'" 9461 ">\n]><doc/>"; 9462 int i; 9463 const int max_realloc_count = 10; 9464 9465 for (i = 0; i < max_realloc_count; i++) { 9466 reallocation_count = i; 9467 XML_SetAttlistDeclHandler(parser, dummy_attlist_decl_handler); 9468 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 9469 XML_TRUE) != XML_STATUS_ERROR) 9470 break; 9471 /* See comment in test_alloc_parse_xdecl() */ 9472 alloc_teardown(); 9473 alloc_setup(); 9474 } 9475 if (i == 0) 9476 fail("Parse succeeded despite failing reallocator"); 9477 if (i == max_realloc_count) 9478 fail("Parse failed at maximum reallocation count"); 9479 } 9480 END_TEST 9481 9482 /* Test long notation name with dodgy allocator */ 9483 START_TEST(test_alloc_notation) 9484 { 9485 const char *text = 9486 "<!DOCTYPE doc [\n" 9487 "<!NOTATION " 9488 /* Each line is 64 characters */ 9489 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9490 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9491 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9492 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9493 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9494 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9495 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9496 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9497 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9498 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9499 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9500 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9501 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9502 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9503 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9504 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9505 " SYSTEM 'http://example.org/n'>\n" 9506 "<!ENTITY e SYSTEM 'http://example.org/e' NDATA " 9507 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9508 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9509 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9510 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9511 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9512 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9513 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9514 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9515 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9516 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9517 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9518 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9519 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9520 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9521 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9522 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9523 ">\n" 9524 "<!ELEMENT doc EMPTY>\n" 9525 "]>\n<doc/>"; 9526 int i; 9527 const int max_alloc_count = 20; 9528 9529 for (i = 0; i < max_alloc_count; i++) { 9530 allocation_count = i; 9531 dummy_handler_flags = 0; 9532 XML_SetNotationDeclHandler(parser, dummy_notation_decl_handler); 9533 XML_SetEntityDeclHandler(parser, dummy_entity_decl_handler); 9534 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 9535 XML_TRUE) != XML_STATUS_ERROR) 9536 break; 9537 /* See comment in test_alloc_parse_xdecl() */ 9538 alloc_teardown(); 9539 alloc_setup(); 9540 } 9541 if (i == 0) 9542 fail("Parse succeeded despite allocation failures"); 9543 if (i == max_alloc_count) 9544 fail("Parse failed at maximum allocation count"); 9545 if (dummy_handler_flags != (DUMMY_ENTITY_DECL_HANDLER_FLAG | 9546 DUMMY_NOTATION_DECL_HANDLER_FLAG)) 9547 fail("Entity declaration handler not called"); 9548 } 9549 END_TEST 9550 9551 /* Test public notation with dodgy allocator */ 9552 START_TEST(test_alloc_public_notation) 9553 { 9554 const char *text = 9555 "<!DOCTYPE doc [\n" 9556 "<!NOTATION note PUBLIC '" 9557 /* 64 characters per line */ 9558 "http://example.com/a/long/enough/name/to/trigger/pool/growth/zz/" 9559 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9560 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9561 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9562 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9563 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9564 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9565 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9566 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9567 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9568 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9569 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9570 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9571 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9572 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9573 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9574 "' 'foo'>\n" 9575 "<!ENTITY e SYSTEM 'http://example.com/e' NDATA note>\n" 9576 "<!ELEMENT doc EMPTY>\n" 9577 "]>\n<doc/>"; 9578 int i; 9579 const int max_alloc_count = 20; 9580 9581 for (i = 0; i < max_alloc_count; i++) { 9582 allocation_count = i; 9583 dummy_handler_flags = 0; 9584 XML_SetNotationDeclHandler(parser, dummy_notation_decl_handler); 9585 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 9586 XML_TRUE) != XML_STATUS_ERROR) 9587 break; 9588 /* See comment in test_alloc_parse_xdecl() */ 9589 alloc_teardown(); 9590 alloc_setup(); 9591 } 9592 if (i == 0) 9593 fail("Parse succeeded despite allocation failures"); 9594 if (i == max_alloc_count) 9595 fail("Parse failed at maximum allocation count"); 9596 if (dummy_handler_flags != DUMMY_NOTATION_DECL_HANDLER_FLAG) 9597 fail("Notation handler not called"); 9598 } 9599 END_TEST 9600 9601 /* Test public notation with dodgy allocator */ 9602 START_TEST(test_alloc_system_notation) 9603 { 9604 const char *text = 9605 "<!DOCTYPE doc [\n" 9606 "<!NOTATION note SYSTEM '" 9607 /* 64 characters per line */ 9608 "http://example.com/a/long/enough/name/to/trigger/pool/growth/zz/" 9609 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9610 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9611 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9612 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9613 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9614 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9615 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9616 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9617 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9618 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9619 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9620 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9621 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9622 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9623 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 9624 "'>\n" 9625 "<!ENTITY e SYSTEM 'http://example.com/e' NDATA note>\n" 9626 "<!ELEMENT doc EMPTY>\n" 9627 "]>\n<doc/>"; 9628 int i; 9629 const int max_alloc_count = 20; 9630 9631 for (i = 0; i < max_alloc_count; i++) { 9632 allocation_count = i; 9633 dummy_handler_flags = 0; 9634 XML_SetNotationDeclHandler(parser, dummy_notation_decl_handler); 9635 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 9636 XML_TRUE) != XML_STATUS_ERROR) 9637 break; 9638 /* See comment in test_alloc_parse_xdecl() */ 9639 alloc_teardown(); 9640 alloc_setup(); 9641 } 9642 if (i == 0) 9643 fail("Parse succeeded despite allocation failures"); 9644 if (i == max_alloc_count) 9645 fail("Parse failed at maximum allocation count"); 9646 if (dummy_handler_flags != DUMMY_NOTATION_DECL_HANDLER_FLAG) 9647 fail("Notation handler not called"); 9648 } 9649 END_TEST 9650 9651 START_TEST(test_alloc_nested_groups) 9652 { 9653 const char *text = 9654 "<!DOCTYPE doc [\n" 9655 "<!ELEMENT doc " 9656 /* Sixteen elements per line */ 9657 "(e,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?," 9658 "(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?" 9659 "))))))))))))))))))))))))))))))))>\n" 9660 "<!ELEMENT e EMPTY>" 9661 "]>\n" 9662 "<doc><e/></doc>"; 9663 CharData storage; 9664 int i; 9665 const int max_alloc_count = 20; 9666 9667 for (i = 0; i < max_alloc_count; i++) { 9668 allocation_count = i; 9669 CharData_Init(&storage); 9670 XML_SetElementDeclHandler(parser, dummy_element_decl_handler); 9671 XML_SetStartElementHandler(parser, record_element_start_handler); 9672 XML_SetUserData(parser, &storage); 9673 dummy_handler_flags = 0; 9674 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 9675 XML_TRUE) != XML_STATUS_ERROR) 9676 break; 9677 /* See comment in test_alloc_parse_xdecl() */ 9678 alloc_teardown(); 9679 alloc_setup(); 9680 } 9681 9682 if (i == 0) 9683 fail("Parse succeeded despite failing reallocator"); 9684 if (i == max_alloc_count) 9685 fail("Parse failed at maximum reallocation count"); 9686 CharData_CheckXMLChars(&storage, XCS("doce")); 9687 if (dummy_handler_flags != DUMMY_ELEMENT_DECL_HANDLER_FLAG) 9688 fail("Element handler not fired"); 9689 } 9690 END_TEST 9691 9692 START_TEST(test_alloc_realloc_nested_groups) 9693 { 9694 const char *text = 9695 "<!DOCTYPE doc [\n" 9696 "<!ELEMENT doc " 9697 /* Sixteen elements per line */ 9698 "(e,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?," 9699 "(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?" 9700 "))))))))))))))))))))))))))))))))>\n" 9701 "<!ELEMENT e EMPTY>" 9702 "]>\n" 9703 "<doc><e/></doc>"; 9704 CharData storage; 9705 int i; 9706 const int max_realloc_count = 10; 9707 9708 for (i = 0; i < max_realloc_count; i++) { 9709 reallocation_count = i; 9710 CharData_Init(&storage); 9711 XML_SetElementDeclHandler(parser, dummy_element_decl_handler); 9712 XML_SetStartElementHandler(parser, record_element_start_handler); 9713 XML_SetUserData(parser, &storage); 9714 dummy_handler_flags = 0; 9715 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 9716 XML_TRUE) != XML_STATUS_ERROR) 9717 break; 9718 /* See comment in test_alloc_parse_xdecl() */ 9719 alloc_teardown(); 9720 alloc_setup(); 9721 } 9722 9723 if (i == 0) 9724 fail("Parse succeeded despite failing reallocator"); 9725 if (i == max_realloc_count) 9726 fail("Parse failed at maximum reallocation count"); 9727 CharData_CheckXMLChars(&storage, XCS("doce")); 9728 if (dummy_handler_flags != DUMMY_ELEMENT_DECL_HANDLER_FLAG) 9729 fail("Element handler not fired"); 9730 } 9731 END_TEST 9732 9733 START_TEST(test_alloc_large_group) 9734 { 9735 const char *text = 9736 "<!DOCTYPE doc [\n" 9737 "<!ELEMENT doc (" 9738 "a1|a2|a3|a4|a5|a6|a7|a8|" 9739 "b1|b2|b3|b4|b5|b6|b7|b8|" 9740 "c1|c2|c3|c4|c5|c6|c7|c8|" 9741 "d1|d2|d3|d4|d5|d6|d7|d8|" 9742 "e1" 9743 ")+>\n" 9744 "]>\n" 9745 "<doc>\n" 9746 "<a1/>\n" 9747 "</doc>\n"; 9748 int i; 9749 const int max_alloc_count = 50; 9750 9751 for (i = 0; i < max_alloc_count; i++) { 9752 allocation_count = i; 9753 XML_SetElementDeclHandler(parser, dummy_element_decl_handler); 9754 dummy_handler_flags = 0; 9755 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 9756 XML_TRUE) != XML_STATUS_ERROR) 9757 break; 9758 /* See comment in test_alloc_parse_xdecl() */ 9759 alloc_teardown(); 9760 alloc_setup(); 9761 } 9762 if (i == 0) 9763 fail("Parse succeeded despite failing allocator"); 9764 if (i == max_alloc_count) 9765 fail("Parse failed at maximum allocation count"); 9766 if (dummy_handler_flags != DUMMY_ELEMENT_DECL_HANDLER_FLAG) 9767 fail("Element handler flag not raised"); 9768 } 9769 END_TEST 9770 9771 START_TEST(test_alloc_realloc_group_choice) 9772 { 9773 const char *text = 9774 "<!DOCTYPE doc [\n" 9775 "<!ELEMENT doc (" 9776 "a1|a2|a3|a4|a5|a6|a7|a8|" 9777 "b1|b2|b3|b4|b5|b6|b7|b8|" 9778 "c1|c2|c3|c4|c5|c6|c7|c8|" 9779 "d1|d2|d3|d4|d5|d6|d7|d8|" 9780 "e1" 9781 ")+>\n" 9782 "]>\n" 9783 "<doc>\n" 9784 "<a1/>\n" 9785 "<b2 attr='foo'>This is a foo</b2>\n" 9786 "<c3></c3>\n" 9787 "</doc>\n"; 9788 int i; 9789 const int max_realloc_count = 10; 9790 9791 for (i = 0; i < max_realloc_count; i++) { 9792 reallocation_count = i; 9793 XML_SetElementDeclHandler(parser, dummy_element_decl_handler); 9794 dummy_handler_flags = 0; 9795 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 9796 XML_TRUE) != XML_STATUS_ERROR) 9797 break; 9798 /* See comment in test_alloc_parse_xdecl() */ 9799 alloc_teardown(); 9800 alloc_setup(); 9801 } 9802 if (i == 0) 9803 fail("Parse succeeded despite failing reallocator"); 9804 if (i == max_realloc_count) 9805 fail("Parse failed at maximum reallocation count"); 9806 if (dummy_handler_flags != DUMMY_ELEMENT_DECL_HANDLER_FLAG) 9807 fail("Element handler flag not raised"); 9808 } 9809 END_TEST 9810 9811 START_TEST(test_alloc_pi_in_epilog) 9812 { 9813 const char *text = 9814 "<doc></doc>\n" 9815 "<?pi in epilog?>"; 9816 int i; 9817 const int max_alloc_count = 15; 9818 9819 for (i = 0; i < max_alloc_count; i++) { 9820 allocation_count = i; 9821 XML_SetProcessingInstructionHandler(parser, dummy_pi_handler); 9822 dummy_handler_flags = 0; 9823 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 9824 XML_TRUE) != XML_STATUS_ERROR) 9825 break; 9826 /* See comment in test_alloc_parse_xdecl() */ 9827 alloc_teardown(); 9828 alloc_setup(); 9829 } 9830 if (i == 0) 9831 fail("Parse completed despite failing allocator"); 9832 if (i == max_alloc_count) 9833 fail("Parse failed at maximum allocation count"); 9834 if (dummy_handler_flags != DUMMY_PI_HANDLER_FLAG) 9835 fail("Processing instruction handler not invoked"); 9836 } 9837 END_TEST 9838 9839 START_TEST(test_alloc_comment_in_epilog) 9840 { 9841 const char *text = 9842 "<doc></doc>\n" 9843 "<!-- comment in epilog -->"; 9844 int i; 9845 const int max_alloc_count = 15; 9846 9847 for (i = 0; i < max_alloc_count; i++) { 9848 allocation_count = i; 9849 XML_SetCommentHandler(parser, dummy_comment_handler); 9850 dummy_handler_flags = 0; 9851 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 9852 XML_TRUE) != XML_STATUS_ERROR) 9853 break; 9854 /* See comment in test_alloc_parse_xdecl() */ 9855 alloc_teardown(); 9856 alloc_setup(); 9857 } 9858 if (i == 0) 9859 fail("Parse completed despite failing allocator"); 9860 if (i == max_alloc_count) 9861 fail("Parse failed at maximum allocation count"); 9862 if (dummy_handler_flags != DUMMY_COMMENT_HANDLER_FLAG) 9863 fail("Processing instruction handler not invoked"); 9864 } 9865 END_TEST 9866 9867 START_TEST(test_alloc_realloc_long_attribute_value) 9868 { 9869 const char *text = 9870 "<!DOCTYPE doc [<!ENTITY foo '" 9871 /* Each line is 64 characters */ 9872 "This entity will be substituted as an attribute value, and is " 9873 "calculated to be exactly long enough that the terminating NUL " 9874 "that the library adds internally will trigger the string pool to" 9875 "grow. GHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9876 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9877 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9878 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9879 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9880 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9881 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9882 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9883 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9884 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9885 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9886 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9887 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9888 "'>]>\n" 9889 "<doc a='&foo;'></doc>"; 9890 int i; 9891 const int max_realloc_count = 10; 9892 9893 for (i = 0; i < max_realloc_count; i++) { 9894 reallocation_count = i; 9895 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 9896 XML_TRUE) != XML_STATUS_ERROR) 9897 break; 9898 /* See comment in test_alloc_parse_xdecl() */ 9899 alloc_teardown(); 9900 alloc_setup(); 9901 } 9902 if (i == 0) 9903 fail("Parse succeeded despite failing reallocator"); 9904 if (i == max_realloc_count) 9905 fail("Parse failed at maximum reallocation count"); 9906 } 9907 END_TEST 9908 9909 START_TEST(test_alloc_attribute_whitespace) 9910 { 9911 const char *text = "<doc a=' '></doc>"; 9912 int i; 9913 const int max_alloc_count = 15; 9914 9915 for (i = 0; i < max_alloc_count; i++) { 9916 allocation_count = i; 9917 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 9918 XML_TRUE) != XML_STATUS_ERROR) 9919 break; 9920 /* See comment in test_alloc_parse_xdecl() */ 9921 alloc_teardown(); 9922 alloc_setup(); 9923 } 9924 if (i == 0) 9925 fail("Parse succeeded despite failing allocator"); 9926 if (i == max_alloc_count) 9927 fail("Parse failed at maximum allocation count"); 9928 } 9929 END_TEST 9930 9931 START_TEST(test_alloc_attribute_predefined_entity) 9932 { 9933 const char *text = "<doc a='&'></doc>"; 9934 int i; 9935 const int max_alloc_count = 15; 9936 9937 for (i = 0; i < max_alloc_count; i++) { 9938 allocation_count = i; 9939 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 9940 XML_TRUE) != XML_STATUS_ERROR) 9941 break; 9942 /* See comment in test_alloc_parse_xdecl() */ 9943 alloc_teardown(); 9944 alloc_setup(); 9945 } 9946 if (i == 0) 9947 fail("Parse succeeded despite failing allocator"); 9948 if (i == max_alloc_count) 9949 fail("Parse failed at maximum allocation count"); 9950 } 9951 END_TEST 9952 9953 /* Test that a character reference at the end of a suitably long 9954 * default value for an attribute can trigger pool growth, and recovers 9955 * if the allocator fails on it. 9956 */ 9957 START_TEST(test_alloc_long_attr_default_with_char_ref) 9958 { 9959 const char *text = 9960 "<!DOCTYPE doc [<!ATTLIST doc a CDATA '" 9961 /* 64 characters per line */ 9962 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9963 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9964 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9965 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9966 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9967 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9968 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9969 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9970 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9971 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9972 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9973 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9974 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9975 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9976 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 9977 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHI" 9978 "1'>]>\n" 9979 "<doc/>"; 9980 int i; 9981 const int max_alloc_count = 20; 9982 9983 for (i = 0; i < max_alloc_count; i++) { 9984 allocation_count = i; 9985 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 9986 XML_TRUE) != XML_STATUS_ERROR) 9987 break; 9988 /* See comment in test_alloc_parse_xdecl() */ 9989 alloc_teardown(); 9990 alloc_setup(); 9991 } 9992 if (i == 0) 9993 fail("Parse succeeded despite failing allocator"); 9994 if (i == max_alloc_count) 9995 fail("Parse failed at maximum allocation count"); 9996 } 9997 END_TEST 9998 9999 /* Test that a long character reference substitution triggers a pool 10000 * expansion correctly for an attribute value. 10001 */ 10002 START_TEST(test_alloc_long_attr_value) 10003 { 10004 const char *text = 10005 "<!DOCTYPE test [<!ENTITY foo '\n" 10006 /* 64 characters per line */ 10007 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10008 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10009 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10010 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10011 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10012 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10013 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10014 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10015 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10016 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10017 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10018 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10019 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10020 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10021 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10022 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10023 "'>]>\n" 10024 "<test a='&foo;'/>"; 10025 int i; 10026 const int max_alloc_count = 25; 10027 10028 for (i = 0; i < max_alloc_count; i++) { 10029 allocation_count = i; 10030 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 10031 XML_TRUE) != XML_STATUS_ERROR) 10032 break; 10033 /* See comment in test_alloc_parse_xdecl() */ 10034 alloc_teardown(); 10035 alloc_setup(); 10036 } 10037 if (i == 0) 10038 fail("Parse succeeded despite failing allocator"); 10039 if (i == max_alloc_count) 10040 fail("Parse failed at maximum allocation count"); 10041 } 10042 END_TEST 10043 10044 /* Test that an error in a nested parameter entity substitution is 10045 * handled correctly. It seems unlikely that the code path being 10046 * exercised can be reached purely by carefully crafted XML, but an 10047 * allocation error in the right place will definitely do it. 10048 */ 10049 START_TEST(test_alloc_nested_entities) 10050 { 10051 const char *text = 10052 "<!DOCTYPE doc SYSTEM 'http://example.org/one.ent'>\n" 10053 "<doc />"; 10054 ExtFaults test_data = { 10055 "<!ENTITY % pe1 '" 10056 /* 64 characters per line */ 10057 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10058 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10059 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10060 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10061 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10062 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10063 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10064 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10065 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10066 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10067 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10068 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10069 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10070 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10071 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10072 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10073 "'>\n" 10074 "<!ENTITY % pe2 '%pe1;'>\n" 10075 "%pe2;", 10076 "Memory Fail not faulted", 10077 NULL, 10078 XML_ERROR_NO_MEMORY 10079 }; 10080 10081 /* Causes an allocation error in a nested storeEntityValue() */ 10082 allocation_count = 12; 10083 XML_SetUserData(parser, &test_data); 10084 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 10085 XML_SetExternalEntityRefHandler(parser, external_entity_faulter); 10086 expect_failure(text, XML_ERROR_EXTERNAL_ENTITY_HANDLING, 10087 "Entity allocation failure not noted"); 10088 } 10089 END_TEST 10090 10091 START_TEST(test_alloc_realloc_param_entity_newline) 10092 { 10093 const char *text = 10094 "<!DOCTYPE doc SYSTEM 'http://example.org/'>\n" 10095 "<doc/>"; 10096 char dtd_text[] = 10097 "<!ENTITY % pe '<!ATTLIST doc att CDATA \"" 10098 /* 64 characters per line */ 10099 "This default value is carefully crafted so that the carriage " 10100 "return right at the end of the entity string causes an internal " 10101 "string pool to have to grow. This allows us to test the alloc " 10102 "failure path from that point. OPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10103 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10104 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10105 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10106 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10107 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10108 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10109 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10110 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10111 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10112 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10113 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10114 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDE" 10115 "\">\n'>" 10116 "%pe;\n"; 10117 int i; 10118 const int max_realloc_count = 5; 10119 10120 for (i = 0; i < max_realloc_count; i++) { 10121 reallocation_count = i; 10122 XML_SetUserData(parser, dtd_text); 10123 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 10124 XML_SetExternalEntityRefHandler(parser, external_entity_alloc); 10125 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 10126 XML_TRUE) != XML_STATUS_ERROR) 10127 break; 10128 /* See comment in test_alloc_parse_xdecl() */ 10129 alloc_teardown(); 10130 alloc_setup(); 10131 } 10132 if (i == 0) 10133 fail("Parse succeeded despite failing reallocator"); 10134 if (i == max_realloc_count) 10135 fail("Parse failed at maximum reallocation count"); 10136 } 10137 END_TEST 10138 10139 START_TEST(test_alloc_realloc_ce_extends_pe) 10140 { 10141 const char *text = 10142 "<!DOCTYPE doc SYSTEM 'http://example.org/'>\n" 10143 "<doc/>"; 10144 char dtd_text[] = 10145 "<!ENTITY % pe '<!ATTLIST doc att CDATA \"" 10146 /* 64 characters per line */ 10147 "This default value is carefully crafted so that the character " 10148 "entity at the end causes an internal string pool to have to " 10149 "grow. This allows us to test the allocation failure path from " 10150 "that point onwards. EFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10151 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10152 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10153 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10154 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10155 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10156 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10157 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10158 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10159 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10160 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10161 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 10162 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGQ" 10163 "\">\n'>" 10164 "%pe;\n"; 10165 int i; 10166 const int max_realloc_count = 5; 10167 10168 for (i = 0; i < max_realloc_count; i++) { 10169 reallocation_count = i; 10170 XML_SetUserData(parser, dtd_text); 10171 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 10172 XML_SetExternalEntityRefHandler(parser, external_entity_alloc); 10173 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 10174 XML_TRUE) != XML_STATUS_ERROR) 10175 break; 10176 /* See comment in test_alloc_parse_xdecl() */ 10177 alloc_teardown(); 10178 alloc_setup(); 10179 } 10180 if (i == 0) 10181 fail("Parse succeeded despite failing reallocator"); 10182 if (i == max_realloc_count) 10183 fail("Parse failed at maximum reallocation count"); 10184 } 10185 END_TEST 10186 10187 START_TEST(test_alloc_realloc_attributes) 10188 { 10189 const char *text = 10190 "<!DOCTYPE doc [\n" 10191 " <!ATTLIST doc\n" 10192 " a1 (a|b|c) 'a'\n" 10193 " a2 (foo|bar) #IMPLIED\n" 10194 " a3 NMTOKEN #IMPLIED\n" 10195 " a4 NMTOKENS #IMPLIED\n" 10196 " a5 ID #IMPLIED\n" 10197 " a6 IDREF #IMPLIED\n" 10198 " a7 IDREFS #IMPLIED\n" 10199 " a8 ENTITY #IMPLIED\n" 10200 " a9 ENTITIES #IMPLIED\n" 10201 " a10 CDATA #IMPLIED\n" 10202 " >]>\n" 10203 "<doc>wombat</doc>\n"; 10204 int i; 10205 const int max_realloc_count = 5; 10206 10207 for (i = 0; i < max_realloc_count; i++) { 10208 reallocation_count = i; 10209 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 10210 XML_TRUE) != XML_STATUS_ERROR) 10211 break; 10212 /* See comment in test_alloc_parse_xdecl() */ 10213 alloc_teardown(); 10214 alloc_setup(); 10215 } 10216 10217 if (i == 0) 10218 fail("Parse succeeded despite failing reallocator"); 10219 if (i == max_realloc_count) 10220 fail("Parse failed at maximum reallocation count"); 10221 } 10222 END_TEST 10223 10224 START_TEST(test_alloc_long_doc_name) 10225 { 10226 const char *text = 10227 /* 64 characters per line */ 10228 "<LongRootElementNameThatWillCauseTheNextAllocationToExpandTheStr" 10229 "ingPoolForTheDTDQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10230 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10231 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10232 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10233 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10234 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10235 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10236 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10237 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10238 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10239 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10240 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10241 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10242 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10243 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10244 " a='1'/>"; 10245 int i; 10246 const int max_alloc_count = 20; 10247 10248 for (i = 0; i < max_alloc_count; i++) { 10249 allocation_count = i; 10250 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 10251 XML_TRUE) != XML_STATUS_ERROR) 10252 break; 10253 /* See comment in test_alloc_parse_xdecl() */ 10254 alloc_teardown(); 10255 alloc_setup(); 10256 } 10257 if (i == 0) 10258 fail("Parsing worked despite failing reallocations"); 10259 else if (i == max_alloc_count) 10260 fail("Parsing failed even at max reallocation count"); 10261 } 10262 END_TEST 10263 10264 START_TEST(test_alloc_long_base) 10265 { 10266 const char *text = 10267 "<!DOCTYPE doc [\n" 10268 " <!ENTITY e SYSTEM 'foo'>\n" 10269 "]>\n" 10270 "<doc>&e;</doc>"; 10271 char entity_text[] = "Hello world"; 10272 const XML_Char *base = 10273 /* 64 characters per line */ 10274 XCS("LongBaseURI/that/will/overflow/an/internal/buffer/and/cause/it/t") 10275 XCS("o/have/to/grow/PQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/") 10276 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/") 10277 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/") 10278 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/") 10279 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/") 10280 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/") 10281 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/") 10282 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/") 10283 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/") 10284 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/") 10285 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/") 10286 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/") 10287 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/") 10288 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/") 10289 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"); 10290 int i; 10291 const int max_alloc_count = 25; 10292 10293 for (i = 0; i < max_alloc_count; i++) { 10294 allocation_count = i; 10295 XML_SetUserData(parser, entity_text); 10296 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 10297 XML_SetExternalEntityRefHandler(parser, external_entity_alloc); 10298 if (XML_SetBase(parser, base) == XML_STATUS_ERROR) { 10299 XML_ParserReset(parser, NULL); 10300 continue; 10301 } 10302 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 10303 XML_TRUE) != XML_STATUS_ERROR) 10304 break; 10305 /* See comment in test_alloc_parse_xdecl() */ 10306 alloc_teardown(); 10307 alloc_setup(); 10308 } 10309 if (i == 0) 10310 fail("Parsing worked despite failing allocations"); 10311 else if (i == max_alloc_count) 10312 fail("Parsing failed even at max allocation count"); 10313 } 10314 END_TEST 10315 10316 START_TEST(test_alloc_long_public_id) 10317 { 10318 const char *text = 10319 "<!DOCTYPE doc [\n" 10320 " <!ENTITY e PUBLIC '" 10321 /* 64 characters per line */ 10322 "LongPublicIDThatShouldResultInAnInternalStringPoolGrowingAtASpec" 10323 "ificMomentKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10324 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10325 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10326 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10327 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10328 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10329 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10330 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10331 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10332 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10333 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10334 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10335 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10336 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10337 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10338 "' 'bar'>\n" 10339 "]>\n" 10340 "<doc>&e;</doc>"; 10341 char entity_text[] = "Hello world"; 10342 int i; 10343 const int max_alloc_count = 40; 10344 10345 for (i = 0; i < max_alloc_count; i++) { 10346 allocation_count = i; 10347 XML_SetUserData(parser, entity_text); 10348 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 10349 XML_SetExternalEntityRefHandler(parser, external_entity_alloc); 10350 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 10351 XML_TRUE) != XML_STATUS_ERROR) 10352 break; 10353 /* See comment in test_alloc_parse_xdecl() */ 10354 alloc_teardown(); 10355 alloc_setup(); 10356 } 10357 if (i == 0) 10358 fail("Parsing worked despite failing allocations"); 10359 else if (i == max_alloc_count) 10360 fail("Parsing failed even at max allocation count"); 10361 } 10362 END_TEST 10363 10364 START_TEST(test_alloc_long_entity_value) 10365 { 10366 const char *text = 10367 "<!DOCTYPE doc [\n" 10368 " <!ENTITY e1 '" 10369 /* 64 characters per line */ 10370 "Long entity value that should provoke a string pool to grow whil" 10371 "e setting up to parse the external entity below. xyz0123456789AB" 10372 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10373 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10374 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10375 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10376 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10377 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10378 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10379 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10380 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10381 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10382 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10383 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10384 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10385 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10386 "'>\n" 10387 " <!ENTITY e2 SYSTEM 'bar'>\n" 10388 "]>\n" 10389 "<doc>&e2;</doc>"; 10390 char entity_text[] = "Hello world"; 10391 int i; 10392 const int max_alloc_count = 40; 10393 10394 for (i = 0; i < max_alloc_count; i++) { 10395 allocation_count = i; 10396 XML_SetUserData(parser, entity_text); 10397 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 10398 XML_SetExternalEntityRefHandler(parser, external_entity_alloc); 10399 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 10400 XML_TRUE) != XML_STATUS_ERROR) 10401 break; 10402 /* See comment in test_alloc_parse_xdecl() */ 10403 alloc_teardown(); 10404 alloc_setup(); 10405 } 10406 if (i == 0) 10407 fail("Parsing worked despite failing allocations"); 10408 else if (i == max_alloc_count) 10409 fail("Parsing failed even at max allocation count"); 10410 } 10411 END_TEST 10412 10413 START_TEST(test_alloc_long_notation) 10414 { 10415 const char *text = 10416 "<!DOCTYPE doc [\n" 10417 " <!NOTATION note SYSTEM '" 10418 /* 64 characters per line */ 10419 "ALongNotationNameThatShouldProvokeStringPoolGrowthWhileCallingAn" 10420 "ExternalEntityParserUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10421 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10422 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10423 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10424 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10425 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10426 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10427 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10428 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10429 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10430 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10431 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10432 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10433 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10434 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10435 "'>\n" 10436 " <!ENTITY e1 SYSTEM 'foo' NDATA " 10437 /* 64 characters per line */ 10438 "ALongNotationNameThatShouldProvokeStringPoolGrowthWhileCallingAn" 10439 "ExternalEntityParserUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10440 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10441 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10442 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10443 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10444 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10445 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10446 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10447 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10448 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10449 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10450 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10451 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10452 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10453 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 10454 ">\n" 10455 " <!ENTITY e2 SYSTEM 'bar'>\n" 10456 "]>\n" 10457 "<doc>&e2;</doc>"; 10458 ExtOption options[] = { 10459 { XCS("foo"), "Entity Foo" }, 10460 { XCS("bar"), "Entity Bar" }, 10461 { NULL, NULL } 10462 }; 10463 int i; 10464 const int max_alloc_count = 40; 10465 10466 for (i = 0; i < max_alloc_count; i++) { 10467 allocation_count = i; 10468 XML_SetUserData(parser, options); 10469 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 10470 XML_SetExternalEntityRefHandler(parser, external_entity_optioner); 10471 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 10472 XML_TRUE) != XML_STATUS_ERROR) 10473 break; 10474 10475 /* See comment in test_alloc_parse_xdecl() */ 10476 alloc_teardown(); 10477 alloc_setup(); 10478 } 10479 if (i == 0) 10480 fail("Parsing worked despite failing allocations"); 10481 else if (i == max_alloc_count) 10482 fail("Parsing failed even at max allocation count"); 10483 } 10484 END_TEST 10485 10486 10487 static void 10488 nsalloc_setup(void) 10489 { 10490 XML_Memory_Handling_Suite memsuite = { 10491 duff_allocator, 10492 duff_reallocator, 10493 free 10494 }; 10495 XML_Char ns_sep[2] = { ' ', '\0' }; 10496 10497 /* Ensure the parser creation will go through */ 10498 allocation_count = ALLOC_ALWAYS_SUCCEED; 10499 reallocation_count = REALLOC_ALWAYS_SUCCEED; 10500 parser = XML_ParserCreate_MM(NULL, &memsuite, ns_sep); 10501 if (parser == NULL) 10502 fail("Parser not created"); 10503 } 10504 10505 static void 10506 nsalloc_teardown(void) 10507 { 10508 basic_teardown(); 10509 } 10510 10511 10512 /* Test the effects of allocation failure in simple namespace parsing. 10513 * Based on test_ns_default_with_empty_uri() 10514 */ 10515 START_TEST(test_nsalloc_xmlns) 10516 { 10517 const char *text = 10518 "<doc xmlns='http://example.org/'>\n" 10519 " <e xmlns=''/>\n" 10520 "</doc>"; 10521 unsigned int i; 10522 const unsigned int max_alloc_count = 30; 10523 10524 for (i = 0; i < max_alloc_count; i++) { 10525 allocation_count = i; 10526 /* Exercise more code paths with a default handler */ 10527 XML_SetDefaultHandler(parser, dummy_default_handler); 10528 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 10529 XML_TRUE) != XML_STATUS_ERROR) 10530 break; 10531 /* Resetting the parser is insufficient, because some memory 10532 * allocations are cached within the parser. Instead we use 10533 * the teardown and setup routines to ensure that we have the 10534 * right sort of parser back in our hands. 10535 */ 10536 nsalloc_teardown(); 10537 nsalloc_setup(); 10538 } 10539 if (i == 0) 10540 fail("Parsing worked despite failing allocations"); 10541 else if (i == max_alloc_count) 10542 fail("Parsing failed even at maximum allocation count"); 10543 } 10544 END_TEST 10545 10546 /* Test XML_ParseBuffer interface with namespace and a dicky allocator */ 10547 START_TEST(test_nsalloc_parse_buffer) 10548 { 10549 const char *text = "<doc>Hello</doc>"; 10550 void *buffer; 10551 10552 /* Try a parse before the start of the world */ 10553 /* (Exercises new code path) */ 10554 allocation_count = 0; 10555 if (XML_ParseBuffer(parser, 0, XML_FALSE) != XML_STATUS_ERROR) 10556 fail("Pre-init XML_ParseBuffer not faulted"); 10557 if (XML_GetErrorCode(parser) != XML_ERROR_NO_MEMORY) 10558 fail("Pre-init XML_ParseBuffer faulted for wrong reason"); 10559 10560 /* Now with actual memory allocation */ 10561 allocation_count = ALLOC_ALWAYS_SUCCEED; 10562 if (XML_ParseBuffer(parser, 0, XML_FALSE) != XML_STATUS_OK) 10563 xml_failure(parser); 10564 10565 /* Check that resuming an unsuspended parser is faulted */ 10566 if (XML_ResumeParser(parser) != XML_STATUS_ERROR) 10567 fail("Resuming unsuspended parser not faulted"); 10568 if (XML_GetErrorCode(parser) != XML_ERROR_NOT_SUSPENDED) 10569 xml_failure(parser); 10570 10571 /* Get the parser into suspended state */ 10572 XML_SetCharacterDataHandler(parser, clearing_aborting_character_handler); 10573 resumable = XML_TRUE; 10574 buffer = XML_GetBuffer(parser, (int)strlen(text)); 10575 if (buffer == NULL) 10576 fail("Could not acquire parse buffer"); 10577 memcpy(buffer, text, strlen(text)); 10578 if (XML_ParseBuffer(parser, (int)strlen(text), 10579 XML_TRUE) != XML_STATUS_SUSPENDED) 10580 xml_failure(parser); 10581 if (XML_GetErrorCode(parser) != XML_ERROR_NONE) 10582 xml_failure(parser); 10583 if (XML_ParseBuffer(parser, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR) 10584 fail("Suspended XML_ParseBuffer not faulted"); 10585 if (XML_GetErrorCode(parser) != XML_ERROR_SUSPENDED) 10586 xml_failure(parser); 10587 if (XML_GetBuffer(parser, (int)strlen(text)) != NULL) 10588 fail("Suspended XML_GetBuffer not faulted"); 10589 10590 /* Get it going again and complete the world */ 10591 XML_SetCharacterDataHandler(parser, NULL); 10592 if (XML_ResumeParser(parser) != XML_STATUS_OK) 10593 xml_failure(parser); 10594 if (XML_ParseBuffer(parser, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR) 10595 fail("Post-finishing XML_ParseBuffer not faulted"); 10596 if (XML_GetErrorCode(parser) != XML_ERROR_FINISHED) 10597 xml_failure(parser); 10598 if (XML_GetBuffer(parser, (int)strlen(text)) != NULL) 10599 fail("Post-finishing XML_GetBuffer not faulted"); 10600 } 10601 END_TEST 10602 10603 /* Check handling of long prefix names (pool growth) */ 10604 START_TEST(test_nsalloc_long_prefix) 10605 { 10606 const char *text = 10607 "<" 10608 /* 64 characters per line */ 10609 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10610 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10611 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10612 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10613 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10614 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10615 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10616 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10617 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10618 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10619 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10620 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10621 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10622 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10623 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10624 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10625 ":foo xmlns:" 10626 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10627 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10628 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10629 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10630 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10631 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10632 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10633 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10634 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10635 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10636 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10637 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10638 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10639 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10640 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10641 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10642 "='http://example.org/'>" 10643 "</" 10644 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10645 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10646 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10647 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10648 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10649 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10650 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10651 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10652 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10653 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10654 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10655 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10656 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10657 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10658 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10659 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10660 ":foo>"; 10661 int i; 10662 const int max_alloc_count = 40; 10663 10664 for (i = 0; i < max_alloc_count; i++) { 10665 allocation_count = i; 10666 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 10667 XML_TRUE) != XML_STATUS_ERROR) 10668 break; 10669 /* See comment in test_nsalloc_xmlns() */ 10670 nsalloc_teardown(); 10671 nsalloc_setup(); 10672 } 10673 if (i == 0) 10674 fail("Parsing worked despite failing allocations"); 10675 else if (i == max_alloc_count) 10676 fail("Parsing failed even at max allocation count"); 10677 } 10678 END_TEST 10679 10680 /* Check handling of long uri names (pool growth) */ 10681 START_TEST(test_nsalloc_long_uri) 10682 { 10683 const char *text = 10684 "<foo:e xmlns:foo='http://example.org/" 10685 /* 64 characters per line */ 10686 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/" 10687 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/" 10688 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/" 10689 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/" 10690 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/" 10691 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/" 10692 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/" 10693 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/" 10694 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/" 10695 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/" 10696 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/" 10697 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/" 10698 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/" 10699 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/" 10700 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/" 10701 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/" 10702 "' bar:a='12'\n" 10703 "xmlns:bar='http://example.org/" 10704 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/" 10705 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/" 10706 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/" 10707 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/" 10708 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/" 10709 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/" 10710 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/" 10711 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/" 10712 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/" 10713 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/" 10714 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/" 10715 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/" 10716 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/" 10717 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/" 10718 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/" 10719 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/" 10720 "'>" 10721 "</foo:e>"; 10722 int i; 10723 const int max_alloc_count = 40; 10724 10725 for (i = 0; i < max_alloc_count; i++) { 10726 allocation_count = i; 10727 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 10728 XML_TRUE) != XML_STATUS_ERROR) 10729 break; 10730 /* See comment in test_nsalloc_xmlns() */ 10731 nsalloc_teardown(); 10732 nsalloc_setup(); 10733 } 10734 if (i == 0) 10735 fail("Parsing worked despite failing allocations"); 10736 else if (i == max_alloc_count) 10737 fail("Parsing failed even at max allocation count"); 10738 } 10739 END_TEST 10740 10741 /* Test handling of long attribute names with prefixes */ 10742 START_TEST(test_nsalloc_long_attr) 10743 { 10744 const char *text = 10745 "<foo:e xmlns:foo='http://example.org/' bar:" 10746 /* 64 characters per line */ 10747 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10748 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10749 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10750 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10751 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10752 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10753 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10754 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10755 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10756 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10757 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10758 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10759 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10760 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10761 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10762 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10763 "='12'\n" 10764 "xmlns:bar='http://example.org/'>" 10765 "</foo:e>"; 10766 int i; 10767 const int max_alloc_count = 40; 10768 10769 for (i = 0; i < max_alloc_count; i++) { 10770 allocation_count = i; 10771 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 10772 XML_TRUE) != XML_STATUS_ERROR) 10773 break; 10774 /* See comment in test_nsalloc_xmlns() */ 10775 nsalloc_teardown(); 10776 nsalloc_setup(); 10777 } 10778 if (i == 0) 10779 fail("Parsing worked despite failing allocations"); 10780 else if (i == max_alloc_count) 10781 fail("Parsing failed even at max allocation count"); 10782 } 10783 END_TEST 10784 10785 /* Test handling of an attribute name with a long namespace prefix */ 10786 START_TEST(test_nsalloc_long_attr_prefix) 10787 { 10788 const char *text = 10789 "<foo:e xmlns:foo='http://example.org/' " 10790 /* 64 characters per line */ 10791 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10792 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10793 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10794 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10795 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10796 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10797 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10798 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10799 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10800 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10801 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10802 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10803 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10804 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10805 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10806 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10807 ":a='12'\n" 10808 "xmlns:" 10809 /* 64 characters per line */ 10810 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10811 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10812 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10813 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10814 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10815 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10816 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10817 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10818 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10819 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10820 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10821 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10822 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10823 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10824 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10825 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10826 "='http://example.org/'>" 10827 "</foo:e>"; 10828 const XML_Char *elemstr[] = { 10829 XCS("http://example.org/ e foo"), 10830 XCS("http://example.org/ a ") 10831 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ") 10832 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ") 10833 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ") 10834 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ") 10835 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ") 10836 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ") 10837 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ") 10838 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ") 10839 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ") 10840 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ") 10841 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ") 10842 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ") 10843 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ") 10844 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ") 10845 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ") 10846 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ") 10847 }; 10848 int i; 10849 const int max_alloc_count = 40; 10850 10851 for (i = 0; i < max_alloc_count; i++) { 10852 allocation_count = i; 10853 XML_SetReturnNSTriplet(parser, XML_TRUE); 10854 XML_SetUserData(parser, (void *)elemstr); 10855 XML_SetElementHandler(parser, 10856 triplet_start_checker, 10857 triplet_end_checker); 10858 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 10859 XML_TRUE) != XML_STATUS_ERROR) 10860 break; 10861 /* See comment in test_nsalloc_xmlns() */ 10862 nsalloc_teardown(); 10863 nsalloc_setup(); 10864 } 10865 if (i == 0) 10866 fail("Parsing worked despite failing allocations"); 10867 else if (i == max_alloc_count) 10868 fail("Parsing failed even at max allocation count"); 10869 } 10870 END_TEST 10871 10872 /* Test attribute handling in the face of a dodgy reallocator */ 10873 START_TEST(test_nsalloc_realloc_attributes) 10874 { 10875 const char *text = 10876 "<foo:e xmlns:foo='http://example.org/' bar:a='12'\n" 10877 " xmlns:bar='http://example.org/'>" 10878 "</foo:e>"; 10879 int i; 10880 const int max_realloc_count = 10; 10881 10882 for (i = 0; i < max_realloc_count; i++) { 10883 reallocation_count = i; 10884 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 10885 XML_TRUE) != XML_STATUS_ERROR) 10886 break; 10887 /* See comment in test_nsalloc_xmlns() */ 10888 nsalloc_teardown(); 10889 nsalloc_setup(); 10890 } 10891 if (i == 0) 10892 fail("Parsing worked despite failing reallocations"); 10893 else if (i == max_realloc_count) 10894 fail("Parsing failed at max reallocation count"); 10895 } 10896 END_TEST 10897 10898 /* Test long element names with namespaces under a failing allocator */ 10899 START_TEST(test_nsalloc_long_element) 10900 { 10901 const char *text = 10902 "<foo:thisisalongenoughelementnametotriggerareallocation\n" 10903 " xmlns:foo='http://example.org/' bar:a='12'\n" 10904 " xmlns:bar='http://example.org/'>" 10905 "</foo:thisisalongenoughelementnametotriggerareallocation>"; 10906 const XML_Char *elemstr[] = { 10907 XCS("http://example.org/") 10908 XCS(" thisisalongenoughelementnametotriggerareallocation foo"), 10909 XCS("http://example.org/ a bar") 10910 }; 10911 int i; 10912 const int max_alloc_count = 30; 10913 10914 for (i = 0; i < max_alloc_count; i++) { 10915 allocation_count = i; 10916 XML_SetReturnNSTriplet(parser, XML_TRUE); 10917 XML_SetUserData(parser, (void *)elemstr); 10918 XML_SetElementHandler(parser, 10919 triplet_start_checker, 10920 triplet_end_checker); 10921 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 10922 XML_TRUE) != XML_STATUS_ERROR) 10923 break; 10924 /* See comment in test_nsalloc_xmlns() */ 10925 nsalloc_teardown(); 10926 nsalloc_setup(); 10927 } 10928 if (i == 0) 10929 fail("Parsing worked despite failing reallocations"); 10930 else if (i == max_alloc_count) 10931 fail("Parsing failed at max reallocation count"); 10932 } 10933 END_TEST 10934 10935 /* Test the effects of reallocation failure when reassigning a 10936 * binding. 10937 * 10938 * XML_ParserReset does not free the BINDING structures used by a 10939 * parser, but instead adds them to an internal free list to be reused 10940 * as necessary. Likewise the URI buffers allocated for the binding 10941 * aren't freed, but kept attached to their existing binding. If the 10942 * new binding has a longer URI, it will need reallocation. This test 10943 * provokes that reallocation, and tests the control path if it fails. 10944 */ 10945 START_TEST(test_nsalloc_realloc_binding_uri) 10946 { 10947 const char *first = 10948 "<doc xmlns='http://example.org/'>\n" 10949 " <e xmlns='' />\n" 10950 "</doc>"; 10951 const char *second = 10952 "<doc xmlns='http://example.org/long/enough/URI/to/reallocate/'>\n" 10953 " <e xmlns='' />\n" 10954 "</doc>"; 10955 unsigned i; 10956 const unsigned max_realloc_count = 10; 10957 10958 /* First, do a full parse that will leave bindings around */ 10959 if (_XML_Parse_SINGLE_BYTES(parser, first, (int)strlen(first), 10960 XML_TRUE) == XML_STATUS_ERROR) 10961 xml_failure(parser); 10962 10963 /* Now repeat with a longer URI and a duff reallocator */ 10964 for (i = 0; i < max_realloc_count; i++) { 10965 XML_ParserReset(parser, NULL); 10966 reallocation_count = i; 10967 if (_XML_Parse_SINGLE_BYTES(parser, second, (int)strlen(second), 10968 XML_TRUE) != XML_STATUS_ERROR) 10969 break; 10970 } 10971 if (i == 0) 10972 fail("Parsing worked despite failing reallocation"); 10973 else if (i == max_realloc_count) 10974 fail("Parsing failed at max reallocation count"); 10975 } 10976 END_TEST 10977 10978 /* Check handling of long prefix names (pool growth) */ 10979 START_TEST(test_nsalloc_realloc_long_prefix) 10980 { 10981 const char *text = 10982 "<" 10983 /* 64 characters per line */ 10984 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10985 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10986 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10987 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10988 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10989 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10990 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10991 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10992 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10993 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10994 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10995 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10996 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10997 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10998 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 10999 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11000 ":foo xmlns:" 11001 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11002 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11003 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11004 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11005 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11006 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11007 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11008 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11009 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11010 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11011 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11012 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11013 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11014 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11015 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11016 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11017 "='http://example.org/'>" 11018 "</" 11019 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11020 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11021 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11022 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11023 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11024 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11025 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11026 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11027 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11028 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11029 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11030 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11031 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11032 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11033 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11034 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11035 ":foo>"; 11036 int i; 11037 const int max_realloc_count = 12; 11038 11039 for (i = 0; i < max_realloc_count; i++) { 11040 reallocation_count = i; 11041 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 11042 XML_TRUE) != XML_STATUS_ERROR) 11043 break; 11044 /* See comment in test_nsalloc_xmlns() */ 11045 nsalloc_teardown(); 11046 nsalloc_setup(); 11047 } 11048 if (i == 0) 11049 fail("Parsing worked despite failing reallocations"); 11050 else if (i == max_realloc_count) 11051 fail("Parsing failed even at max reallocation count"); 11052 } 11053 END_TEST 11054 11055 /* Check handling of even long prefix names (different code path) */ 11056 START_TEST(test_nsalloc_realloc_longer_prefix) 11057 { 11058 const char *text = 11059 "<" 11060 /* 64 characters per line */ 11061 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11062 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11063 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11064 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11065 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11066 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11067 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11068 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11069 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11070 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11071 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11072 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11073 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11074 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11075 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11076 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11077 "Q:foo xmlns:" 11078 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11079 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11080 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11081 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11082 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11083 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11084 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11085 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11086 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11087 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11088 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11089 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11090 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11091 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11092 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11093 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11094 "Q='http://example.org/'>" 11095 "</" 11096 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11097 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11098 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11099 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11100 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11101 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11102 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11103 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11104 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11105 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11106 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11107 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11108 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11109 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11110 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11111 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11112 "Q:foo>"; 11113 int i; 11114 const int max_realloc_count = 12; 11115 11116 for (i = 0; i < max_realloc_count; i++) { 11117 reallocation_count = i; 11118 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 11119 XML_TRUE) != XML_STATUS_ERROR) 11120 break; 11121 /* See comment in test_nsalloc_xmlns() */ 11122 nsalloc_teardown(); 11123 nsalloc_setup(); 11124 } 11125 if (i == 0) 11126 fail("Parsing worked despite failing reallocations"); 11127 else if (i == max_realloc_count) 11128 fail("Parsing failed even at max reallocation count"); 11129 } 11130 END_TEST 11131 11132 START_TEST(test_nsalloc_long_namespace) 11133 { 11134 const char *text1 = 11135 "<" 11136 /* 64 characters per line */ 11137 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11138 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11139 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11140 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11141 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11142 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11143 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11144 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11145 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11146 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11147 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11148 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11149 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11150 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11151 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11152 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11153 ":e xmlns:" 11154 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11155 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11156 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11157 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11158 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11159 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11160 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11161 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11162 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11163 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11164 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11165 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11166 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11167 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11168 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11169 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11170 "='http://example.org/'>\n"; 11171 const char *text2 = 11172 "<" 11173 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11174 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11175 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11176 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11177 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11178 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11179 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11180 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11181 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11182 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11183 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11184 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11185 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11186 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11187 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11188 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11189 ":f " 11190 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11191 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11192 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11193 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11194 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11195 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11196 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11197 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11198 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11199 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11200 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11201 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11202 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11203 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11204 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11205 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11206 ":attr='foo'/>\n" 11207 "</" 11208 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11209 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11210 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11211 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11212 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11213 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11214 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11215 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11216 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11217 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11218 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11219 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11220 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11221 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11222 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11223 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11224 ":e>"; 11225 int i; 11226 const int max_alloc_count = 40; 11227 11228 for (i = 0; i < max_alloc_count; i++) { 11229 allocation_count = i; 11230 if (_XML_Parse_SINGLE_BYTES(parser, text1, (int)strlen(text1), 11231 XML_FALSE) != XML_STATUS_ERROR && 11232 _XML_Parse_SINGLE_BYTES(parser, text2, (int)strlen(text2), 11233 XML_TRUE) != XML_STATUS_ERROR) 11234 break; 11235 /* See comment in test_nsalloc_xmlns() */ 11236 nsalloc_teardown(); 11237 nsalloc_setup(); 11238 } 11239 if (i == 0) 11240 fail("Parsing worked despite failing allocations"); 11241 else if (i == max_alloc_count) 11242 fail("Parsing failed even at max allocation count"); 11243 } 11244 END_TEST 11245 11246 /* Using a slightly shorter namespace name provokes allocations in 11247 * slightly different places in the code. 11248 */ 11249 START_TEST(test_nsalloc_less_long_namespace) 11250 { 11251 const char *text = 11252 "<" 11253 /* 64 characters per line */ 11254 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11255 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11256 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11257 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11258 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11259 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11260 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11261 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678" 11262 ":e xmlns:" 11263 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11264 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11265 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11266 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11267 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11268 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11269 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11270 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678" 11271 "='http://example.org/'>\n" 11272 "<" 11273 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11274 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11275 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11276 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11277 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11278 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11279 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11280 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678" 11281 ":f " 11282 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11283 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11284 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11285 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11286 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11287 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11288 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11289 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678" 11290 ":att='foo'/>\n" 11291 "</" 11292 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11293 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11294 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11295 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11296 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11297 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11298 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 11299 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678" 11300 ":e>"; 11301 int i; 11302 const int max_alloc_count = 40; 11303 11304 for (i = 0; i < max_alloc_count; i++) { 11305 allocation_count = i; 11306 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 11307 XML_TRUE) != XML_STATUS_ERROR) 11308 break; 11309 /* See comment in test_nsalloc_xmlns() */ 11310 nsalloc_teardown(); 11311 nsalloc_setup(); 11312 } 11313 if (i == 0) 11314 fail("Parsing worked despite failing allocations"); 11315 else if (i == max_alloc_count) 11316 fail("Parsing failed even at max allocation count"); 11317 } 11318 END_TEST 11319 11320 START_TEST(test_nsalloc_long_context) 11321 { 11322 const char *text = 11323 "<!DOCTYPE doc SYSTEM 'foo' [\n" 11324 " <!ATTLIST doc baz ID #REQUIRED>\n" 11325 " <!ENTITY en SYSTEM 'bar'>\n" 11326 "]>\n" 11327 "<doc xmlns='http://example.org/" 11328 /* 64 characters per line */ 11329 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11330 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11331 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11332 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11333 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11334 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11335 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11336 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11337 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11338 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11339 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11340 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11341 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11342 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11343 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11344 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKL" 11345 "' baz='2'>\n" 11346 "&en;" 11347 "</doc>"; 11348 ExtOption options[] = { 11349 { XCS("foo"), "<!ELEMENT e EMPTY>"}, 11350 { XCS("bar"), "<e/>" }, 11351 { NULL, NULL } 11352 }; 11353 int i; 11354 const int max_alloc_count = 70; 11355 11356 for (i = 0; i < max_alloc_count; i++) { 11357 allocation_count = i; 11358 XML_SetUserData(parser, options); 11359 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 11360 XML_SetExternalEntityRefHandler(parser, external_entity_optioner); 11361 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 11362 XML_TRUE) != XML_STATUS_ERROR) 11363 break; 11364 11365 /* See comment in test_nsalloc_xmlns() */ 11366 nsalloc_teardown(); 11367 nsalloc_setup(); 11368 } 11369 if (i == 0) 11370 fail("Parsing worked despite failing allocations"); 11371 else if (i == max_alloc_count) 11372 fail("Parsing failed even at max allocation count"); 11373 } 11374 END_TEST 11375 11376 /* This function is void; it will throw a fail() on error, so if it 11377 * returns normally it must have succeeded. 11378 */ 11379 static void 11380 context_realloc_test(const char *text) 11381 { 11382 ExtOption options[] = { 11383 { XCS("foo"), "<!ELEMENT e EMPTY>"}, 11384 { XCS("bar"), "<e/>" }, 11385 { NULL, NULL } 11386 }; 11387 int i; 11388 const int max_realloc_count = 6; 11389 11390 for (i = 0; i < max_realloc_count; i++) { 11391 reallocation_count = i; 11392 XML_SetUserData(parser, options); 11393 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 11394 XML_SetExternalEntityRefHandler(parser, external_entity_optioner); 11395 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 11396 XML_TRUE) != XML_STATUS_ERROR) 11397 break; 11398 /* See comment in test_nsalloc_xmlns() */ 11399 nsalloc_teardown(); 11400 nsalloc_setup(); 11401 } 11402 if (i == 0) 11403 fail("Parsing worked despite failing reallocations"); 11404 else if (i == max_realloc_count) 11405 fail("Parsing failed even at max reallocation count"); 11406 } 11407 11408 START_TEST(test_nsalloc_realloc_long_context) 11409 { 11410 const char *text = 11411 "<!DOCTYPE doc SYSTEM 'foo' [\n" 11412 " <!ENTITY en SYSTEM 'bar'>\n" 11413 "]>\n" 11414 "<doc xmlns='http://example.org/" 11415 /* 64 characters per line */ 11416 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11417 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11418 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11419 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11420 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11421 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11422 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11423 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11424 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11425 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11426 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11427 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11428 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11429 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11430 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11431 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKL" 11432 "'>\n" 11433 "&en;" 11434 "</doc>"; 11435 11436 context_realloc_test(text); 11437 } 11438 END_TEST 11439 11440 START_TEST(test_nsalloc_realloc_long_context_2) 11441 { 11442 const char *text = 11443 "<!DOCTYPE doc SYSTEM 'foo' [\n" 11444 " <!ENTITY en SYSTEM 'bar'>\n" 11445 "]>\n" 11446 "<doc xmlns='http://example.org/" 11447 /* 64 characters per line */ 11448 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11449 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11450 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11451 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11452 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11453 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11454 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11455 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11456 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11457 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11458 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11459 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11460 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11461 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11462 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11463 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJK" 11464 "'>\n" 11465 "&en;" 11466 "</doc>"; 11467 11468 context_realloc_test(text); 11469 } 11470 END_TEST 11471 11472 START_TEST(test_nsalloc_realloc_long_context_3) 11473 { 11474 const char *text = 11475 "<!DOCTYPE doc SYSTEM 'foo' [\n" 11476 " <!ENTITY en SYSTEM 'bar'>\n" 11477 "]>\n" 11478 "<doc xmlns='http://example.org/" 11479 /* 64 characters per line */ 11480 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11481 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11482 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11483 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11484 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11485 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11486 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11487 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11488 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11489 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11490 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11491 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11492 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11493 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11494 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11495 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGH" 11496 "'>\n" 11497 "&en;" 11498 "</doc>"; 11499 11500 context_realloc_test(text); 11501 } 11502 END_TEST 11503 11504 START_TEST(test_nsalloc_realloc_long_context_4) 11505 { 11506 const char *text = 11507 "<!DOCTYPE doc SYSTEM 'foo' [\n" 11508 " <!ENTITY en SYSTEM 'bar'>\n" 11509 "]>\n" 11510 "<doc xmlns='http://example.org/" 11511 /* 64 characters per line */ 11512 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11513 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11514 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11515 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11516 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11517 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11518 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11519 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11520 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11521 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11522 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11523 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11524 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11525 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11526 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11527 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO" 11528 "'>\n" 11529 "&en;" 11530 "</doc>"; 11531 11532 context_realloc_test(text); 11533 } 11534 END_TEST 11535 11536 START_TEST(test_nsalloc_realloc_long_context_5) 11537 { 11538 const char *text = 11539 "<!DOCTYPE doc SYSTEM 'foo' [\n" 11540 " <!ENTITY en SYSTEM 'bar'>\n" 11541 "]>\n" 11542 "<doc xmlns='http://example.org/" 11543 /* 64 characters per line */ 11544 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11545 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11546 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11547 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11548 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11549 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11550 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11551 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11552 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11553 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11554 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11555 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11556 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11557 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11558 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11559 "ABC" 11560 "'>\n" 11561 "&en;" 11562 "</doc>"; 11563 11564 context_realloc_test(text); 11565 } 11566 END_TEST 11567 11568 START_TEST(test_nsalloc_realloc_long_context_6) 11569 { 11570 const char *text = 11571 "<!DOCTYPE doc SYSTEM 'foo' [\n" 11572 " <!ENTITY en SYSTEM 'bar'>\n" 11573 "]>\n" 11574 "<doc xmlns='http://example.org/" 11575 /* 64 characters per line */ 11576 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11577 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11578 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11579 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11580 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11581 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11582 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11583 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11584 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11585 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11586 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11587 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11588 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11589 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11590 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP" 11591 "'>\n" 11592 "&en;" 11593 "</doc>"; 11594 11595 context_realloc_test(text); 11596 } 11597 END_TEST 11598 11599 START_TEST(test_nsalloc_realloc_long_context_7) 11600 { 11601 const char *text = 11602 "<!DOCTYPE doc SYSTEM 'foo' [\n" 11603 " <!ENTITY en SYSTEM 'bar'>\n" 11604 "]>\n" 11605 "<doc xmlns='http://example.org/" 11606 /* 64 characters per line */ 11607 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11608 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11609 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11610 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11611 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11612 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11613 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11614 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11615 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11616 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11617 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11618 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11619 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11620 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11621 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11622 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLM" 11623 "'>\n" 11624 "&en;" 11625 "</doc>"; 11626 11627 context_realloc_test(text); 11628 } 11629 END_TEST 11630 11631 START_TEST(test_nsalloc_realloc_long_ge_name) 11632 { 11633 const char *text = 11634 "<!DOCTYPE doc SYSTEM 'foo' [\n" 11635 " <!ENTITY " 11636 /* 64 characters per line */ 11637 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11638 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11639 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11640 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11641 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11642 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11643 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11644 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11645 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11646 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11647 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11648 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11649 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11650 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11651 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11652 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11653 " SYSTEM 'bar'>\n" 11654 "]>\n" 11655 "<doc xmlns='http://example.org/baz'>\n" 11656 "&" 11657 /* 64 characters per line */ 11658 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11659 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11660 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11661 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11662 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11663 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11664 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11665 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11666 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11667 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11668 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11669 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11670 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11671 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11672 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11673 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11674 ";" 11675 "</doc>"; 11676 ExtOption options[] = { 11677 { XCS("foo"), "<!ELEMENT el EMPTY>" }, 11678 { XCS("bar"), "<el/>" }, 11679 { NULL, NULL } 11680 }; 11681 int i; 11682 const int max_realloc_count = 10; 11683 11684 for (i = 0; i < max_realloc_count; i++) { 11685 reallocation_count = i; 11686 XML_SetUserData(parser, options); 11687 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 11688 XML_SetExternalEntityRefHandler(parser, external_entity_optioner); 11689 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 11690 XML_TRUE) != XML_STATUS_ERROR) 11691 break; 11692 /* See comment in test_nsalloc_xmlns() */ 11693 nsalloc_teardown(); 11694 nsalloc_setup(); 11695 } 11696 if (i == 0) 11697 fail("Parsing worked despite failing reallocations"); 11698 else if (i == max_realloc_count) 11699 fail("Parsing failed even at max reallocation count"); 11700 } 11701 END_TEST 11702 11703 /* Test that when a namespace is passed through the context mechanism 11704 * to an external entity parser, the parsers handle reallocation 11705 * failures correctly. The prefix is exactly the right length to 11706 * provoke particular uncommon code paths. 11707 */ 11708 START_TEST(test_nsalloc_realloc_long_context_in_dtd) 11709 { 11710 const char *text1 = 11711 "<!DOCTYPE " 11712 /* 64 characters per line */ 11713 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11714 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11715 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11716 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11717 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11718 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11719 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11720 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11721 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11722 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11723 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11724 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11725 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11726 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11727 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11728 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11729 ":doc [\n" 11730 " <!ENTITY First SYSTEM 'foo/First'>\n" 11731 "]>\n" 11732 "<" 11733 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11734 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11735 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11736 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11737 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11738 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11739 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11740 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11741 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11742 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11743 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11744 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11745 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11746 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11747 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11748 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11749 ":doc xmlns:" 11750 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11751 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11752 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11753 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11754 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11755 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11756 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11757 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11758 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11759 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11760 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11761 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11762 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11763 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11764 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11765 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11766 "='foo/Second'>&First;"; 11767 const char *text2 = "</" 11768 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11769 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11770 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11771 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11772 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11773 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11774 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11775 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11776 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11777 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11778 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11779 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11780 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11781 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11782 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11783 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11784 ":doc>"; 11785 ExtOption options[] = { 11786 { XCS("foo/First"), "Hello world" }, 11787 { NULL, NULL } 11788 }; 11789 int i; 11790 const int max_realloc_count = 20; 11791 11792 for (i = 0; i < max_realloc_count; i++) { 11793 reallocation_count = i; 11794 XML_SetUserData(parser, options); 11795 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 11796 XML_SetExternalEntityRefHandler(parser, external_entity_optioner); 11797 if (_XML_Parse_SINGLE_BYTES(parser, text1, (int)strlen(text1), 11798 XML_FALSE) != XML_STATUS_ERROR && 11799 _XML_Parse_SINGLE_BYTES(parser, text2, (int)strlen(text2), 11800 XML_TRUE) != XML_STATUS_ERROR) 11801 break; 11802 /* See comment in test_nsalloc_xmlns() */ 11803 nsalloc_teardown(); 11804 nsalloc_setup(); 11805 } 11806 if (i == 0) 11807 fail("Parsing worked despite failing reallocations"); 11808 else if (i == max_realloc_count) 11809 fail("Parsing failed even at max reallocation count"); 11810 } 11811 END_TEST 11812 11813 START_TEST(test_nsalloc_long_default_in_ext) 11814 { 11815 const char *text = 11816 "<!DOCTYPE doc [\n" 11817 " <!ATTLIST e a1 CDATA '" 11818 /* 64 characters per line */ 11819 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11820 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11821 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11822 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11823 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11824 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11825 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11826 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11827 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11828 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11829 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11830 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11831 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11832 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11833 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11834 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 11835 "'>\n" 11836 " <!ENTITY x SYSTEM 'foo'>\n" 11837 "]>\n" 11838 "<doc>&x;</doc>"; 11839 ExtOption options[] = { 11840 { XCS("foo"), "<e/>"}, 11841 { NULL, NULL } 11842 }; 11843 int i; 11844 const int max_alloc_count = 50; 11845 11846 for (i = 0; i < max_alloc_count; i++) { 11847 allocation_count = i; 11848 XML_SetUserData(parser, options); 11849 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 11850 XML_SetExternalEntityRefHandler(parser, external_entity_optioner); 11851 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 11852 XML_TRUE) != XML_STATUS_ERROR) 11853 break; 11854 11855 /* See comment in test_nsalloc_xmlns() */ 11856 nsalloc_teardown(); 11857 nsalloc_setup(); 11858 } 11859 if (i == 0) 11860 fail("Parsing worked despite failing allocations"); 11861 else if (i == max_alloc_count) 11862 fail("Parsing failed even at max allocation count"); 11863 } 11864 END_TEST 11865 11866 START_TEST(test_nsalloc_long_systemid_in_ext) 11867 { 11868 const char *text = 11869 "<!DOCTYPE doc SYSTEM 'foo' [\n" 11870 " <!ENTITY en SYSTEM '" 11871 /* 64 characters per line */ 11872 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11873 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11874 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11875 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11876 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11877 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11878 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11879 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11880 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11881 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11882 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11883 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11884 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11885 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11886 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11887 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 11888 "'>\n" 11889 "]>\n" 11890 "<doc>&en;</doc>"; 11891 ExtOption options[] = { 11892 { XCS("foo"), "<!ELEMENT e EMPTY>" }, 11893 { 11894 XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/") 11895 XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/") 11896 XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/") 11897 XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/") 11898 XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/") 11899 XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/") 11900 XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/") 11901 XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/") 11902 XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/") 11903 XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/") 11904 XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/") 11905 XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/") 11906 XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/") 11907 XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/") 11908 XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/") 11909 XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"), 11910 "<e/>" 11911 }, 11912 { NULL, NULL } 11913 }; 11914 int i; 11915 const int max_alloc_count = 55; 11916 11917 for (i = 0; i < max_alloc_count; i++) { 11918 allocation_count = i; 11919 XML_SetUserData(parser, options); 11920 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 11921 XML_SetExternalEntityRefHandler(parser, external_entity_optioner); 11922 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 11923 XML_TRUE) != XML_STATUS_ERROR) 11924 break; 11925 11926 /* See comment in test_nsalloc_xmlns() */ 11927 nsalloc_teardown(); 11928 nsalloc_setup(); 11929 } 11930 if (i == 0) 11931 fail("Parsing worked despite failing allocations"); 11932 else if (i == max_alloc_count) 11933 fail("Parsing failed even at max allocation count"); 11934 } 11935 END_TEST 11936 11937 /* Test the effects of allocation failure on parsing an element in a 11938 * namespace. Based on test_nsalloc_long_context. 11939 */ 11940 START_TEST(test_nsalloc_prefixed_element) 11941 { 11942 const char *text = 11943 "<!DOCTYPE pfx:element SYSTEM 'foo' [\n" 11944 " <!ATTLIST pfx:element baz ID #REQUIRED>\n" 11945 " <!ENTITY en SYSTEM 'bar'>\n" 11946 "]>\n" 11947 "<pfx:element xmlns:pfx='http://example.org/' baz='2'>\n" 11948 "&en;" 11949 "</pfx:element>"; 11950 ExtOption options[] = { 11951 { XCS("foo"), "<!ELEMENT e EMPTY>" }, 11952 { XCS("bar"), "<e/>" }, 11953 { NULL, NULL } 11954 }; 11955 int i; 11956 const int max_alloc_count = 70; 11957 11958 for (i = 0; i < max_alloc_count; i++) { 11959 allocation_count = i; 11960 XML_SetUserData(parser, options); 11961 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 11962 XML_SetExternalEntityRefHandler(parser, external_entity_optioner); 11963 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), 11964 XML_TRUE) != XML_STATUS_ERROR) 11965 break; 11966 11967 /* See comment in test_nsalloc_xmlns() */ 11968 nsalloc_teardown(); 11969 nsalloc_setup(); 11970 } 11971 if (i == 0) 11972 fail("Success despite failing allocator"); 11973 else if (i == max_alloc_count) 11974 fail("Failed even at full allocation count"); 11975 } 11976 END_TEST 11977 11978 static Suite * 11979 make_suite(void) 11980 { 11981 Suite *s = suite_create("basic"); 11982 TCase *tc_basic = tcase_create("basic tests"); 11983 TCase *tc_namespace = tcase_create("XML namespaces"); 11984 TCase *tc_misc = tcase_create("miscellaneous tests"); 11985 TCase *tc_alloc = tcase_create("allocation tests"); 11986 TCase *tc_nsalloc = tcase_create("namespace allocation tests"); 11987 11988 suite_add_tcase(s, tc_basic); 11989 tcase_add_checked_fixture(tc_basic, basic_setup, basic_teardown); 11990 tcase_add_test(tc_basic, test_nul_byte); 11991 tcase_add_test(tc_basic, test_u0000_char); 11992 tcase_add_test(tc_basic, test_siphash_self); 11993 tcase_add_test(tc_basic, test_siphash_spec); 11994 tcase_add_test(tc_basic, test_bom_utf8); 11995 tcase_add_test(tc_basic, test_bom_utf16_be); 11996 tcase_add_test(tc_basic, test_bom_utf16_le); 11997 tcase_add_test(tc_basic, test_nobom_utf16_le); 11998 tcase_add_test(tc_basic, test_illegal_utf8); 11999 tcase_add_test(tc_basic, test_utf8_auto_align); 12000 tcase_add_test(tc_basic, test_utf16); 12001 tcase_add_test(tc_basic, test_utf16_le_epilog_newline); 12002 tcase_add_test(tc_basic, test_not_utf16); 12003 tcase_add_test(tc_basic, test_bad_encoding); 12004 tcase_add_test(tc_basic, test_latin1_umlauts); 12005 tcase_add_test(tc_basic, test_long_utf8_character); 12006 tcase_add_test(tc_basic, test_long_latin1_attribute); 12007 tcase_add_test(tc_basic, test_long_ascii_attribute); 12008 /* Regression test for SF bug #491986. */ 12009 tcase_add_test(tc_basic, test_danish_latin1); 12010 /* Regression test for SF bug #514281. */ 12011 tcase_add_test(tc_basic, test_french_charref_hexidecimal); 12012 tcase_add_test(tc_basic, test_french_charref_decimal); 12013 tcase_add_test(tc_basic, test_french_latin1); 12014 tcase_add_test(tc_basic, test_french_utf8); 12015 tcase_add_test(tc_basic, test_utf8_false_rejection); 12016 tcase_add_test(tc_basic, test_line_number_after_parse); 12017 tcase_add_test(tc_basic, test_column_number_after_parse); 12018 tcase_add_test(tc_basic, test_line_and_column_numbers_inside_handlers); 12019 tcase_add_test(tc_basic, test_line_number_after_error); 12020 tcase_add_test(tc_basic, test_column_number_after_error); 12021 tcase_add_test(tc_basic, test_really_long_lines); 12022 tcase_add_test(tc_basic, test_really_long_encoded_lines); 12023 tcase_add_test(tc_basic, test_end_element_events); 12024 tcase_add_test(tc_basic, test_attr_whitespace_normalization); 12025 tcase_add_test(tc_basic, test_xmldecl_misplaced); 12026 tcase_add_test(tc_basic, test_xmldecl_invalid); 12027 tcase_add_test(tc_basic, test_xmldecl_missing_attr); 12028 tcase_add_test(tc_basic, test_xmldecl_missing_value); 12029 tcase_add_test(tc_basic, test_unknown_encoding_internal_entity); 12030 tcase_add_test(tc_basic, test_unrecognised_encoding_internal_entity); 12031 tcase_add_test(tc_basic, 12032 test_wfc_undeclared_entity_unread_external_subset); 12033 tcase_add_test(tc_basic, test_wfc_undeclared_entity_no_external_subset); 12034 tcase_add_test(tc_basic, test_wfc_undeclared_entity_standalone); 12035 tcase_add_test(tc_basic, test_wfc_undeclared_entity_with_external_subset); 12036 tcase_add_test(tc_basic, test_not_standalone_handler_reject); 12037 tcase_add_test(tc_basic, test_not_standalone_handler_accept); 12038 tcase_add_test(tc_basic, 12039 test_wfc_undeclared_entity_with_external_subset_standalone); 12040 tcase_add_test(tc_basic, 12041 test_entity_with_external_subset_unless_standalone); 12042 tcase_add_test(tc_basic, test_wfc_no_recursive_entity_refs); 12043 tcase_add_test(tc_basic, test_ext_entity_set_encoding); 12044 tcase_add_test(tc_basic, test_ext_entity_no_handler); 12045 tcase_add_test(tc_basic, test_ext_entity_set_bom); 12046 tcase_add_test(tc_basic, test_ext_entity_bad_encoding); 12047 tcase_add_test(tc_basic, test_ext_entity_bad_encoding_2); 12048 tcase_add_test(tc_basic, test_ext_entity_invalid_parse); 12049 tcase_add_test(tc_basic, test_ext_entity_invalid_suspended_parse); 12050 tcase_add_test(tc_basic, test_dtd_default_handling); 12051 tcase_add_test(tc_basic, test_dtd_attr_handling); 12052 tcase_add_test(tc_basic, test_empty_ns_without_namespaces); 12053 tcase_add_test(tc_basic, test_ns_in_attribute_default_without_namespaces); 12054 tcase_add_test(tc_basic, test_stop_parser_between_char_data_calls); 12055 tcase_add_test(tc_basic, test_suspend_parser_between_char_data_calls); 12056 tcase_add_test(tc_basic, test_repeated_stop_parser_between_char_data_calls); 12057 tcase_add_test(tc_basic, test_good_cdata_ascii); 12058 tcase_add_test(tc_basic, test_good_cdata_utf16); 12059 tcase_add_test(tc_basic, test_good_cdata_utf16_le); 12060 tcase_add_test(tc_basic, test_long_cdata_utf16); 12061 tcase_add_test(tc_basic, test_multichar_cdata_utf16); 12062 tcase_add_test(tc_basic, test_utf16_bad_surrogate_pair); 12063 tcase_add_test(tc_basic, test_bad_cdata); 12064 tcase_add_test(tc_basic, test_bad_cdata_utf16); 12065 tcase_add_test(tc_basic, test_stop_parser_between_cdata_calls); 12066 tcase_add_test(tc_basic, test_suspend_parser_between_cdata_calls); 12067 tcase_add_test(tc_basic, test_memory_allocation); 12068 tcase_add_test(tc_basic, test_default_current); 12069 tcase_add_test(tc_basic, test_dtd_elements); 12070 tcase_add_test(tc_basic, test_set_foreign_dtd); 12071 tcase_add_test(tc_basic, test_foreign_dtd_not_standalone); 12072 tcase_add_test(tc_basic, test_invalid_foreign_dtd); 12073 tcase_add_test(tc_basic, test_foreign_dtd_with_doctype); 12074 tcase_add_test(tc_basic, test_foreign_dtd_without_external_subset); 12075 tcase_add_test(tc_basic, test_empty_foreign_dtd); 12076 tcase_add_test(tc_basic, test_set_base); 12077 tcase_add_test(tc_basic, test_attributes); 12078 tcase_add_test(tc_basic, test_reset_in_entity); 12079 tcase_add_test(tc_basic, test_resume_invalid_parse); 12080 tcase_add_test(tc_basic, test_resume_resuspended); 12081 tcase_add_test(tc_basic, test_cdata_default); 12082 tcase_add_test(tc_basic, test_subordinate_reset); 12083 tcase_add_test(tc_basic, test_subordinate_suspend); 12084 tcase_add_test(tc_basic, test_subordinate_xdecl_suspend); 12085 tcase_add_test(tc_basic, test_subordinate_xdecl_abort); 12086 tcase_add_test(tc_basic, test_explicit_encoding); 12087 tcase_add_test(tc_basic, test_trailing_cr); 12088 tcase_add_test(tc_basic, test_ext_entity_trailing_cr); 12089 tcase_add_test(tc_basic, test_trailing_rsqb); 12090 tcase_add_test(tc_basic, test_ext_entity_trailing_rsqb); 12091 tcase_add_test(tc_basic, test_ext_entity_good_cdata); 12092 tcase_add_test(tc_basic, test_user_parameters); 12093 tcase_add_test(tc_basic, test_ext_entity_ref_parameter); 12094 tcase_add_test(tc_basic, test_empty_parse); 12095 tcase_add_test(tc_basic, test_get_buffer_1); 12096 tcase_add_test(tc_basic, test_get_buffer_2); 12097 tcase_add_test(tc_basic, test_byte_info_at_end); 12098 tcase_add_test(tc_basic, test_byte_info_at_error); 12099 tcase_add_test(tc_basic, test_byte_info_at_cdata); 12100 tcase_add_test(tc_basic, test_predefined_entities); 12101 tcase_add_test(tc_basic, test_invalid_tag_in_dtd); 12102 tcase_add_test(tc_basic, test_not_predefined_entities); 12103 tcase_add_test(tc_basic, test_ignore_section); 12104 tcase_add_test(tc_basic, test_ignore_section_utf16); 12105 tcase_add_test(tc_basic, test_ignore_section_utf16_be); 12106 tcase_add_test(tc_basic, test_bad_ignore_section); 12107 tcase_add_test(tc_basic, test_external_entity_values); 12108 tcase_add_test(tc_basic, test_ext_entity_not_standalone); 12109 tcase_add_test(tc_basic, test_ext_entity_value_abort); 12110 tcase_add_test(tc_basic, test_bad_public_doctype); 12111 tcase_add_test(tc_basic, test_attribute_enum_value); 12112 tcase_add_test(tc_basic, test_predefined_entity_redefinition); 12113 tcase_add_test(tc_basic, test_dtd_stop_processing); 12114 tcase_add_test(tc_basic, test_public_notation_no_sysid); 12115 tcase_add_test(tc_basic, test_nested_groups); 12116 tcase_add_test(tc_basic, test_group_choice); 12117 tcase_add_test(tc_basic, test_standalone_parameter_entity); 12118 tcase_add_test(tc_basic, test_skipped_parameter_entity); 12119 tcase_add_test(tc_basic, test_recursive_external_parameter_entity); 12120 tcase_add_test(tc_basic, test_undefined_ext_entity_in_external_dtd); 12121 tcase_add_test(tc_basic, test_suspend_xdecl); 12122 tcase_add_test(tc_basic, test_abort_epilog); 12123 tcase_add_test(tc_basic, test_abort_epilog_2); 12124 tcase_add_test(tc_basic, test_suspend_epilog); 12125 tcase_add_test(tc_basic, test_suspend_in_sole_empty_tag); 12126 tcase_add_test(tc_basic, test_unfinished_epilog); 12127 tcase_add_test(tc_basic, test_partial_char_in_epilog); 12128 tcase_add_test(tc_basic, test_hash_collision); 12129 tcase_add_test(tc_basic, test_suspend_resume_internal_entity); 12130 tcase_add_test(tc_basic, test_resume_entity_with_syntax_error); 12131 tcase_add_test(tc_basic, test_suspend_resume_parameter_entity); 12132 tcase_add_test(tc_basic, test_restart_on_error); 12133 tcase_add_test(tc_basic, test_reject_lt_in_attribute_value); 12134 tcase_add_test(tc_basic, test_reject_unfinished_param_in_att_value); 12135 tcase_add_test(tc_basic, test_trailing_cr_in_att_value); 12136 tcase_add_test(tc_basic, test_standalone_internal_entity); 12137 tcase_add_test(tc_basic, test_skipped_external_entity); 12138 tcase_add_test(tc_basic, test_skipped_null_loaded_ext_entity); 12139 tcase_add_test(tc_basic, test_skipped_unloaded_ext_entity); 12140 tcase_add_test(tc_basic, test_param_entity_with_trailing_cr); 12141 tcase_add_test(tc_basic, test_invalid_character_entity); 12142 tcase_add_test(tc_basic, test_invalid_character_entity_2); 12143 tcase_add_test(tc_basic, test_invalid_character_entity_3); 12144 tcase_add_test(tc_basic, test_invalid_character_entity_4); 12145 tcase_add_test(tc_basic, test_pi_handled_in_default); 12146 tcase_add_test(tc_basic, test_comment_handled_in_default); 12147 tcase_add_test(tc_basic, test_pi_yml); 12148 tcase_add_test(tc_basic, test_pi_xnl); 12149 tcase_add_test(tc_basic, test_pi_xmm); 12150 tcase_add_test(tc_basic, test_utf16_pi); 12151 tcase_add_test(tc_basic, test_utf16_be_pi); 12152 tcase_add_test(tc_basic, test_utf16_be_comment); 12153 tcase_add_test(tc_basic, test_utf16_le_comment); 12154 tcase_add_test(tc_basic, test_missing_encoding_conversion_fn); 12155 tcase_add_test(tc_basic, test_failing_encoding_conversion_fn); 12156 tcase_add_test(tc_basic, test_unknown_encoding_success); 12157 tcase_add_test(tc_basic, test_unknown_encoding_bad_name); 12158 tcase_add_test(tc_basic, test_unknown_encoding_bad_name_2); 12159 tcase_add_test(tc_basic, test_unknown_encoding_long_name_1); 12160 tcase_add_test(tc_basic, test_unknown_encoding_long_name_2); 12161 tcase_add_test(tc_basic, test_invalid_unknown_encoding); 12162 tcase_add_test(tc_basic, test_unknown_ascii_encoding_ok); 12163 tcase_add_test(tc_basic, test_unknown_ascii_encoding_fail); 12164 tcase_add_test(tc_basic, test_unknown_encoding_invalid_length); 12165 tcase_add_test(tc_basic, test_unknown_encoding_invalid_topbit); 12166 tcase_add_test(tc_basic, test_unknown_encoding_invalid_surrogate); 12167 tcase_add_test(tc_basic, test_unknown_encoding_invalid_high); 12168 tcase_add_test(tc_basic, test_unknown_encoding_invalid_attr_value); 12169 tcase_add_test(tc_basic, test_ext_entity_latin1_utf16le_bom); 12170 tcase_add_test(tc_basic, test_ext_entity_latin1_utf16be_bom); 12171 tcase_add_test(tc_basic, test_ext_entity_latin1_utf16le_bom2); 12172 tcase_add_test(tc_basic, test_ext_entity_latin1_utf16be_bom2); 12173 tcase_add_test(tc_basic, test_ext_entity_utf16_be); 12174 tcase_add_test(tc_basic, test_ext_entity_utf16_le); 12175 tcase_add_test(tc_basic, test_ext_entity_utf16_unknown); 12176 tcase_add_test(tc_basic, test_ext_entity_utf8_non_bom); 12177 tcase_add_test(tc_basic, test_utf8_in_cdata_section); 12178 tcase_add_test(tc_basic, test_utf8_in_cdata_section_2); 12179 tcase_add_test(tc_basic, test_trailing_spaces_in_elements); 12180 tcase_add_test(tc_basic, test_utf16_attribute); 12181 tcase_add_test(tc_basic, test_utf16_second_attr); 12182 tcase_add_test(tc_basic, test_attr_after_solidus); 12183 tcase_add_test(tc_basic, test_utf16_pe); 12184 tcase_add_test(tc_basic, test_bad_attr_desc_keyword); 12185 tcase_add_test(tc_basic, test_bad_attr_desc_keyword_utf16); 12186 tcase_add_test(tc_basic, test_bad_doctype); 12187 tcase_add_test(tc_basic, test_bad_doctype_utf16); 12188 tcase_add_test(tc_basic, test_bad_doctype_plus); 12189 tcase_add_test(tc_basic, test_bad_doctype_star); 12190 tcase_add_test(tc_basic, test_bad_doctype_query); 12191 tcase_add_test(tc_basic, test_unknown_encoding_bad_ignore); 12192 tcase_add_test(tc_basic, test_entity_in_utf16_be_attr); 12193 tcase_add_test(tc_basic, test_entity_in_utf16_le_attr); 12194 tcase_add_test(tc_basic, test_entity_public_utf16_be); 12195 tcase_add_test(tc_basic, test_entity_public_utf16_le); 12196 tcase_add_test(tc_basic, test_short_doctype); 12197 tcase_add_test(tc_basic, test_short_doctype_2); 12198 tcase_add_test(tc_basic, test_short_doctype_3); 12199 tcase_add_test(tc_basic, test_long_doctype); 12200 tcase_add_test(tc_basic, test_bad_entity); 12201 tcase_add_test(tc_basic, test_bad_entity_2); 12202 tcase_add_test(tc_basic, test_bad_entity_3); 12203 tcase_add_test(tc_basic, test_bad_entity_4); 12204 tcase_add_test(tc_basic, test_bad_notation); 12205 tcase_add_test(tc_basic, test_default_doctype_handler); 12206 tcase_add_test(tc_basic, test_empty_element_abort); 12207 12208 suite_add_tcase(s, tc_namespace); 12209 tcase_add_checked_fixture(tc_namespace, 12210 namespace_setup, namespace_teardown); 12211 tcase_add_test(tc_namespace, test_return_ns_triplet); 12212 tcase_add_test(tc_namespace, test_ns_tagname_overwrite); 12213 tcase_add_test(tc_namespace, test_ns_tagname_overwrite_triplet); 12214 tcase_add_test(tc_namespace, test_start_ns_clears_start_element); 12215 tcase_add_test(tc_namespace, test_default_ns_from_ext_subset_and_ext_ge); 12216 tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_1); 12217 tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_2); 12218 tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_3); 12219 tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_4); 12220 tcase_add_test(tc_namespace, test_ns_unbound_prefix); 12221 tcase_add_test(tc_namespace, test_ns_default_with_empty_uri); 12222 tcase_add_test(tc_namespace, test_ns_duplicate_attrs_diff_prefixes); 12223 tcase_add_test(tc_namespace, test_ns_duplicate_hashes); 12224 tcase_add_test(tc_namespace, test_ns_unbound_prefix_on_attribute); 12225 tcase_add_test(tc_namespace, test_ns_unbound_prefix_on_element); 12226 tcase_add_test(tc_namespace, test_ns_parser_reset); 12227 tcase_add_test(tc_namespace, test_ns_long_element); 12228 tcase_add_test(tc_namespace, test_ns_mixed_prefix_atts); 12229 tcase_add_test(tc_namespace, test_ns_extend_uri_buffer); 12230 tcase_add_test(tc_namespace, test_ns_reserved_attributes); 12231 tcase_add_test(tc_namespace, test_ns_reserved_attributes_2); 12232 tcase_add_test(tc_namespace, test_ns_extremely_long_prefix); 12233 tcase_add_test(tc_namespace, test_ns_unknown_encoding_success); 12234 tcase_add_test(tc_namespace, test_ns_double_colon); 12235 tcase_add_test(tc_namespace, test_ns_double_colon_element); 12236 tcase_add_test(tc_namespace, test_ns_bad_attr_leafname); 12237 tcase_add_test(tc_namespace, test_ns_bad_element_leafname); 12238 tcase_add_test(tc_namespace, test_ns_utf16_leafname); 12239 tcase_add_test(tc_namespace, test_ns_utf16_element_leafname); 12240 tcase_add_test(tc_namespace, test_ns_utf16_doctype); 12241 tcase_add_test(tc_namespace, test_ns_invalid_doctype); 12242 tcase_add_test(tc_namespace, test_ns_double_colon_doctype); 12243 12244 suite_add_tcase(s, tc_misc); 12245 tcase_add_checked_fixture(tc_misc, NULL, basic_teardown); 12246 tcase_add_test(tc_misc, test_misc_alloc_create_parser); 12247 tcase_add_test(tc_misc, test_misc_alloc_create_parser_with_encoding); 12248 tcase_add_test(tc_misc, test_misc_null_parser); 12249 tcase_add_test(tc_misc, test_misc_error_string); 12250 tcase_add_test(tc_misc, test_misc_version); 12251 tcase_add_test(tc_misc, test_misc_features); 12252 tcase_add_test(tc_misc, test_misc_attribute_leak); 12253 tcase_add_test(tc_misc, test_misc_utf16le); 12254 12255 suite_add_tcase(s, tc_alloc); 12256 tcase_add_checked_fixture(tc_alloc, alloc_setup, alloc_teardown); 12257 tcase_add_test(tc_alloc, test_alloc_parse_xdecl); 12258 tcase_add_test(tc_alloc, test_alloc_parse_xdecl_2); 12259 tcase_add_test(tc_alloc, test_alloc_parse_pi); 12260 tcase_add_test(tc_alloc, test_alloc_parse_pi_2); 12261 tcase_add_test(tc_alloc, test_alloc_parse_pi_3); 12262 tcase_add_test(tc_alloc, test_alloc_parse_comment); 12263 tcase_add_test(tc_alloc, test_alloc_parse_comment_2); 12264 tcase_add_test(tc_alloc, test_alloc_create_external_parser); 12265 tcase_add_test(tc_alloc, test_alloc_run_external_parser); 12266 tcase_add_test(tc_alloc, test_alloc_dtd_copy_default_atts); 12267 tcase_add_test(tc_alloc, test_alloc_external_entity); 12268 tcase_add_test(tc_alloc, test_alloc_ext_entity_set_encoding); 12269 tcase_add_test(tc_alloc, test_alloc_internal_entity); 12270 tcase_add_test(tc_alloc, test_alloc_dtd_default_handling); 12271 tcase_add_test(tc_alloc, test_alloc_explicit_encoding); 12272 tcase_add_test(tc_alloc, test_alloc_set_base); 12273 tcase_add_test(tc_alloc, test_alloc_realloc_buffer); 12274 tcase_add_test(tc_alloc, test_alloc_ext_entity_realloc_buffer); 12275 tcase_add_test(tc_alloc, test_alloc_realloc_many_attributes); 12276 tcase_add_test(tc_alloc, test_alloc_public_entity_value); 12277 tcase_add_test(tc_alloc, test_alloc_realloc_subst_public_entity_value); 12278 tcase_add_test(tc_alloc, test_alloc_parse_public_doctype); 12279 tcase_add_test(tc_alloc, test_alloc_parse_public_doctype_long_name); 12280 tcase_add_test(tc_alloc, test_alloc_set_foreign_dtd); 12281 tcase_add_test(tc_alloc, test_alloc_attribute_enum_value); 12282 tcase_add_test(tc_alloc, test_alloc_realloc_attribute_enum_value); 12283 tcase_add_test(tc_alloc, test_alloc_realloc_implied_attribute); 12284 tcase_add_test(tc_alloc, test_alloc_realloc_default_attribute); 12285 tcase_add_test(tc_alloc, test_alloc_notation); 12286 tcase_add_test(tc_alloc, test_alloc_public_notation); 12287 tcase_add_test(tc_alloc, test_alloc_system_notation); 12288 tcase_add_test(tc_alloc, test_alloc_nested_groups); 12289 tcase_add_test(tc_alloc, test_alloc_realloc_nested_groups); 12290 tcase_add_test(tc_alloc, test_alloc_large_group); 12291 tcase_add_test(tc_alloc, test_alloc_realloc_group_choice); 12292 tcase_add_test(tc_alloc, test_alloc_pi_in_epilog); 12293 tcase_add_test(tc_alloc, test_alloc_comment_in_epilog); 12294 tcase_add_test(tc_alloc, test_alloc_realloc_long_attribute_value); 12295 tcase_add_test(tc_alloc, test_alloc_attribute_whitespace); 12296 tcase_add_test(tc_alloc, test_alloc_attribute_predefined_entity); 12297 tcase_add_test(tc_alloc, test_alloc_long_attr_default_with_char_ref); 12298 tcase_add_test(tc_alloc, test_alloc_long_attr_value); 12299 tcase_add_test(tc_alloc, test_alloc_nested_entities); 12300 tcase_add_test(tc_alloc, test_alloc_realloc_param_entity_newline); 12301 tcase_add_test(tc_alloc, test_alloc_realloc_ce_extends_pe); 12302 tcase_add_test(tc_alloc, test_alloc_realloc_attributes); 12303 tcase_add_test(tc_alloc, test_alloc_long_doc_name); 12304 tcase_add_test(tc_alloc, test_alloc_long_base); 12305 tcase_add_test(tc_alloc, test_alloc_long_public_id); 12306 tcase_add_test(tc_alloc, test_alloc_long_entity_value); 12307 tcase_add_test(tc_alloc, test_alloc_long_notation); 12308 12309 suite_add_tcase(s, tc_nsalloc); 12310 tcase_add_checked_fixture(tc_nsalloc, nsalloc_setup, nsalloc_teardown); 12311 tcase_add_test(tc_nsalloc, test_nsalloc_xmlns); 12312 tcase_add_test(tc_nsalloc, test_nsalloc_parse_buffer); 12313 tcase_add_test(tc_nsalloc, test_nsalloc_long_prefix); 12314 tcase_add_test(tc_nsalloc, test_nsalloc_long_uri); 12315 tcase_add_test(tc_nsalloc, test_nsalloc_long_attr); 12316 tcase_add_test(tc_nsalloc, test_nsalloc_long_attr_prefix); 12317 tcase_add_test(tc_nsalloc, test_nsalloc_realloc_attributes); 12318 tcase_add_test(tc_nsalloc, test_nsalloc_long_element); 12319 tcase_add_test(tc_nsalloc, test_nsalloc_realloc_binding_uri); 12320 tcase_add_test(tc_nsalloc, test_nsalloc_realloc_long_prefix); 12321 tcase_add_test(tc_nsalloc, test_nsalloc_realloc_longer_prefix); 12322 tcase_add_test(tc_nsalloc, test_nsalloc_long_namespace); 12323 tcase_add_test(tc_nsalloc, test_nsalloc_less_long_namespace); 12324 tcase_add_test(tc_nsalloc, test_nsalloc_long_context); 12325 tcase_add_test(tc_nsalloc, test_nsalloc_realloc_long_context); 12326 tcase_add_test(tc_nsalloc, test_nsalloc_realloc_long_context_2); 12327 tcase_add_test(tc_nsalloc, test_nsalloc_realloc_long_context_3); 12328 tcase_add_test(tc_nsalloc, test_nsalloc_realloc_long_context_4); 12329 tcase_add_test(tc_nsalloc, test_nsalloc_realloc_long_context_5); 12330 tcase_add_test(tc_nsalloc, test_nsalloc_realloc_long_context_6); 12331 tcase_add_test(tc_nsalloc, test_nsalloc_realloc_long_context_7); 12332 tcase_add_test(tc_nsalloc, test_nsalloc_realloc_long_ge_name); 12333 tcase_add_test(tc_nsalloc, test_nsalloc_realloc_long_context_in_dtd); 12334 tcase_add_test(tc_nsalloc, test_nsalloc_long_default_in_ext); 12335 tcase_add_test(tc_nsalloc, test_nsalloc_long_systemid_in_ext); 12336 tcase_add_test(tc_nsalloc, test_nsalloc_prefixed_element); 12337 12338 return s; 12339 } 12340 12341 12342 int 12343 main(int argc, char *argv[]) 12344 { 12345 int i, nf; 12346 int verbosity = CK_NORMAL; 12347 Suite *s = make_suite(); 12348 SRunner *sr = srunner_create(s); 12349 12350 /* run the tests for internal helper functions */ 12351 testhelper_is_whitespace_normalized(); 12352 12353 for (i = 1; i < argc; ++i) { 12354 char *opt = argv[i]; 12355 if (strcmp(opt, "-v") == 0 || strcmp(opt, "--verbose") == 0) 12356 verbosity = CK_VERBOSE; 12357 else if (strcmp(opt, "-q") == 0 || strcmp(opt, "--quiet") == 0) 12358 verbosity = CK_SILENT; 12359 else { 12360 fprintf(stderr, "runtests: unknown option '%s'\n", opt); 12361 return 2; 12362 } 12363 } 12364 if (verbosity != CK_SILENT) 12365 printf("Expat version: %" XML_FMT_STR "\n", XML_ExpatVersion()); 12366 srunner_run_all(sr, verbosity); 12367 nf = srunner_ntests_failed(sr); 12368 srunner_free(sr); 12369 12370 return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE; 12371 } 12372