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