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