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