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