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