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