1 /* Tests in the "allocation" test case for the Expat test suite 2 __ __ _ 3 ___\ \/ /_ __ __ _| |_ 4 / _ \\ /| '_ \ / _` | __| 5 | __// \| |_) | (_| | |_ 6 \___/_/\_\ .__/ \__,_|\__| 7 |_| XML parser 8 9 Copyright (c) 2001-2006 Fred L. Drake, Jr. <fdrake@users.sourceforge.net> 10 Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net> 11 Copyright (c) 2005-2007 Steven Solie <steven@solie.ca> 12 Copyright (c) 2005-2012 Karl Waclawek <karl@waclawek.net> 13 Copyright (c) 2016-2026 Sebastian Pipping <sebastian@pipping.org> 14 Copyright (c) 2017-2022 Rhodri James <rhodri@wildebeest.org.uk> 15 Copyright (c) 2017 Joe Orton <jorton@redhat.com> 16 Copyright (c) 2017 José Gutiérrez de la Concha <jose@zeroc.com> 17 Copyright (c) 2018 Marco Maggi <marco.maggi-ipsu@poste.it> 18 Copyright (c) 2019 David Loffredo <loffredo@steptools.com> 19 Copyright (c) 2020 Tim Gates <tim.gates@iress.com> 20 Copyright (c) 2021 Donghee Na <donghee.na@python.org> 21 Copyright (c) 2023 Sony Corporation / Snild Dolkow <snild@sony.com> 22 Copyright (c) 2025 Berkay Eren Ürün <berkay.ueruen@siemens.com> 23 Copyright (c) 2026 Matthew Fernandez <matthew.fernandez@gmail.com> 24 Copyright (c) 2026 Filippo Tedeschi <filippotedeschi98@gmail.com> 25 Licensed under the MIT license: 26 27 Permission is hereby granted, free of charge, to any person obtaining 28 a copy of this software and associated documentation files (the 29 "Software"), to deal in the Software without restriction, including 30 without limitation the rights to use, copy, modify, merge, publish, 31 distribute, sublicense, and/or sell copies of the Software, and to permit 32 persons to whom the Software is furnished to do so, subject to the 33 following conditions: 34 35 The above copyright notice and this permission notice shall be included 36 in all copies or substantial portions of the Software. 37 38 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 39 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 40 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 41 NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 42 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 43 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 44 USE OR OTHER DEALINGS IN THE SOFTWARE. 45 46 SPDX-License-Identifier: MIT 47 */ 48 49 #if defined(NDEBUG) 50 # undef NDEBUG /* because test suite relies on assert(...) at the moment */ 51 #endif 52 53 #include "expat_config.h" 54 55 #include <math.h> /* NAN, INFINITY */ 56 #include <stdbool.h> 57 #include <stdint.h> /* for SIZE_MAX */ 58 #include <string.h> 59 #include <assert.h> 60 61 #include "expat.h" 62 #include "internal.h" 63 #include "common.h" 64 #include "minicheck.h" 65 #include "dummy.h" 66 #include "handlers.h" 67 #include "alloc_tests.h" 68 69 static void 70 alloc_setup(void) { 71 XML_Memory_Handling_Suite memsuite = {duff_allocator, duff_reallocator, free}; 72 73 /* Ensure the parser creation will go through */ 74 g_allocation_count = ALLOC_ALWAYS_SUCCEED; 75 g_reallocation_count = REALLOC_ALWAYS_SUCCEED; 76 g_parser = XML_ParserCreate_MM(NULL, &memsuite, NULL); 77 if (g_parser == NULL) 78 fail("Parser not created"); 79 } 80 81 static void 82 alloc_teardown(void) { 83 basic_teardown(); 84 } 85 86 /* Test the effects of allocation failures on xml declaration processing */ 87 START_TEST(test_alloc_parse_xdecl) { 88 const char *text = "<?xml version='1.0' encoding='utf-8'?>\n" 89 "<doc>Hello, world</doc>"; 90 int i; 91 const int max_alloc_count = 15; 92 93 for (i = 0; i < max_alloc_count; i++) { 94 g_allocation_count = i; 95 XML_SetXmlDeclHandler(g_parser, dummy_xdecl_handler); 96 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 97 != XML_STATUS_ERROR) 98 break; 99 /* Resetting the parser is insufficient, because some memory 100 * allocations are cached within the parser. Instead we use 101 * the teardown and setup routines to ensure that we have the 102 * right sort of parser back in our hands. 103 */ 104 alloc_teardown(); 105 alloc_setup(); 106 } 107 if (i == 0) 108 fail("Parse succeeded despite failing allocator"); 109 if (i == max_alloc_count) 110 fail("Parse failed with max allocations"); 111 } 112 END_TEST 113 114 /* As above, but with an encoding big enough to cause storing the 115 * version information to expand the string pool being used. 116 */ 117 START_TEST(test_alloc_parse_xdecl_2) { 118 const char *text 119 = "<?xml version='1.0' encoding='" 120 /* Each line is 64 characters */ 121 "ThisIsAStupidlyLongEncodingNameIntendedToTriggerPoolGrowth123456" 122 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 123 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 124 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 125 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 126 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 127 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 128 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 129 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 130 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 131 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 132 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 133 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 134 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 135 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 136 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMN" 137 "'?>" 138 "<doc>Hello, world</doc>"; 139 int i; 140 const int max_alloc_count = 20; 141 142 for (i = 0; i < max_alloc_count; i++) { 143 g_allocation_count = i; 144 XML_SetXmlDeclHandler(g_parser, dummy_xdecl_handler); 145 XML_SetUnknownEncodingHandler(g_parser, long_encoding_handler, NULL); 146 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 147 != XML_STATUS_ERROR) 148 break; 149 /* See comment in test_alloc_parse_xdecl() */ 150 alloc_teardown(); 151 alloc_setup(); 152 } 153 if (i == 0) 154 fail("Parse succeeded despite failing allocator"); 155 if (i == max_alloc_count) 156 fail("Parse failed with max allocations"); 157 } 158 END_TEST 159 160 /* Test the effects of allocation failures on a straightforward parse */ 161 START_TEST(test_alloc_parse_pi) { 162 const char *text = "<?xml version='1.0' encoding='utf-8'?>\n" 163 "<?pi unknown?>\n" 164 "<doc>" 165 "Hello, world" 166 "</doc>"; 167 int i; 168 const int max_alloc_count = 15; 169 170 for (i = 0; i < max_alloc_count; i++) { 171 g_allocation_count = i; 172 XML_SetProcessingInstructionHandler(g_parser, dummy_pi_handler); 173 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 174 != XML_STATUS_ERROR) 175 break; 176 /* See comment in test_alloc_parse_xdecl() */ 177 alloc_teardown(); 178 alloc_setup(); 179 } 180 if (i == 0) 181 fail("Parse succeeded despite failing allocator"); 182 if (i == max_alloc_count) 183 fail("Parse failed with max allocations"); 184 } 185 END_TEST 186 187 START_TEST(test_alloc_parse_pi_2) { 188 const char *text = "<?xml version='1.0' encoding='utf-8'?>\n" 189 "<doc>" 190 "Hello, world" 191 "<?pi unknown?>\n" 192 "</doc>"; 193 int i; 194 const int max_alloc_count = 15; 195 196 for (i = 0; i < max_alloc_count; i++) { 197 g_allocation_count = i; 198 XML_SetProcessingInstructionHandler(g_parser, dummy_pi_handler); 199 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 200 != XML_STATUS_ERROR) 201 break; 202 /* See comment in test_alloc_parse_xdecl() */ 203 alloc_teardown(); 204 alloc_setup(); 205 } 206 if (i == 0) 207 fail("Parse succeeded despite failing allocator"); 208 if (i == max_alloc_count) 209 fail("Parse failed with max allocations"); 210 } 211 END_TEST 212 213 START_TEST(test_alloc_parse_pi_3) { 214 const char *text 215 = "<?" 216 /* 64 characters per line */ 217 "This processing instruction should be long enough to ensure that" 218 "it triggers the growth of an internal string pool when the " 219 "allocator fails at a cruicial moment FGHIJKLMNOPABCDEFGHIJKLMNOP" 220 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 221 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 222 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 223 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 224 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 225 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 226 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 227 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 228 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 229 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 230 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 231 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 232 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 233 "Q?><doc/>"; 234 int i; 235 const int max_alloc_count = 20; 236 237 for (i = 0; i < max_alloc_count; i++) { 238 g_allocation_count = i; 239 XML_SetProcessingInstructionHandler(g_parser, dummy_pi_handler); 240 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 241 != XML_STATUS_ERROR) 242 break; 243 /* See comment in test_alloc_parse_xdecl() */ 244 alloc_teardown(); 245 alloc_setup(); 246 } 247 if (i == 0) 248 fail("Parse succeeded despite failing allocator"); 249 if (i == max_alloc_count) 250 fail("Parse failed with max allocations"); 251 } 252 END_TEST 253 254 START_TEST(test_alloc_parse_comment) { 255 const char *text = "<?xml version='1.0' encoding='utf-8'?>\n" 256 "<!-- Test parsing this comment -->" 257 "<doc>Hi</doc>"; 258 int i; 259 const int max_alloc_count = 15; 260 261 for (i = 0; i < max_alloc_count; i++) { 262 g_allocation_count = i; 263 XML_SetCommentHandler(g_parser, dummy_comment_handler); 264 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 265 != XML_STATUS_ERROR) 266 break; 267 /* See comment in test_alloc_parse_xdecl() */ 268 alloc_teardown(); 269 alloc_setup(); 270 } 271 if (i == 0) 272 fail("Parse succeeded despite failing allocator"); 273 if (i == max_alloc_count) 274 fail("Parse failed with max allocations"); 275 } 276 END_TEST 277 278 START_TEST(test_alloc_parse_comment_2) { 279 const char *text = "<?xml version='1.0' encoding='utf-8'?>\n" 280 "<doc>" 281 "Hello, world" 282 "<!-- Parse this comment too -->" 283 "</doc>"; 284 int i; 285 const int max_alloc_count = 15; 286 287 for (i = 0; i < max_alloc_count; i++) { 288 g_allocation_count = i; 289 XML_SetCommentHandler(g_parser, dummy_comment_handler); 290 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 291 != XML_STATUS_ERROR) 292 break; 293 /* See comment in test_alloc_parse_xdecl() */ 294 alloc_teardown(); 295 alloc_setup(); 296 } 297 if (i == 0) 298 fail("Parse succeeded despite failing allocator"); 299 if (i == max_alloc_count) 300 fail("Parse failed with max allocations"); 301 } 302 END_TEST 303 304 /* Test that external parser creation running out of memory is 305 * correctly reported. Based on the external entity test cases. 306 */ 307 START_TEST(test_alloc_create_external_parser) { 308 const char *text = "<?xml version='1.0' encoding='us-ascii'?>\n" 309 "<!DOCTYPE doc SYSTEM 'foo'>\n" 310 "<doc>&entity;</doc>"; 311 char foo_text[] = "<!ELEMENT doc (#PCDATA)*>"; 312 313 XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 314 XML_SetUserData(g_parser, foo_text); 315 XML_SetExternalEntityRefHandler(g_parser, external_entity_duff_loader); 316 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 317 != XML_STATUS_ERROR) { 318 fail("External parser allocator returned success incorrectly"); 319 } 320 } 321 END_TEST 322 323 /* More external parser memory allocation testing */ 324 START_TEST(test_alloc_run_external_parser) { 325 const char *text = "<?xml version='1.0' encoding='us-ascii'?>\n" 326 "<!DOCTYPE doc SYSTEM 'foo'>\n" 327 "<doc>&entity;</doc>"; 328 char foo_text[] = "<!ELEMENT doc (#PCDATA)*>"; 329 unsigned int i; 330 const unsigned int max_alloc_count = 15; 331 332 for (i = 0; i < max_alloc_count; i++) { 333 XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 334 XML_SetUserData(g_parser, foo_text); 335 XML_SetExternalEntityRefHandler(g_parser, external_entity_null_loader); 336 g_allocation_count = (int)i; 337 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 338 != XML_STATUS_ERROR) 339 break; 340 /* See comment in test_alloc_parse_xdecl() */ 341 alloc_teardown(); 342 alloc_setup(); 343 } 344 if (i == 0) 345 fail("Parsing ignored failing allocator"); 346 else if (i == max_alloc_count) 347 fail("Parsing failed with allocation count 10"); 348 } 349 END_TEST 350 351 /* Test that running out of memory in dtdCopy is correctly reported. 352 * Based on test_default_ns_from_ext_subset_and_ext_ge() 353 */ 354 START_TEST(test_alloc_dtd_copy_default_atts) { 355 const char *text = "<?xml version='1.0'?>\n" 356 "<!DOCTYPE doc SYSTEM 'http://example.org/doc.dtd' [\n" 357 " <!ENTITY en SYSTEM 'http://example.org/entity.ent'>\n" 358 "]>\n" 359 "<doc xmlns='http://example.org/ns1'>\n" 360 "&en;\n" 361 "</doc>"; 362 int callno = 0; 363 364 XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 365 XML_SetExternalEntityRefHandler(g_parser, external_entity_dbl_handler); 366 XML_SetUserData(g_parser, &callno); 367 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 368 == XML_STATUS_ERROR) 369 xml_failure(g_parser); 370 } 371 END_TEST 372 373 /* Test more external entity allocation failure paths */ 374 START_TEST(test_alloc_external_entity) { 375 const char *text = "<?xml version='1.0'?>\n" 376 "<!DOCTYPE doc SYSTEM 'http://example.org/doc.dtd' [\n" 377 " <!ENTITY en SYSTEM 'http://example.org/entity.ent'>\n" 378 "]>\n" 379 "<doc xmlns='http://example.org/ns1'>\n" 380 "&en;\n" 381 "</doc>"; 382 int i; 383 const int alloc_test_max_repeats = 50; 384 int callno = 0; 385 386 for (i = 0; i < alloc_test_max_repeats; i++) { 387 g_allocation_count = -1; 388 XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 389 XML_SetExternalEntityRefHandler(g_parser, external_entity_dbl_handler_2); 390 callno = 0; 391 XML_SetUserData(g_parser, &callno); 392 g_allocation_count = i; 393 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 394 == XML_STATUS_OK) 395 break; 396 /* See comment in test_alloc_parse_xdecl() */ 397 alloc_teardown(); 398 alloc_setup(); 399 } 400 g_allocation_count = -1; 401 if (i == 0) 402 fail("External entity parsed despite duff allocator"); 403 if (i == alloc_test_max_repeats) 404 fail("External entity not parsed at max allocation count"); 405 } 406 END_TEST 407 408 /* Test more allocation failure paths */ 409 START_TEST(test_alloc_ext_entity_set_encoding) { 410 const char *text = "<!DOCTYPE doc [\n" 411 " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n" 412 "]>\n" 413 "<doc>&en;</doc>"; 414 int i; 415 const int max_allocation_count = 30; 416 417 for (i = 0; i < max_allocation_count; i++) { 418 XML_SetExternalEntityRefHandler(g_parser, 419 external_entity_alloc_set_encoding); 420 g_allocation_count = i; 421 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 422 == XML_STATUS_OK) 423 break; 424 g_allocation_count = -1; 425 /* See comment in test_alloc_parse_xdecl() */ 426 alloc_teardown(); 427 alloc_setup(); 428 } 429 if (i == 0) 430 fail("Encoding check succeeded despite failing allocator"); 431 if (i == max_allocation_count) 432 fail("Encoding failed at max allocation count"); 433 } 434 END_TEST 435 436 /* Test the effects of allocation failure in internal entities. 437 * Based on test_unknown_encoding_internal_entity 438 */ 439 START_TEST(test_alloc_internal_entity) { 440 const char *text = "<?xml version='1.0' encoding='unsupported-encoding'?>\n" 441 "<!DOCTYPE test [<!ENTITY foo 'bar'>]>\n" 442 "<test a='&foo;'/>"; 443 unsigned int i; 444 const unsigned int max_alloc_count = 20; 445 446 for (i = 0; i < max_alloc_count; i++) { 447 g_allocation_count = (int)i; 448 XML_SetUnknownEncodingHandler(g_parser, unknown_released_encoding_handler, 449 NULL); 450 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 451 != XML_STATUS_ERROR) 452 break; 453 /* See comment in test_alloc_parse_xdecl() */ 454 alloc_teardown(); 455 alloc_setup(); 456 } 457 if (i == 0) 458 fail("Internal entity worked despite failing allocations"); 459 else if (i == max_alloc_count) 460 fail("Internal entity failed at max allocation count"); 461 } 462 END_TEST 463 464 START_TEST(test_alloc_parameter_entity) { 465 const char *text = "<!DOCTYPE foo [" 466 "<!ENTITY % param1 \"<!ENTITY internal 'some_text'>\">" 467 "%param1;" 468 "]> <foo>&internal;content</foo>"; 469 int i; 470 const int alloc_test_max_repeats = 30; 471 472 for (i = 0; i < alloc_test_max_repeats; i++) { 473 g_allocation_count = i; 474 XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 475 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 476 != XML_STATUS_ERROR) 477 break; 478 alloc_teardown(); 479 alloc_setup(); 480 } 481 g_allocation_count = -1; 482 if (i == 0) 483 fail("Parameter entity processed despite duff allocator"); 484 if (i == alloc_test_max_repeats) 485 fail("Parameter entity not processed at max allocation count"); 486 } 487 END_TEST 488 489 /* Test the robustness against allocation failure of element handling 490 * Based on test_dtd_default_handling(). 491 */ 492 START_TEST(test_alloc_dtd_default_handling) { 493 const char *text = "<!DOCTYPE doc [\n" 494 "<!ENTITY e SYSTEM 'http://example.org/e'>\n" 495 "<!NOTATION n SYSTEM 'http://example.org/n'>\n" 496 "<!ENTITY e1 SYSTEM 'http://example.org/e' NDATA n>\n" 497 "<!ELEMENT doc (#PCDATA)>\n" 498 "<!ATTLIST doc a CDATA #IMPLIED>\n" 499 "<?pi in dtd?>\n" 500 "<!--comment in dtd-->\n" 501 "]>\n" 502 "<doc><![CDATA[text in doc]]></doc>"; 503 const XML_Char *expected = XCS("\n\n\n\n\n\n\n\n\n<doc>text in doc</doc>"); 504 CharData storage; 505 int i; 506 const int max_alloc_count = 25; 507 508 for (i = 0; i < max_alloc_count; i++) { 509 g_allocation_count = i; 510 init_dummy_handlers(); 511 XML_SetDefaultHandler(g_parser, accumulate_characters); 512 XML_SetDoctypeDeclHandler(g_parser, dummy_start_doctype_handler, 513 dummy_end_doctype_handler); 514 XML_SetEntityDeclHandler(g_parser, dummy_entity_decl_handler); 515 XML_SetNotationDeclHandler(g_parser, dummy_notation_decl_handler); 516 XML_SetElementDeclHandler(g_parser, dummy_element_decl_handler); 517 XML_SetAttlistDeclHandler(g_parser, dummy_attlist_decl_handler); 518 XML_SetProcessingInstructionHandler(g_parser, dummy_pi_handler); 519 XML_SetCommentHandler(g_parser, dummy_comment_handler); 520 XML_SetCdataSectionHandler(g_parser, dummy_start_cdata_handler, 521 dummy_end_cdata_handler); 522 XML_SetUnparsedEntityDeclHandler(g_parser, 523 dummy_unparsed_entity_decl_handler); 524 CharData_Init(&storage); 525 XML_SetUserData(g_parser, &storage); 526 XML_SetCharacterDataHandler(g_parser, accumulate_characters); 527 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 528 != XML_STATUS_ERROR) 529 break; 530 /* See comment in test_alloc_parse_xdecl() */ 531 alloc_teardown(); 532 alloc_setup(); 533 } 534 if (i == 0) 535 fail("Default DTD parsed despite allocation failures"); 536 if (i == max_alloc_count) 537 fail("Default DTD not parsed with maximum alloc count"); 538 CharData_CheckXMLChars(&storage, expected); 539 if (get_dummy_handler_flags() 540 != (DUMMY_START_DOCTYPE_HANDLER_FLAG | DUMMY_END_DOCTYPE_HANDLER_FLAG 541 | DUMMY_ENTITY_DECL_HANDLER_FLAG | DUMMY_NOTATION_DECL_HANDLER_FLAG 542 | DUMMY_ELEMENT_DECL_HANDLER_FLAG | DUMMY_ATTLIST_DECL_HANDLER_FLAG 543 | DUMMY_COMMENT_HANDLER_FLAG | DUMMY_PI_HANDLER_FLAG 544 | DUMMY_START_CDATA_HANDLER_FLAG | DUMMY_END_CDATA_HANDLER_FLAG 545 | DUMMY_UNPARSED_ENTITY_DECL_HANDLER_FLAG)) 546 fail("Not all handlers were called"); 547 } 548 END_TEST 549 550 /* Test robustness of XML_SetEncoding() with a failing allocator */ 551 START_TEST(test_alloc_explicit_encoding) { 552 int i; 553 const int max_alloc_count = 5; 554 555 for (i = 0; i < max_alloc_count; i++) { 556 g_allocation_count = i; 557 if (XML_SetEncoding(g_parser, XCS("us-ascii")) == XML_STATUS_OK) 558 break; 559 } 560 if (i == 0) 561 fail("Encoding set despite failing allocator"); 562 else if (i == max_alloc_count) 563 fail("Encoding not set at max allocation count"); 564 } 565 END_TEST 566 567 /* Test robustness of XML_ParserReset() with a failing allocator when setting 568 * encoding */ 569 START_TEST(test_alloc_reset_encoding) { 570 int i; 571 const int max_alloc_count = 5; 572 573 for (i = 0; i < max_alloc_count; i++) { 574 g_allocation_count = i; 575 if (XML_ParserReset(g_parser, XCS("us-ascii")) == XML_TRUE) 576 break; 577 } 578 if (i == 0) 579 fail("Reset with encoding succeeded despite failing allocator"); 580 else if (i == max_alloc_count) 581 fail("Reset with encoding failed at max allocation count"); 582 } 583 END_TEST 584 585 /* Test robustness of XML_SetBase against a failing allocator */ 586 START_TEST(test_alloc_set_base) { 587 const XML_Char *new_base = XCS("/local/file/name.xml"); 588 int i; 589 const int max_alloc_count = 5; 590 591 for (i = 0; i < max_alloc_count; i++) { 592 g_allocation_count = i; 593 if (XML_SetBase(g_parser, new_base) == XML_STATUS_OK) 594 break; 595 } 596 if (i == 0) 597 fail("Base set despite failing allocator"); 598 else if (i == max_alloc_count) 599 fail("Base not set with max allocation count"); 600 } 601 END_TEST 602 603 /* Test buffer extension in the face of a duff reallocator */ 604 START_TEST(test_alloc_realloc_buffer) { 605 const char *text = get_buffer_test_text; 606 void *buffer; 607 int i; 608 const int max_realloc_count = 10; 609 610 /* Get a smallish buffer */ 611 for (i = 0; i < max_realloc_count; i++) { 612 g_reallocation_count = i; 613 buffer = XML_GetBuffer(g_parser, 1536); 614 if (buffer == NULL) 615 fail("1.5K buffer reallocation failed"); 616 assert(buffer != NULL); 617 memcpy(buffer, text, strlen(text)); 618 if (XML_ParseBuffer(g_parser, (int)strlen(text), XML_FALSE) 619 == XML_STATUS_OK) 620 break; 621 /* See comment in test_alloc_parse_xdecl() */ 622 alloc_teardown(); 623 alloc_setup(); 624 } 625 g_reallocation_count = -1; 626 if (i == 0) 627 fail("Parse succeeded with no reallocation"); 628 else if (i == max_realloc_count) 629 fail("Parse failed with max reallocation count"); 630 } 631 END_TEST 632 633 /* Same test for external entity parsers */ 634 START_TEST(test_alloc_ext_entity_realloc_buffer) { 635 const char *text = "<!DOCTYPE doc [\n" 636 " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n" 637 "]>\n" 638 "<doc>&en;</doc>"; 639 int i; 640 const int max_realloc_count = 10; 641 642 for (i = 0; i < max_realloc_count; i++) { 643 XML_SetExternalEntityRefHandler(g_parser, external_entity_reallocator); 644 XML_SetUserData(g_parser, &i); 645 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 646 == XML_STATUS_OK) 647 break; 648 /* See comment in test_alloc_parse_xdecl() */ 649 alloc_teardown(); 650 alloc_setup(); 651 } 652 if (i == 0) 653 fail("Succeeded with no reallocations"); 654 if (i == max_realloc_count) 655 fail("Failed with max reallocations"); 656 } 657 END_TEST 658 659 /* Test elements with many attributes are handled correctly */ 660 START_TEST(test_alloc_realloc_many_attributes) { 661 const char *text = "<!DOCTYPE doc [\n" 662 "<!ATTLIST doc za CDATA 'default'>\n" 663 "<!ATTLIST doc zb CDATA 'def2'>\n" 664 "<!ATTLIST doc zc CDATA 'def3'>\n" 665 "]>\n" 666 "<doc a='1'" 667 " b='2'" 668 " c='3'" 669 " d='4'" 670 " e='5'" 671 " f='6'" 672 " g='7'" 673 " h='8'" 674 " i='9'" 675 " j='10'" 676 " k='11'" 677 " l='12'" 678 " m='13'" 679 " n='14'" 680 " p='15'" 681 " q='16'" 682 " r='17'" 683 " s='18'>" 684 "</doc>"; 685 int i; 686 const int max_realloc_count = 10; 687 688 for (i = 0; i < max_realloc_count; i++) { 689 g_reallocation_count = i; 690 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 691 != XML_STATUS_ERROR) 692 break; 693 /* See comment in test_alloc_parse_xdecl() */ 694 alloc_teardown(); 695 alloc_setup(); 696 } 697 if (i == 0) 698 fail("Parse succeeded despite no reallocations"); 699 if (i == max_realloc_count) 700 fail("Parse failed at max reallocations"); 701 } 702 END_TEST 703 704 /* Test handling of a public entity with failing allocator */ 705 START_TEST(test_alloc_public_entity_value) { 706 const char *text = "<!DOCTYPE doc SYSTEM 'http://example.org/'>\n" 707 "<doc></doc>\n"; 708 char dtd_text[] 709 = "<!ELEMENT doc EMPTY>\n" 710 "<!ENTITY % e1 PUBLIC 'foo' 'bar.ent'>\n" 711 "<!ENTITY % " 712 /* Each line is 64 characters */ 713 "ThisIsAStupidlyLongParameterNameIntendedToTriggerPoolGrowth12345" 714 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 715 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 716 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 717 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 718 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 719 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 720 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 721 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 722 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 723 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 724 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 725 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 726 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 727 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 728 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 729 " '%e1;'>\n" 730 "%e1;\n"; 731 int i; 732 const int max_alloc_count = 50; 733 734 for (i = 0; i < max_alloc_count; i++) { 735 g_allocation_count = i; 736 init_dummy_handlers(); 737 XML_SetUserData(g_parser, dtd_text); 738 XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 739 XML_SetExternalEntityRefHandler(g_parser, external_entity_public); 740 /* Provoke a particular code path */ 741 XML_SetEntityDeclHandler(g_parser, dummy_entity_decl_handler); 742 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 743 != XML_STATUS_ERROR) 744 break; 745 /* See comment in test_alloc_parse_xdecl() */ 746 alloc_teardown(); 747 alloc_setup(); 748 } 749 if (i == 0) 750 fail("Parsing worked despite failing allocation"); 751 if (i == max_alloc_count) 752 fail("Parsing failed at max allocation count"); 753 if (get_dummy_handler_flags() != DUMMY_ENTITY_DECL_HANDLER_FLAG) 754 fail("Entity declaration handler not called"); 755 } 756 END_TEST 757 758 START_TEST(test_alloc_realloc_subst_public_entity_value) { 759 const char *text = "<!DOCTYPE doc SYSTEM 'http://example.org/'>\n" 760 "<doc></doc>\n"; 761 char dtd_text[] 762 = "<!ELEMENT doc EMPTY>\n" 763 "<!ENTITY % " 764 /* Each line is 64 characters */ 765 "ThisIsAStupidlyLongParameterNameIntendedToTriggerPoolGrowth12345" 766 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 767 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 768 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 769 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 770 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 771 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 772 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 773 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 774 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 775 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 776 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 777 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 778 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 779 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 780 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 781 " PUBLIC 'foo' 'bar.ent'>\n" 782 "%ThisIsAStupidlyLongParameterNameIntendedToTriggerPoolGrowth12345" 783 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 784 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 785 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 786 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 787 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 788 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 789 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 790 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 791 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 792 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 793 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 794 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 795 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 796 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 797 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP;"; 798 int i; 799 const int max_realloc_count = 10; 800 801 for (i = 0; i < max_realloc_count; i++) { 802 g_reallocation_count = i; 803 XML_SetUserData(g_parser, dtd_text); 804 XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 805 XML_SetExternalEntityRefHandler(g_parser, external_entity_public); 806 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 807 != XML_STATUS_ERROR) 808 break; 809 /* See comment in test_alloc_parse_xdecl() */ 810 alloc_teardown(); 811 alloc_setup(); 812 } 813 if (i == 0) 814 fail("Parsing worked despite failing reallocation"); 815 if (i == max_realloc_count) 816 fail("Parsing failed at max reallocation count"); 817 } 818 END_TEST 819 820 START_TEST(test_alloc_parse_public_doctype) { 821 const char *text 822 = "<?xml version='1.0' encoding='utf-8'?>\n" 823 "<!DOCTYPE doc PUBLIC '" 824 /* 64 characters per line */ 825 "http://example.com/a/long/enough/name/to/trigger/pool/growth/zz/" 826 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 827 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 828 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 829 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 830 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 831 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 832 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 833 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 834 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 835 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 836 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 837 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 838 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 839 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 840 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 841 "' 'test'>\n" 842 "<doc></doc>"; 843 int i; 844 const int max_alloc_count = 25; 845 846 for (i = 0; i < max_alloc_count; i++) { 847 g_allocation_count = i; 848 init_dummy_handlers(); 849 XML_SetDoctypeDeclHandler(g_parser, dummy_start_doctype_decl_handler, 850 dummy_end_doctype_decl_handler); 851 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 852 != XML_STATUS_ERROR) 853 break; 854 /* See comment in test_alloc_parse_xdecl() */ 855 alloc_teardown(); 856 alloc_setup(); 857 } 858 if (i == 0) 859 fail("Parse succeeded despite failing allocator"); 860 if (i == max_alloc_count) 861 fail("Parse failed at maximum allocation count"); 862 if (get_dummy_handler_flags() 863 != (DUMMY_START_DOCTYPE_DECL_HANDLER_FLAG 864 | DUMMY_END_DOCTYPE_DECL_HANDLER_FLAG)) 865 fail("Doctype handler functions not called"); 866 } 867 END_TEST 868 869 START_TEST(test_alloc_parse_public_doctype_long_name) { 870 const char *text 871 = "<?xml version='1.0' encoding='utf-8'?>\n" 872 "<!DOCTYPE doc PUBLIC 'http://example.com/foo' '" 873 /* 64 characters per line */ 874 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP" 875 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP" 876 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP" 877 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP" 878 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP" 879 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP" 880 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP" 881 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP" 882 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP" 883 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP" 884 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP" 885 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP" 886 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP" 887 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP" 888 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP" 889 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP" 890 "'>\n" 891 "<doc></doc>"; 892 int i; 893 const int max_alloc_count = 25; 894 895 for (i = 0; i < max_alloc_count; i++) { 896 g_allocation_count = i; 897 XML_SetDoctypeDeclHandler(g_parser, dummy_start_doctype_decl_handler, 898 dummy_end_doctype_decl_handler); 899 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 900 != XML_STATUS_ERROR) 901 break; 902 /* See comment in test_alloc_parse_xdecl() */ 903 alloc_teardown(); 904 alloc_setup(); 905 } 906 if (i == 0) 907 fail("Parse succeeded despite failing allocator"); 908 if (i == max_alloc_count) 909 fail("Parse failed at maximum allocation count"); 910 } 911 END_TEST 912 913 /* Test foreign DTD handling */ 914 START_TEST(test_alloc_set_foreign_dtd) { 915 const char *text1 = "<?xml version='1.0' encoding='us-ascii'?>\n" 916 "<doc>&entity;</doc>"; 917 char text2[] = "<!ELEMENT doc (#PCDATA)*>"; 918 int i; 919 const int max_alloc_count = 25; 920 921 for (i = 0; i < max_alloc_count; i++) { 922 g_allocation_count = i; 923 XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 924 XML_SetUserData(g_parser, &text2); 925 XML_SetExternalEntityRefHandler(g_parser, external_entity_alloc); 926 if (XML_UseForeignDTD(g_parser, XML_TRUE) != XML_ERROR_NONE) 927 fail("Could not set foreign DTD"); 928 if (_XML_Parse_SINGLE_BYTES(g_parser, text1, (int)strlen(text1), XML_TRUE) 929 != XML_STATUS_ERROR) 930 break; 931 /* See comment in test_alloc_parse_xdecl() */ 932 alloc_teardown(); 933 alloc_setup(); 934 } 935 if (i == 0) 936 fail("Parse succeeded despite failing allocator"); 937 if (i == max_alloc_count) 938 fail("Parse failed at maximum allocation count"); 939 } 940 END_TEST 941 942 /* Test based on ibm/valid/P32/ibm32v04.xml */ 943 START_TEST(test_alloc_attribute_enum_value) { 944 const char *text = "<?xml version='1.0' standalone='no'?>\n" 945 "<!DOCTYPE animal SYSTEM 'test.dtd'>\n" 946 "<animal>This is a \n <a/> \n\nyellow tiger</animal>"; 947 char dtd_text[] = "<!ELEMENT animal (#PCDATA|a)*>\n" 948 "<!ELEMENT a EMPTY>\n" 949 "<!ATTLIST animal xml:space (default|preserve) 'preserve'>"; 950 int i; 951 const int max_alloc_count = 30; 952 953 for (i = 0; i < max_alloc_count; i++) { 954 g_allocation_count = i; 955 XML_SetExternalEntityRefHandler(g_parser, external_entity_alloc); 956 XML_SetUserData(g_parser, dtd_text); 957 XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 958 /* An attribute list handler provokes a different code path */ 959 XML_SetAttlistDeclHandler(g_parser, dummy_attlist_decl_handler); 960 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 961 != XML_STATUS_ERROR) 962 break; 963 /* See comment in test_alloc_parse_xdecl() */ 964 alloc_teardown(); 965 alloc_setup(); 966 } 967 if (i == 0) 968 fail("Parse succeeded despite failing allocator"); 969 if (i == max_alloc_count) 970 fail("Parse failed at maximum allocation count"); 971 } 972 END_TEST 973 974 /* Test attribute enums sufficient to overflow the string pool */ 975 START_TEST(test_alloc_realloc_attribute_enum_value) { 976 const char *text = "<?xml version='1.0' standalone='no'?>\n" 977 "<!DOCTYPE animal SYSTEM 'test.dtd'>\n" 978 "<animal>This is a yellow tiger</animal>"; 979 /* We wish to define a collection of attribute enums that will 980 * cause the string pool storing them to have to expand. This 981 * means more than 1024 bytes, including the parentheses and 982 * separator bars. 983 */ 984 char dtd_text[] 985 = "<!ELEMENT animal (#PCDATA)*>\n" 986 "<!ATTLIST animal thing " 987 "(default" 988 /* Each line is 64 characters */ 989 "|ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 990 "|BBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 991 "|CBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 992 "|DBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 993 "|EBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 994 "|FBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 995 "|GBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 996 "|HBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 997 "|IBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 998 "|JBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 999 "|KBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 1000 "|LBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 1001 "|MBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 1002 "|NBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 1003 "|OBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 1004 "|PBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO)" 1005 " 'default'>"; 1006 int i; 1007 const int max_realloc_count = 10; 1008 1009 for (i = 0; i < max_realloc_count; i++) { 1010 g_reallocation_count = i; 1011 XML_SetExternalEntityRefHandler(g_parser, external_entity_alloc); 1012 XML_SetUserData(g_parser, dtd_text); 1013 XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 1014 /* An attribute list handler provokes a different code path */ 1015 XML_SetAttlistDeclHandler(g_parser, dummy_attlist_decl_handler); 1016 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 1017 != XML_STATUS_ERROR) 1018 break; 1019 /* See comment in test_alloc_parse_xdecl() */ 1020 alloc_teardown(); 1021 alloc_setup(); 1022 } 1023 if (i == 0) 1024 fail("Parse succeeded despite failing reallocator"); 1025 if (i == max_realloc_count) 1026 fail("Parse failed at maximum reallocation count"); 1027 } 1028 END_TEST 1029 1030 /* Test attribute enums in a #IMPLIED attribute forcing pool growth */ 1031 START_TEST(test_alloc_realloc_implied_attribute) { 1032 /* Forcing this particular code path is a balancing act. The 1033 * addition of the closing parenthesis and terminal NUL must be 1034 * what pushes the string of enums over the 1024-byte limit, 1035 * otherwise a different code path will pick up the realloc. 1036 */ 1037 const char *text 1038 = "<!DOCTYPE doc [\n" 1039 "<!ELEMENT doc EMPTY>\n" 1040 "<!ATTLIST doc a " 1041 /* Each line is 64 characters */ 1042 "(ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 1043 "|BBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 1044 "|CBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 1045 "|DBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 1046 "|EBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 1047 "|FBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 1048 "|GBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 1049 "|HBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 1050 "|IBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 1051 "|JBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 1052 "|KBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 1053 "|LBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 1054 "|MBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 1055 "|NBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 1056 "|OBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 1057 "|PBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMN)" 1058 " #IMPLIED>\n" 1059 "]><doc/>"; 1060 int i; 1061 const int max_realloc_count = 10; 1062 1063 for (i = 0; i < max_realloc_count; i++) { 1064 g_reallocation_count = i; 1065 XML_SetAttlistDeclHandler(g_parser, dummy_attlist_decl_handler); 1066 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 1067 != XML_STATUS_ERROR) 1068 break; 1069 /* See comment in test_alloc_parse_xdecl() */ 1070 alloc_teardown(); 1071 alloc_setup(); 1072 } 1073 if (i == 0) 1074 fail("Parse succeeded despite failing reallocator"); 1075 if (i == max_realloc_count) 1076 fail("Parse failed at maximum reallocation count"); 1077 } 1078 END_TEST 1079 1080 /* Test attribute enums in a defaulted attribute forcing pool growth */ 1081 START_TEST(test_alloc_realloc_default_attribute) { 1082 /* Forcing this particular code path is a balancing act. The 1083 * addition of the closing parenthesis and terminal NUL must be 1084 * what pushes the string of enums over the 1024-byte limit, 1085 * otherwise a different code path will pick up the realloc. 1086 */ 1087 const char *text 1088 = "<!DOCTYPE doc [\n" 1089 "<!ELEMENT doc EMPTY>\n" 1090 "<!ATTLIST doc a " 1091 /* Each line is 64 characters */ 1092 "(ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 1093 "|BBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 1094 "|CBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 1095 "|DBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 1096 "|EBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 1097 "|FBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 1098 "|GBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 1099 "|HBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 1100 "|IBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 1101 "|JBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 1102 "|KBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 1103 "|LBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 1104 "|MBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 1105 "|NBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 1106 "|OBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO" 1107 "|PBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMN)" 1108 " 'ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO'" 1109 ">\n]><doc/>"; 1110 int i; 1111 const int max_realloc_count = 10; 1112 1113 for (i = 0; i < max_realloc_count; i++) { 1114 g_reallocation_count = i; 1115 XML_SetAttlistDeclHandler(g_parser, dummy_attlist_decl_handler); 1116 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 1117 != XML_STATUS_ERROR) 1118 break; 1119 /* See comment in test_alloc_parse_xdecl() */ 1120 alloc_teardown(); 1121 alloc_setup(); 1122 } 1123 if (i == 0) 1124 fail("Parse succeeded despite failing reallocator"); 1125 if (i == max_realloc_count) 1126 fail("Parse failed at maximum reallocation count"); 1127 } 1128 END_TEST 1129 1130 /* Test long notation name with dodgy allocator */ 1131 START_TEST(test_alloc_notation) { 1132 const char *text 1133 = "<!DOCTYPE doc [\n" 1134 "<!NOTATION " 1135 /* Each line is 64 characters */ 1136 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1137 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1138 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1139 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1140 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1141 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1142 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1143 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1144 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1145 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1146 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1147 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1148 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1149 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1150 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1151 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1152 " SYSTEM 'http://example.org/n'>\n" 1153 "<!ENTITY e SYSTEM 'http://example.org/e' NDATA " 1154 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1155 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1156 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1157 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1158 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1159 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1160 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1161 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1162 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1163 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1164 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1165 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1166 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1167 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1168 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1169 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1170 ">\n" 1171 "<!ELEMENT doc EMPTY>\n" 1172 "]>\n<doc/>"; 1173 int i; 1174 const int max_alloc_count = 20; 1175 1176 for (i = 0; i < max_alloc_count; i++) { 1177 g_allocation_count = i; 1178 init_dummy_handlers(); 1179 XML_SetNotationDeclHandler(g_parser, dummy_notation_decl_handler); 1180 XML_SetEntityDeclHandler(g_parser, dummy_entity_decl_handler); 1181 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 1182 != XML_STATUS_ERROR) 1183 break; 1184 /* See comment in test_alloc_parse_xdecl() */ 1185 alloc_teardown(); 1186 alloc_setup(); 1187 } 1188 if (i == 0) 1189 fail("Parse succeeded despite allocation failures"); 1190 if (i == max_alloc_count) 1191 fail("Parse failed at maximum allocation count"); 1192 if (get_dummy_handler_flags() 1193 != (DUMMY_ENTITY_DECL_HANDLER_FLAG | DUMMY_NOTATION_DECL_HANDLER_FLAG)) 1194 fail("Entity declaration handler not called"); 1195 } 1196 END_TEST 1197 1198 /* Test public notation with dodgy allocator */ 1199 START_TEST(test_alloc_public_notation) { 1200 const char *text 1201 = "<!DOCTYPE doc [\n" 1202 "<!NOTATION note PUBLIC '" 1203 /* 64 characters per line */ 1204 "http://example.com/a/long/enough/name/to/trigger/pool/growth/zz/" 1205 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 1206 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 1207 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 1208 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 1209 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 1210 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 1211 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 1212 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 1213 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 1214 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 1215 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 1216 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 1217 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 1218 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 1219 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 1220 "' 'foo'>\n" 1221 "<!ENTITY e SYSTEM 'http://example.com/e' NDATA note>\n" 1222 "<!ELEMENT doc EMPTY>\n" 1223 "]>\n<doc/>"; 1224 int i; 1225 const int max_alloc_count = 20; 1226 1227 for (i = 0; i < max_alloc_count; i++) { 1228 g_allocation_count = i; 1229 init_dummy_handlers(); 1230 XML_SetNotationDeclHandler(g_parser, dummy_notation_decl_handler); 1231 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 1232 != XML_STATUS_ERROR) 1233 break; 1234 /* See comment in test_alloc_parse_xdecl() */ 1235 alloc_teardown(); 1236 alloc_setup(); 1237 } 1238 if (i == 0) 1239 fail("Parse succeeded despite allocation failures"); 1240 if (i == max_alloc_count) 1241 fail("Parse failed at maximum allocation count"); 1242 if (get_dummy_handler_flags() != DUMMY_NOTATION_DECL_HANDLER_FLAG) 1243 fail("Notation handler not called"); 1244 } 1245 END_TEST 1246 1247 /* Test public notation with dodgy allocator */ 1248 START_TEST(test_alloc_system_notation) { 1249 const char *text 1250 = "<!DOCTYPE doc [\n" 1251 "<!NOTATION note SYSTEM '" 1252 /* 64 characters per line */ 1253 "http://example.com/a/long/enough/name/to/trigger/pool/growth/zz/" 1254 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 1255 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 1256 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 1257 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 1258 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 1259 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 1260 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 1261 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 1262 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 1263 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 1264 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 1265 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 1266 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 1267 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 1268 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/" 1269 "'>\n" 1270 "<!ENTITY e SYSTEM 'http://example.com/e' NDATA note>\n" 1271 "<!ELEMENT doc EMPTY>\n" 1272 "]>\n<doc/>"; 1273 int i; 1274 const int max_alloc_count = 20; 1275 1276 for (i = 0; i < max_alloc_count; i++) { 1277 g_allocation_count = i; 1278 init_dummy_handlers(); 1279 XML_SetNotationDeclHandler(g_parser, dummy_notation_decl_handler); 1280 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 1281 != XML_STATUS_ERROR) 1282 break; 1283 /* See comment in test_alloc_parse_xdecl() */ 1284 alloc_teardown(); 1285 alloc_setup(); 1286 } 1287 if (i == 0) 1288 fail("Parse succeeded despite allocation failures"); 1289 if (i == max_alloc_count) 1290 fail("Parse failed at maximum allocation count"); 1291 if (get_dummy_handler_flags() != DUMMY_NOTATION_DECL_HANDLER_FLAG) 1292 fail("Notation handler not called"); 1293 } 1294 END_TEST 1295 1296 START_TEST(test_alloc_nested_groups) { 1297 const char *text 1298 = "<!DOCTYPE doc [\n" 1299 "<!ELEMENT doc " 1300 /* Sixteen elements per line */ 1301 "(e,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?," 1302 "(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?" 1303 "))))))))))))))))))))))))))))))))>\n" 1304 "<!ELEMENT e EMPTY>" 1305 "]>\n" 1306 "<doc><e/></doc>"; 1307 CharData storage; 1308 int i; 1309 const int max_alloc_count = 20; 1310 1311 for (i = 0; i < max_alloc_count; i++) { 1312 g_allocation_count = i; 1313 CharData_Init(&storage); 1314 XML_SetElementDeclHandler(g_parser, dummy_element_decl_handler); 1315 XML_SetStartElementHandler(g_parser, record_element_start_handler); 1316 XML_SetUserData(g_parser, &storage); 1317 init_dummy_handlers(); 1318 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 1319 != XML_STATUS_ERROR) 1320 break; 1321 /* See comment in test_alloc_parse_xdecl() */ 1322 alloc_teardown(); 1323 alloc_setup(); 1324 } 1325 1326 if (i == 0) 1327 fail("Parse succeeded despite failing reallocator"); 1328 if (i == max_alloc_count) 1329 fail("Parse failed at maximum reallocation count"); 1330 CharData_CheckXMLChars(&storage, XCS("doce")); 1331 if (get_dummy_handler_flags() != DUMMY_ELEMENT_DECL_HANDLER_FLAG) 1332 fail("Element handler not fired"); 1333 } 1334 END_TEST 1335 1336 START_TEST(test_alloc_realloc_nested_groups) { 1337 const char *text 1338 = "<!DOCTYPE doc [\n" 1339 "<!ELEMENT doc " 1340 /* Sixteen elements per line */ 1341 "(e,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?," 1342 "(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?" 1343 "))))))))))))))))))))))))))))))))>\n" 1344 "<!ELEMENT e EMPTY>" 1345 "]>\n" 1346 "<doc><e/></doc>"; 1347 CharData storage; 1348 int i; 1349 const int max_realloc_count = 10; 1350 1351 for (i = 0; i < max_realloc_count; i++) { 1352 g_reallocation_count = i; 1353 CharData_Init(&storage); 1354 XML_SetElementDeclHandler(g_parser, dummy_element_decl_handler); 1355 XML_SetStartElementHandler(g_parser, record_element_start_handler); 1356 XML_SetUserData(g_parser, &storage); 1357 init_dummy_handlers(); 1358 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 1359 != XML_STATUS_ERROR) 1360 break; 1361 /* See comment in test_alloc_parse_xdecl() */ 1362 alloc_teardown(); 1363 alloc_setup(); 1364 } 1365 1366 if (i == 0) 1367 fail("Parse succeeded despite failing reallocator"); 1368 if (i == max_realloc_count) 1369 fail("Parse failed at maximum reallocation count"); 1370 CharData_CheckXMLChars(&storage, XCS("doce")); 1371 if (get_dummy_handler_flags() != DUMMY_ELEMENT_DECL_HANDLER_FLAG) 1372 fail("Element handler not fired"); 1373 } 1374 END_TEST 1375 1376 START_TEST(test_alloc_large_group) { 1377 const char *text = "<!DOCTYPE doc [\n" 1378 "<!ELEMENT doc (" 1379 "a1|a2|a3|a4|a5|a6|a7|a8|" 1380 "b1|b2|b3|b4|b5|b6|b7|b8|" 1381 "c1|c2|c3|c4|c5|c6|c7|c8|" 1382 "d1|d2|d3|d4|d5|d6|d7|d8|" 1383 "e1" 1384 ")+>\n" 1385 "]>\n" 1386 "<doc>\n" 1387 "<a1/>\n" 1388 "</doc>\n"; 1389 int i; 1390 const int max_alloc_count = 50; 1391 1392 for (i = 0; i < max_alloc_count; i++) { 1393 g_allocation_count = i; 1394 XML_SetElementDeclHandler(g_parser, dummy_element_decl_handler); 1395 init_dummy_handlers(); 1396 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 1397 != XML_STATUS_ERROR) 1398 break; 1399 /* See comment in test_alloc_parse_xdecl() */ 1400 alloc_teardown(); 1401 alloc_setup(); 1402 } 1403 if (i == 0) 1404 fail("Parse succeeded despite failing allocator"); 1405 if (i == max_alloc_count) 1406 fail("Parse failed at maximum allocation count"); 1407 if (get_dummy_handler_flags() != DUMMY_ELEMENT_DECL_HANDLER_FLAG) 1408 fail("Element handler flag not raised"); 1409 } 1410 END_TEST 1411 1412 START_TEST(test_alloc_realloc_group_choice) { 1413 const char *text = "<!DOCTYPE doc [\n" 1414 "<!ELEMENT doc (" 1415 "a1|a2|a3|a4|a5|a6|a7|a8|" 1416 "b1|b2|b3|b4|b5|b6|b7|b8|" 1417 "c1|c2|c3|c4|c5|c6|c7|c8|" 1418 "d1|d2|d3|d4|d5|d6|d7|d8|" 1419 "e1" 1420 ")+>\n" 1421 "]>\n" 1422 "<doc>\n" 1423 "<a1/>\n" 1424 "<b2 attr='foo'>This is a foo</b2>\n" 1425 "<c3></c3>\n" 1426 "</doc>\n"; 1427 int i; 1428 const int max_realloc_count = 10; 1429 1430 for (i = 0; i < max_realloc_count; i++) { 1431 g_reallocation_count = i; 1432 XML_SetElementDeclHandler(g_parser, dummy_element_decl_handler); 1433 init_dummy_handlers(); 1434 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 1435 != XML_STATUS_ERROR) 1436 break; 1437 /* See comment in test_alloc_parse_xdecl() */ 1438 alloc_teardown(); 1439 alloc_setup(); 1440 } 1441 if (i == 0) 1442 fail("Parse succeeded despite failing reallocator"); 1443 if (i == max_realloc_count) 1444 fail("Parse failed at maximum reallocation count"); 1445 if (get_dummy_handler_flags() != DUMMY_ELEMENT_DECL_HANDLER_FLAG) 1446 fail("Element handler flag not raised"); 1447 } 1448 END_TEST 1449 1450 START_TEST(test_alloc_pi_in_epilog) { 1451 const char *text = "<doc></doc>\n" 1452 "<?pi in epilog?>"; 1453 int i; 1454 const int max_alloc_count = 15; 1455 1456 for (i = 0; i < max_alloc_count; i++) { 1457 g_allocation_count = i; 1458 XML_SetProcessingInstructionHandler(g_parser, dummy_pi_handler); 1459 init_dummy_handlers(); 1460 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 1461 != XML_STATUS_ERROR) 1462 break; 1463 /* See comment in test_alloc_parse_xdecl() */ 1464 alloc_teardown(); 1465 alloc_setup(); 1466 } 1467 if (i == 0) 1468 fail("Parse completed despite failing allocator"); 1469 if (i == max_alloc_count) 1470 fail("Parse failed at maximum allocation count"); 1471 if (get_dummy_handler_flags() != DUMMY_PI_HANDLER_FLAG) 1472 fail("Processing instruction handler not invoked"); 1473 } 1474 END_TEST 1475 1476 START_TEST(test_alloc_comment_in_epilog) { 1477 const char *text = "<doc></doc>\n" 1478 "<!-- comment in epilog -->"; 1479 int i; 1480 const int max_alloc_count = 15; 1481 1482 for (i = 0; i < max_alloc_count; i++) { 1483 g_allocation_count = i; 1484 XML_SetCommentHandler(g_parser, dummy_comment_handler); 1485 init_dummy_handlers(); 1486 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 1487 != XML_STATUS_ERROR) 1488 break; 1489 /* See comment in test_alloc_parse_xdecl() */ 1490 alloc_teardown(); 1491 alloc_setup(); 1492 } 1493 if (i == 0) 1494 fail("Parse completed despite failing allocator"); 1495 if (i == max_alloc_count) 1496 fail("Parse failed at maximum allocation count"); 1497 if (get_dummy_handler_flags() != DUMMY_COMMENT_HANDLER_FLAG) 1498 fail("Processing instruction handler not invoked"); 1499 } 1500 END_TEST 1501 1502 START_TEST(test_alloc_realloc_long_attribute_value) { 1503 const char *text 1504 = "<!DOCTYPE doc [<!ENTITY foo '" 1505 /* Each line is 64 characters */ 1506 "This entity will be substituted as an attribute value, and is " 1507 "calculated to be exactly long enough that the terminating NUL " 1508 "that the library adds internally will trigger the string pool to" 1509 "grow. GHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1510 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1511 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1512 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1513 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1514 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1515 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1516 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1517 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1518 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1519 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1520 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1521 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1522 "'>]>\n" 1523 "<doc a='&foo;'></doc>"; 1524 int i; 1525 const int max_realloc_count = 10; 1526 1527 for (i = 0; i < max_realloc_count; i++) { 1528 g_reallocation_count = i; 1529 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 1530 != XML_STATUS_ERROR) 1531 break; 1532 /* See comment in test_alloc_parse_xdecl() */ 1533 alloc_teardown(); 1534 alloc_setup(); 1535 } 1536 if (i == 0) 1537 fail("Parse succeeded despite failing reallocator"); 1538 if (i == max_realloc_count) 1539 fail("Parse failed at maximum reallocation count"); 1540 } 1541 END_TEST 1542 1543 START_TEST(test_alloc_attribute_whitespace) { 1544 const char *text = "<doc a=' '></doc>"; 1545 int i; 1546 const int max_alloc_count = 15; 1547 1548 for (i = 0; i < max_alloc_count; i++) { 1549 g_allocation_count = i; 1550 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 1551 != XML_STATUS_ERROR) 1552 break; 1553 /* See comment in test_alloc_parse_xdecl() */ 1554 alloc_teardown(); 1555 alloc_setup(); 1556 } 1557 if (i == 0) 1558 fail("Parse succeeded despite failing allocator"); 1559 if (i == max_alloc_count) 1560 fail("Parse failed at maximum allocation count"); 1561 } 1562 END_TEST 1563 1564 START_TEST(test_alloc_attribute_predefined_entity) { 1565 const char *text = "<doc a='&'></doc>"; 1566 int i; 1567 const int max_alloc_count = 15; 1568 1569 for (i = 0; i < max_alloc_count; i++) { 1570 g_allocation_count = i; 1571 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 1572 != XML_STATUS_ERROR) 1573 break; 1574 /* See comment in test_alloc_parse_xdecl() */ 1575 alloc_teardown(); 1576 alloc_setup(); 1577 } 1578 if (i == 0) 1579 fail("Parse succeeded despite failing allocator"); 1580 if (i == max_alloc_count) 1581 fail("Parse failed at maximum allocation count"); 1582 } 1583 END_TEST 1584 1585 /* Test that a character reference at the end of a suitably long 1586 * default value for an attribute can trigger pool growth, and recovers 1587 * if the allocator fails on it. 1588 */ 1589 START_TEST(test_alloc_long_attr_default_with_char_ref) { 1590 const char *text 1591 = "<!DOCTYPE doc [<!ATTLIST doc a CDATA '" 1592 /* 64 characters per line */ 1593 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1594 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1595 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1596 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1597 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1598 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1599 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1600 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1601 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1602 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1603 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1604 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1605 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1606 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1607 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1608 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHI" 1609 "1'>]>\n" 1610 "<doc/>"; 1611 int i; 1612 const int max_alloc_count = 20; 1613 1614 for (i = 0; i < max_alloc_count; i++) { 1615 g_allocation_count = i; 1616 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 1617 != XML_STATUS_ERROR) 1618 break; 1619 /* See comment in test_alloc_parse_xdecl() */ 1620 alloc_teardown(); 1621 alloc_setup(); 1622 } 1623 if (i == 0) 1624 fail("Parse succeeded despite failing allocator"); 1625 if (i == max_alloc_count) 1626 fail("Parse failed at maximum allocation count"); 1627 } 1628 END_TEST 1629 1630 /* Test that a long character reference substitution triggers a pool 1631 * expansion correctly for an attribute value. 1632 */ 1633 START_TEST(test_alloc_long_attr_value) { 1634 const char *text 1635 = "<!DOCTYPE test [<!ENTITY foo '\n" 1636 /* 64 characters per line */ 1637 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1638 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1639 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1640 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1641 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1642 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1643 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1644 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1645 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1646 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1647 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1648 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1649 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1650 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1651 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1652 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1653 "'>]>\n" 1654 "<test a='&foo;'/>"; 1655 int i; 1656 const int max_alloc_count = 25; 1657 1658 for (i = 0; i < max_alloc_count; i++) { 1659 g_allocation_count = i; 1660 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 1661 != XML_STATUS_ERROR) 1662 break; 1663 /* See comment in test_alloc_parse_xdecl() */ 1664 alloc_teardown(); 1665 alloc_setup(); 1666 } 1667 if (i == 0) 1668 fail("Parse succeeded despite failing allocator"); 1669 if (i == max_alloc_count) 1670 fail("Parse failed at maximum allocation count"); 1671 } 1672 END_TEST 1673 1674 /* Test that an error in a nested parameter entity substitution is 1675 * handled correctly. It seems unlikely that the code path being 1676 * exercised can be reached purely by carefully crafted XML, but an 1677 * allocation error in the right place will definitely do it. 1678 */ 1679 START_TEST(test_alloc_nested_entities) { 1680 const char *text = "<!DOCTYPE doc SYSTEM 'http://example.org/one.ent'>\n" 1681 "<doc />"; 1682 ExtFaults test_data 1683 = {"<!ENTITY % pe1 '" 1684 /* 64 characters per line */ 1685 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1686 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1687 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1688 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1689 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1690 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1691 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1692 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1693 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1694 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1695 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1696 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1697 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1698 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1699 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1700 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1701 "'>\n" 1702 "<!ENTITY % pe2 '%pe1;'>\n" 1703 "<!ENTITY % pe3 '%pe2;'>", 1704 "Memory Fail not faulted", NULL, XML_ERROR_NO_MEMORY}; 1705 1706 /* Causes an allocation error in a nested storeEntityValue() */ 1707 g_allocation_count = 12; 1708 XML_SetUserData(g_parser, &test_data); 1709 XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 1710 XML_SetExternalEntityRefHandler(g_parser, external_entity_faulter); 1711 expect_failure(text, XML_ERROR_EXTERNAL_ENTITY_HANDLING, 1712 "Entity allocation failure not noted"); 1713 } 1714 END_TEST 1715 1716 START_TEST(test_alloc_realloc_param_entity_newline) { 1717 const char *text = "<!DOCTYPE doc SYSTEM 'http://example.org/'>\n" 1718 "<doc/>"; 1719 char dtd_text[] 1720 = "<!ENTITY % pe '<!ATTLIST doc att CDATA \"" 1721 /* 64 characters per line */ 1722 "This default value is carefully crafted so that the carriage " 1723 "return right at the end of the entity string causes an internal " 1724 "string pool to have to grow. This allows us to test the alloc " 1725 "failure path from that point. OPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1726 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1727 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1728 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1729 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1730 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1731 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1732 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1733 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1734 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1735 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1736 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1737 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDE" 1738 "\">\n'>" 1739 "%pe;\n"; 1740 int i; 1741 const int max_realloc_count = 5; 1742 1743 for (i = 0; i < max_realloc_count; i++) { 1744 g_reallocation_count = i; 1745 XML_SetUserData(g_parser, dtd_text); 1746 XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 1747 XML_SetExternalEntityRefHandler(g_parser, external_entity_alloc); 1748 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 1749 != XML_STATUS_ERROR) 1750 break; 1751 /* See comment in test_alloc_parse_xdecl() */ 1752 alloc_teardown(); 1753 alloc_setup(); 1754 } 1755 if (i == 0) 1756 fail("Parse succeeded despite failing reallocator"); 1757 if (i == max_realloc_count) 1758 fail("Parse failed at maximum reallocation count"); 1759 } 1760 END_TEST 1761 1762 START_TEST(test_alloc_realloc_ce_extends_pe) { 1763 const char *text = "<!DOCTYPE doc SYSTEM 'http://example.org/'>\n" 1764 "<doc/>"; 1765 char dtd_text[] 1766 = "<!ENTITY % pe '<!ATTLIST doc att CDATA \"" 1767 /* 64 characters per line */ 1768 "This default value is carefully crafted so that the character " 1769 "entity at the end causes an internal string pool to have to " 1770 "grow. This allows us to test the allocation failure path from " 1771 "that point onwards. EFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1772 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1773 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1774 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1775 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1776 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1777 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1778 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1779 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1780 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1781 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1782 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" 1783 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGQ" 1784 "\">\n'>" 1785 "%pe;\n"; 1786 int i; 1787 const int max_realloc_count = 5; 1788 1789 for (i = 0; i < max_realloc_count; i++) { 1790 g_reallocation_count = i; 1791 XML_SetUserData(g_parser, dtd_text); 1792 XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 1793 XML_SetExternalEntityRefHandler(g_parser, external_entity_alloc); 1794 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 1795 != XML_STATUS_ERROR) 1796 break; 1797 /* See comment in test_alloc_parse_xdecl() */ 1798 alloc_teardown(); 1799 alloc_setup(); 1800 } 1801 if (i == 0) 1802 fail("Parse succeeded despite failing reallocator"); 1803 if (i == max_realloc_count) 1804 fail("Parse failed at maximum reallocation count"); 1805 } 1806 END_TEST 1807 1808 START_TEST(test_alloc_realloc_attributes) { 1809 const char *text = "<!DOCTYPE doc [\n" 1810 " <!ATTLIST doc\n" 1811 " a1 (a|b|c) 'a'\n" 1812 " a2 (foo|bar) #IMPLIED\n" 1813 " a3 NMTOKEN #IMPLIED\n" 1814 " a4 NMTOKENS #IMPLIED\n" 1815 " a5 ID #IMPLIED\n" 1816 " a6 IDREF #IMPLIED\n" 1817 " a7 IDREFS #IMPLIED\n" 1818 " a8 ENTITY #IMPLIED\n" 1819 " a9 ENTITIES #IMPLIED\n" 1820 " a10 CDATA #IMPLIED\n" 1821 " >]>\n" 1822 "<doc>wombat</doc>\n"; 1823 int i; 1824 const int max_realloc_count = 5; 1825 1826 for (i = 0; i < max_realloc_count; i++) { 1827 g_reallocation_count = i; 1828 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 1829 != XML_STATUS_ERROR) 1830 break; 1831 /* See comment in test_alloc_parse_xdecl() */ 1832 alloc_teardown(); 1833 alloc_setup(); 1834 } 1835 1836 if (i == 0) 1837 fail("Parse succeeded despite failing reallocator"); 1838 if (i == max_realloc_count) 1839 fail("Parse failed at maximum reallocation count"); 1840 } 1841 END_TEST 1842 1843 START_TEST(test_alloc_long_doc_name) { 1844 const char *text = 1845 /* 64 characters per line */ 1846 "<LongRootElementNameThatWillCauseTheNextAllocationToExpandTheStr" 1847 "ingPoolForTheDTDQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 1848 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 1849 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 1850 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 1851 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 1852 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 1853 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 1854 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 1855 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 1856 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 1857 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 1858 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 1859 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 1860 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 1861 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" 1862 " a='1'/>"; 1863 int i; 1864 const int max_alloc_count = 20; 1865 1866 for (i = 0; i < max_alloc_count; i++) { 1867 g_allocation_count = i; 1868 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 1869 != XML_STATUS_ERROR) 1870 break; 1871 /* See comment in test_alloc_parse_xdecl() */ 1872 alloc_teardown(); 1873 alloc_setup(); 1874 } 1875 if (i == 0) 1876 fail("Parsing worked despite failing reallocations"); 1877 else if (i == max_alloc_count) 1878 fail("Parsing failed even at max reallocation count"); 1879 } 1880 END_TEST 1881 1882 START_TEST(test_alloc_long_base) { 1883 const char *text = "<!DOCTYPE doc [\n" 1884 " <!ENTITY e SYSTEM 'foo'>\n" 1885 "]>\n" 1886 "<doc>&e;</doc>"; 1887 char entity_text[] = "Hello world"; 1888 const XML_Char *base = 1889 /* 64 characters per line */ 1890 /* clang-format off */ 1891 XCS("LongBaseURI/that/will/overflow/an/internal/buffer/and/cause/it/t") 1892 XCS("o/have/to/grow/PQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/") 1893 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/") 1894 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/") 1895 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/") 1896 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/") 1897 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/") 1898 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/") 1899 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/") 1900 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/") 1901 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/") 1902 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/") 1903 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/") 1904 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/") 1905 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/") 1906 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"); 1907 /* clang-format on */ 1908 int i; 1909 const int max_alloc_count = 25; 1910 1911 for (i = 0; i < max_alloc_count; i++) { 1912 g_allocation_count = i; 1913 XML_SetUserData(g_parser, entity_text); 1914 XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 1915 XML_SetExternalEntityRefHandler(g_parser, external_entity_alloc); 1916 if (XML_SetBase(g_parser, base) == XML_STATUS_ERROR) { 1917 XML_ParserReset(g_parser, NULL); 1918 continue; 1919 } 1920 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 1921 != XML_STATUS_ERROR) 1922 break; 1923 /* See comment in test_alloc_parse_xdecl() */ 1924 alloc_teardown(); 1925 alloc_setup(); 1926 } 1927 if (i == 0) 1928 fail("Parsing worked despite failing allocations"); 1929 else if (i == max_alloc_count) 1930 fail("Parsing failed even at max allocation count"); 1931 } 1932 END_TEST 1933 1934 START_TEST(test_alloc_long_public_id) { 1935 const char *text 1936 = "<!DOCTYPE doc [\n" 1937 " <!ENTITY e PUBLIC '" 1938 /* 64 characters per line */ 1939 "LongPublicIDThatShouldResultInAnInternalStringPoolGrowingAtASpec" 1940 "ificMomentKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 1941 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 1942 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 1943 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 1944 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 1945 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 1946 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 1947 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 1948 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 1949 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 1950 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 1951 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 1952 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 1953 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 1954 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 1955 "' 'bar'>\n" 1956 "]>\n" 1957 "<doc>&e;</doc>"; 1958 char entity_text[] = "Hello world"; 1959 int i; 1960 const int max_alloc_count = 40; 1961 1962 for (i = 0; i < max_alloc_count; i++) { 1963 g_allocation_count = i; 1964 XML_SetUserData(g_parser, entity_text); 1965 XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 1966 XML_SetExternalEntityRefHandler(g_parser, external_entity_alloc); 1967 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 1968 != XML_STATUS_ERROR) 1969 break; 1970 /* See comment in test_alloc_parse_xdecl() */ 1971 alloc_teardown(); 1972 alloc_setup(); 1973 } 1974 if (i == 0) 1975 fail("Parsing worked despite failing allocations"); 1976 else if (i == max_alloc_count) 1977 fail("Parsing failed even at max allocation count"); 1978 } 1979 END_TEST 1980 1981 START_TEST(test_alloc_long_entity_value) { 1982 const char *text 1983 = "<!DOCTYPE doc [\n" 1984 " <!ENTITY e1 '" 1985 /* 64 characters per line */ 1986 "Long entity value that should provoke a string pool to grow whil" 1987 "e setting up to parse the external entity below. xyz0123456789AB" 1988 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 1989 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 1990 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 1991 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 1992 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 1993 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 1994 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 1995 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 1996 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 1997 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 1998 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 1999 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 2000 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 2001 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 2002 "'>\n" 2003 " <!ENTITY e2 SYSTEM 'bar'>\n" 2004 "]>\n" 2005 "<doc>&e2;</doc>"; 2006 char entity_text[] = "Hello world"; 2007 int i; 2008 const int max_alloc_count = 40; 2009 2010 for (i = 0; i < max_alloc_count; i++) { 2011 g_allocation_count = i; 2012 XML_SetUserData(g_parser, entity_text); 2013 XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 2014 XML_SetExternalEntityRefHandler(g_parser, external_entity_alloc); 2015 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 2016 != XML_STATUS_ERROR) 2017 break; 2018 /* See comment in test_alloc_parse_xdecl() */ 2019 alloc_teardown(); 2020 alloc_setup(); 2021 } 2022 if (i == 0) 2023 fail("Parsing worked despite failing allocations"); 2024 else if (i == max_alloc_count) 2025 fail("Parsing failed even at max allocation count"); 2026 } 2027 END_TEST 2028 2029 START_TEST(test_alloc_long_notation) { 2030 const char *text 2031 = "<!DOCTYPE doc [\n" 2032 " <!NOTATION note SYSTEM '" 2033 /* 64 characters per line */ 2034 "ALongNotationNameThatShouldProvokeStringPoolGrowthWhileCallingAn" 2035 "ExternalEntityParserUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 2036 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 2037 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 2038 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 2039 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 2040 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 2041 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 2042 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 2043 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 2044 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 2045 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 2046 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 2047 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 2048 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 2049 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 2050 "'>\n" 2051 " <!ENTITY e1 SYSTEM 'foo' NDATA " 2052 /* 64 characters per line */ 2053 "ALongNotationNameThatShouldProvokeStringPoolGrowthWhileCallingAn" 2054 "ExternalEntityParserUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 2055 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 2056 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 2057 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 2058 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 2059 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 2060 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 2061 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 2062 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 2063 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 2064 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 2065 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 2066 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 2067 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 2068 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB" 2069 ">\n" 2070 " <!ENTITY e2 SYSTEM 'bar'>\n" 2071 "]>\n" 2072 "<doc>&e2;</doc>"; 2073 ExtOption options[] 2074 = {{XCS("foo"), "Entity Foo"}, {XCS("bar"), "Entity Bar"}, {NULL, NULL}}; 2075 int i; 2076 const int max_alloc_count = 40; 2077 2078 for (i = 0; i < max_alloc_count; i++) { 2079 g_allocation_count = i; 2080 XML_SetUserData(g_parser, options); 2081 XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 2082 XML_SetExternalEntityRefHandler(g_parser, external_entity_optioner); 2083 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 2084 != XML_STATUS_ERROR) 2085 break; 2086 2087 /* See comment in test_alloc_parse_xdecl() */ 2088 alloc_teardown(); 2089 alloc_setup(); 2090 } 2091 if (i == 0) 2092 fail("Parsing worked despite failing allocations"); 2093 else if (i == max_alloc_count) 2094 fail("Parsing failed even at max allocation count"); 2095 } 2096 END_TEST 2097 2098 START_TEST(test_alloc_reset_after_external_entity_parser_create_fail) { 2099 const char *const text = "<!DOCTYPE doc SYSTEM 'foo'><doc/>"; 2100 2101 XML_SetExternalEntityRefHandler( 2102 g_parser, external_entity_parser_create_alloc_fail_handler); 2103 XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 2104 2105 if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) 2106 != XML_STATUS_ERROR) 2107 fail("Call to parse was expected to fail"); 2108 2109 if (XML_GetErrorCode(g_parser) != XML_ERROR_EXTERNAL_ENTITY_HANDLING) 2110 fail("Call to parse was expected to fail from the external entity handler"); 2111 2112 XML_ParserReset(g_parser, NULL); 2113 } 2114 END_TEST 2115 2116 #if XML_GE == 1 2117 static size_t 2118 sizeRecordedFor(void *ptr) { 2119 return *(size_t *)((char *)ptr - EXPAT_MALLOC_PADDING - sizeof(size_t)); 2120 } 2121 #endif // XML_GE == 1 2122 2123 START_TEST(test_alloc_tracker_size_recorded) { 2124 XML_Memory_Handling_Suite memsuite = {malloc, realloc, free}; 2125 2126 bool values[] = {true, false}; 2127 for (size_t i = 0; i < sizeof(values) / sizeof(values[0]); i++) { 2128 const bool useMemSuite = values[i]; 2129 set_subtest("useMemSuite=%d", (int)useMemSuite); 2130 XML_Parser parser = useMemSuite 2131 ? XML_ParserCreate_MM(NULL, &memsuite, XCS("|")) 2132 : XML_ParserCreate(NULL); 2133 2134 #if XML_GE == 1 2135 void *ptr = expat_malloc(parser, 10, -1); 2136 2137 assert_true(ptr != NULL); 2138 assert_true(sizeRecordedFor(ptr) == 10); 2139 2140 assert_true(expat_realloc(parser, ptr, SIZE_MAX, -1) == NULL); 2141 2142 assert_true(sizeRecordedFor(ptr) == 10); // i.e. unchanged 2143 2144 assert_true(expat_realloc(parser, ptr, SIZE_MAX / 2, -1) == NULL); 2145 2146 assert_true(sizeRecordedFor(ptr) == 10); // i.e. unchanged 2147 2148 ptr = expat_realloc(parser, ptr, 20, -1); 2149 2150 assert_true(ptr != NULL); 2151 assert_true(sizeRecordedFor(ptr) == 20); 2152 2153 expat_free(parser, ptr, -1); 2154 #endif 2155 2156 XML_ParserFree(parser); 2157 } 2158 } 2159 END_TEST 2160 2161 START_TEST(test_alloc_tracker_pointer_alignment) { 2162 XML_Parser parser = XML_ParserCreate(NULL); 2163 #if XML_GE == 1 2164 assert_true(sizeof(long long) >= sizeof(size_t)); // self-test 2165 long long *const ptr = expat_malloc(parser, 4 * sizeof(long long), -1); 2166 ptr[0] = 0LL; 2167 ptr[1] = 1LL; 2168 ptr[2] = 2LL; 2169 ptr[3] = 3LL; 2170 expat_free(parser, ptr, -1); 2171 #endif 2172 XML_ParserFree(parser); 2173 } 2174 END_TEST 2175 2176 START_TEST(test_alloc_tracker_maximum_amplification) { 2177 if (g_reparseDeferralEnabledDefault == XML_TRUE) { 2178 return; 2179 } 2180 2181 XML_Parser parser = XML_ParserCreate(NULL); 2182 2183 // Get .m_accounting.countBytesDirect from 0 to 3 2184 const char *const chunk = "<e>"; 2185 assert_true(_XML_Parse_SINGLE_BYTES(parser, chunk, (int)strlen(chunk), 2186 /*isFinal=*/XML_FALSE) 2187 == XML_STATUS_OK); 2188 2189 #if XML_GE == 1 2190 // Stop activation threshold from interfering 2191 assert_true(XML_SetAllocTrackerActivationThreshold(parser, 0) == XML_TRUE); 2192 2193 // Exceed maximum amplification: should be rejected. 2194 assert_true(expat_malloc(parser, 1000, -1) == NULL); 2195 2196 // Increase maximum amplification, and try the same amount once more: should 2197 // work. 2198 assert_true(XML_SetAllocTrackerMaximumAmplification(parser, 3000.0f) 2199 == XML_TRUE); 2200 2201 void *const ptr = expat_malloc(parser, 1000, -1); 2202 assert_true(ptr != NULL); 2203 expat_free(parser, ptr, -1); 2204 #endif 2205 2206 XML_ParserFree(parser); 2207 } 2208 END_TEST 2209 2210 START_TEST(test_alloc_tracker_threshold) { 2211 XML_Parser parser = XML_ParserCreate(NULL); 2212 2213 #if XML_GE == 1 2214 // Exceed maximum amplification *before* (default) threshold: should work. 2215 void *const ptr = expat_malloc(parser, 1000, -1); 2216 assert_true(ptr != NULL); 2217 expat_free(parser, ptr, -1); 2218 2219 // Exceed maximum amplification *after* threshold: should be rejected. 2220 assert_true(XML_SetAllocTrackerActivationThreshold(parser, 999) == XML_TRUE); 2221 assert_true(expat_malloc(parser, 1000, -1) == NULL); 2222 #endif 2223 2224 XML_ParserFree(parser); 2225 } 2226 END_TEST 2227 2228 START_TEST(test_alloc_tracker_getbuffer_unlimited) { 2229 XML_Parser parser = XML_ParserCreate(NULL); 2230 2231 #if XML_GE == 1 2232 // Artificially lower threshold 2233 assert_true(XML_SetAllocTrackerActivationThreshold(parser, 0) == XML_TRUE); 2234 2235 // Self-test: Prove that threshold is as rejecting as expected 2236 assert_true(expat_malloc(parser, 1000, -1) == NULL); 2237 #endif 2238 // XML_GetBuffer should be allowed to pass, though 2239 assert_true(XML_GetBuffer(parser, 1000) != NULL); 2240 2241 XML_ParserFree(parser); 2242 } 2243 END_TEST 2244 2245 START_TEST(test_alloc_tracker_api) { 2246 XML_Parser parserWithoutParent = XML_ParserCreate(NULL); 2247 XML_Parser parserWithParent = XML_ExternalEntityParserCreate( 2248 parserWithoutParent, XCS("entity123"), NULL); 2249 if (parserWithoutParent == NULL) 2250 fail("parserWithoutParent is NULL"); 2251 if (parserWithParent == NULL) 2252 fail("parserWithParent is NULL"); 2253 2254 #if XML_GE == 1 2255 // XML_SetAllocTrackerMaximumAmplification, error cases 2256 if (XML_SetAllocTrackerMaximumAmplification(NULL, 123.0f) == XML_TRUE) 2257 fail("Call with NULL parser is NOT supposed to succeed"); 2258 if (XML_SetAllocTrackerMaximumAmplification(parserWithParent, 123.0f) 2259 == XML_TRUE) 2260 fail("Call with non-root parser is NOT supposed to succeed"); 2261 if (XML_SetAllocTrackerMaximumAmplification(parserWithoutParent, NAN) 2262 == XML_TRUE) 2263 fail("Call with NaN limit is NOT supposed to succeed"); 2264 if (XML_SetAllocTrackerMaximumAmplification(parserWithoutParent, -1.0f) 2265 == XML_TRUE) 2266 fail("Call with negative limit is NOT supposed to succeed"); 2267 if (XML_SetAllocTrackerMaximumAmplification(parserWithoutParent, 0.9f) 2268 == XML_TRUE) 2269 fail("Call with positive limit <1.0 is NOT supposed to succeed"); 2270 2271 // XML_SetAllocTrackerMaximumAmplification, success cases 2272 if (XML_SetAllocTrackerMaximumAmplification(parserWithoutParent, 1.0f) 2273 == XML_FALSE) 2274 fail("Call with positive limit >=1.0 is supposed to succeed"); 2275 if (XML_SetAllocTrackerMaximumAmplification(parserWithoutParent, 123456.789f) 2276 == XML_FALSE) 2277 fail("Call with positive limit >=1.0 is supposed to succeed"); 2278 if (XML_SetAllocTrackerMaximumAmplification(parserWithoutParent, INFINITY) 2279 == XML_FALSE) 2280 fail("Call with positive limit >=1.0 is supposed to succeed"); 2281 2282 // XML_SetAllocTrackerActivationThreshold, error cases 2283 if (XML_SetAllocTrackerActivationThreshold(NULL, 123) == XML_TRUE) 2284 fail("Call with NULL parser is NOT supposed to succeed"); 2285 if (XML_SetAllocTrackerActivationThreshold(parserWithParent, 123) == XML_TRUE) 2286 fail("Call with non-root parser is NOT supposed to succeed"); 2287 2288 // XML_SetAllocTrackerActivationThreshold, success cases 2289 if (XML_SetAllocTrackerActivationThreshold(parserWithoutParent, 123) 2290 == XML_FALSE) 2291 fail("Call with non-NULL parentless parser is supposed to succeed"); 2292 #endif // XML_GE == 1 2293 2294 XML_ParserFree(parserWithParent); 2295 XML_ParserFree(parserWithoutParent); 2296 } 2297 END_TEST 2298 2299 START_TEST(test_alloc_tracker_api_float_round_trip) { 2300 const float values[] = {1.0f, 1.1f, INFINITY}; 2301 2302 for (size_t i = 0; i < sizeof(values) / sizeof(values[0]); i++) { 2303 set_subtest("float %f", (double)i); 2304 const float wanted = values[i]; 2305 2306 XML_Parser parser = XML_ParserCreate(NULL); 2307 assert_true(parser != NULL); 2308 2309 // Self-Test: Original value not already at target value 2310 double actual = 123.456; 2311 assert_true((float)actual != wanted); 2312 #if XML_GE == 1 2313 assert_true( 2314 XML_GetPropertyDouble( 2315 parser, XML_PROP_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION, &actual) 2316 == XML_PROP_ERROR_NONE); 2317 assert_true((float)actual != wanted); // Self-Test 2318 2319 // Test: Target value applied successfully 2320 assert_true(XML_SetAllocTrackerMaximumAmplification(parser, wanted) 2321 == XML_TRUE); 2322 assert_true( 2323 XML_GetPropertyDouble( 2324 parser, XML_PROP_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION, &actual) 2325 == XML_PROP_ERROR_NONE); 2326 assert_true((float)actual == wanted); 2327 #endif // XML_GE == 1 2328 XML_ParserFree(parser); 2329 } 2330 } 2331 END_TEST 2332 2333 START_TEST(test_mem_api_cycle) { 2334 XML_Parser parser = XML_ParserCreate(NULL); 2335 2336 void *ptr = XML_MemMalloc(parser, 10); 2337 2338 assert_true(ptr != NULL); 2339 memset(ptr, 'x', 10); // assert writability, with ASan in mind 2340 2341 ptr = XML_MemRealloc(parser, ptr, 20); 2342 2343 assert_true(ptr != NULL); 2344 memset(ptr, 'y', 20); // assert writability, with ASan in mind 2345 2346 XML_MemFree(parser, ptr); 2347 2348 XML_ParserFree(parser); 2349 } 2350 END_TEST 2351 2352 START_TEST(test_mem_api_unlimited) { 2353 XML_Parser parser = XML_ParserCreate(NULL); 2354 2355 #if XML_GE == 1 2356 assert_true(XML_SetAllocTrackerActivationThreshold(parser, 0) == XML_TRUE); 2357 #endif 2358 2359 void *ptr = XML_MemMalloc(parser, 1000); 2360 2361 assert_true(ptr != NULL); 2362 2363 ptr = XML_MemRealloc(parser, ptr, 2000); 2364 2365 assert_true(ptr != NULL); 2366 2367 XML_MemFree(parser, ptr); 2368 2369 XML_ParserFree(parser); 2370 } 2371 END_TEST 2372 2373 void 2374 make_alloc_test_case(Suite *s) { 2375 TCase *tc_alloc = tcase_create("allocation tests"); 2376 2377 suite_add_tcase(s, tc_alloc); 2378 tcase_add_checked_fixture(tc_alloc, alloc_setup, alloc_teardown); 2379 2380 tcase_add_test(tc_alloc, test_alloc_parse_xdecl); 2381 tcase_add_test(tc_alloc, test_alloc_parse_xdecl_2); 2382 tcase_add_test(tc_alloc, test_alloc_parse_pi); 2383 tcase_add_test(tc_alloc, test_alloc_parse_pi_2); 2384 tcase_add_test(tc_alloc, test_alloc_parse_pi_3); 2385 tcase_add_test(tc_alloc, test_alloc_parse_comment); 2386 tcase_add_test(tc_alloc, test_alloc_parse_comment_2); 2387 tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_create_external_parser); 2388 tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_run_external_parser); 2389 tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_dtd_copy_default_atts); 2390 tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_external_entity); 2391 tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_ext_entity_set_encoding); 2392 tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_internal_entity); 2393 tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_parameter_entity); 2394 tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_dtd_default_handling); 2395 tcase_add_test(tc_alloc, test_alloc_explicit_encoding); 2396 tcase_add_test(tc_alloc, test_alloc_reset_encoding); 2397 tcase_add_test(tc_alloc, test_alloc_set_base); 2398 tcase_add_test(tc_alloc, test_alloc_realloc_buffer); 2399 tcase_add_test__if_xml_ge(tc_alloc, test_alloc_ext_entity_realloc_buffer); 2400 tcase_add_test(tc_alloc, test_alloc_realloc_many_attributes); 2401 tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_public_entity_value); 2402 tcase_add_test__ifdef_xml_dtd(tc_alloc, 2403 test_alloc_realloc_subst_public_entity_value); 2404 tcase_add_test(tc_alloc, test_alloc_parse_public_doctype); 2405 tcase_add_test(tc_alloc, test_alloc_parse_public_doctype_long_name); 2406 tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_set_foreign_dtd); 2407 tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_attribute_enum_value); 2408 tcase_add_test__ifdef_xml_dtd(tc_alloc, 2409 test_alloc_realloc_attribute_enum_value); 2410 tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_realloc_implied_attribute); 2411 tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_realloc_default_attribute); 2412 tcase_add_test__if_xml_ge(tc_alloc, test_alloc_notation); 2413 tcase_add_test(tc_alloc, test_alloc_public_notation); 2414 tcase_add_test(tc_alloc, test_alloc_system_notation); 2415 tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_nested_groups); 2416 tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_realloc_nested_groups); 2417 tcase_add_test(tc_alloc, test_alloc_large_group); 2418 tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_realloc_group_choice); 2419 tcase_add_test(tc_alloc, test_alloc_pi_in_epilog); 2420 tcase_add_test(tc_alloc, test_alloc_comment_in_epilog); 2421 tcase_add_test__ifdef_xml_dtd(tc_alloc, 2422 test_alloc_realloc_long_attribute_value); 2423 tcase_add_test(tc_alloc, test_alloc_attribute_whitespace); 2424 tcase_add_test(tc_alloc, test_alloc_attribute_predefined_entity); 2425 tcase_add_test(tc_alloc, test_alloc_long_attr_default_with_char_ref); 2426 tcase_add_test__if_xml_ge(tc_alloc, test_alloc_long_attr_value); 2427 tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_nested_entities); 2428 tcase_add_test__ifdef_xml_dtd(tc_alloc, 2429 test_alloc_realloc_param_entity_newline); 2430 tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_realloc_ce_extends_pe); 2431 tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_realloc_attributes); 2432 tcase_add_test(tc_alloc, test_alloc_long_doc_name); 2433 tcase_add_test__if_xml_ge(tc_alloc, test_alloc_long_base); 2434 tcase_add_test__if_xml_ge(tc_alloc, test_alloc_long_public_id); 2435 tcase_add_test__if_xml_ge(tc_alloc, test_alloc_long_entity_value); 2436 tcase_add_test__if_xml_ge(tc_alloc, test_alloc_long_notation); 2437 2438 tcase_add_test__ifdef_xml_dtd( 2439 tc_alloc, test_alloc_reset_after_external_entity_parser_create_fail); 2440 2441 tcase_add_test__if_xml_ge(tc_alloc, test_alloc_tracker_size_recorded); 2442 tcase_add_test__if_xml_ge(tc_alloc, test_alloc_tracker_pointer_alignment); 2443 tcase_add_test__if_xml_ge(tc_alloc, test_alloc_tracker_maximum_amplification); 2444 tcase_add_test__if_xml_ge(tc_alloc, test_alloc_tracker_threshold); 2445 tcase_add_test__if_xml_ge(tc_alloc, test_alloc_tracker_getbuffer_unlimited); 2446 tcase_add_test__if_xml_ge(tc_alloc, test_alloc_tracker_api); 2447 tcase_add_test__if_xml_ge(tc_alloc, test_alloc_tracker_api_float_round_trip); 2448 2449 tcase_add_test(tc_alloc, test_mem_api_cycle); 2450 tcase_add_test__if_xml_ge(tc_alloc, test_mem_api_unlimited); 2451 } 2452