1 /* Run the Expat test suite
2 __ __ _
3 ___\ \/ /_ __ __ _| |_
4 / _ \\ /| '_ \ / _` | __|
5 | __// \| |_) | (_| | |_
6 \___/_/\_\ .__/ \__,_|\__|
7 |_| XML parser
8
9 Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
10 Copyright (c) 2000-2017 Expat development team
11 Licensed under the MIT license:
12
13 Permission is hereby granted, free of charge, to any person obtaining
14 a copy of this software and associated documentation files (the
15 "Software"), to deal in the Software without restriction, including
16 without limitation the rights to use, copy, modify, merge, publish,
17 distribute, sublicense, and/or sell copies of the Software, and to permit
18 persons to whom the Software is furnished to do so, subject to the
19 following conditions:
20
21 The above copyright notice and this permission notice shall be included
22 in all copies or substantial portions of the Software.
23
24 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
27 NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
28 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
29 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
30 USE OR OTHER DEALINGS IN THE SOFTWARE.
31 */
32
33 #if defined(NDEBUG)
34 # undef NDEBUG /* because test suite relies on assert(...) at the moment */
35 #endif
36
37 #ifdef HAVE_EXPAT_CONFIG_H
38 # include <expat_config.h>
39 #endif
40
41 #include <assert.h>
42 #include <stdlib.h>
43 #include <stdio.h>
44 #include <string.h>
45 #include <stddef.h> /* ptrdiff_t */
46 #include <ctype.h>
47 #include <limits.h>
48
49
50 #if defined(_WIN32) && defined(_MSC_VER) && (_MSC_VER < 1600)
51 /* For vs2003/7.1 up to vs2008/9.0; _MSC_VER 1600 is vs2010/10.0 */
52 #if defined(_WIN64)
53 typedef __int64 intptr_t;
54 #else
55 typedef __int32 intptr_t;
56 #endif
57 typedef unsigned __int64 uint64_t;
58 #else
59 #include <stdint.h> /* intptr_t uint64_t */
60 #endif
61
62
63 #if ! defined(__cplusplus)
64 # if defined(_MSC_VER) && (_MSC_VER <= 1700)
65 /* for vs2012/11.0/1700 and earlier Visual Studio compilers */
66 # define bool int
67 # define false 0
68 # define true 1
69 # else
70 # include <stdbool.h>
71 # endif
72 #endif
73
74
75 #include "expat.h"
76 #include "chardata.h"
77 #include "structdata.h"
78 #include "internal.h" /* for UNUSED_P only */
79 #include "minicheck.h"
80 #include "memcheck.h"
81 #include "siphash.h"
82 #include "ascii.h" /* for ASCII_xxx */
83
84 #ifdef XML_LARGE_SIZE
85 # define XML_FMT_INT_MOD "ll"
86 #else
87 # define XML_FMT_INT_MOD "l"
88 #endif
89
90 #ifdef XML_UNICODE_WCHAR_T
91 # define XML_FMT_CHAR "lc"
92 # define XML_FMT_STR "ls"
93 # include <wchar.h>
94 # define xcstrlen(s) wcslen(s)
95 # define xcstrcmp(s, t) wcscmp((s), (t))
96 # define xcstrncmp(s, t, n) wcsncmp((s), (t), (n))
97 # define XCS(s) _XCS(s)
98 # define _XCS(s) L ## s
99 #else
100 # ifdef XML_UNICODE
101 # error "No support for UTF-16 character without wchar_t in tests"
102 # else
103 # define XML_FMT_CHAR "c"
104 # define XML_FMT_STR "s"
105 # define xcstrlen(s) strlen(s)
106 # define xcstrcmp(s, t) strcmp((s), (t))
107 # define xcstrncmp(s, t, n) strncmp((s), (t), (n))
108 # define XCS(s) s
109 # endif /* XML_UNICODE */
110 #endif /* XML_UNICODE_WCHAR_T */
111
112
113 static XML_Parser parser = NULL;
114
115
116 static void
basic_setup(void)117 basic_setup(void)
118 {
119 parser = XML_ParserCreate(NULL);
120 if (parser == NULL)
121 fail("Parser not created.");
122 }
123
124 static void
basic_teardown(void)125 basic_teardown(void)
126 {
127 if (parser != NULL) {
128 XML_ParserFree(parser);
129 parser = NULL;
130 }
131 }
132
133 /* Generate a failure using the parser state to create an error message;
134 this should be used when the parser reports an error we weren't
135 expecting.
136 */
137 static void
_xml_failure(XML_Parser parser,const char * file,int line)138 _xml_failure(XML_Parser parser, const char *file, int line)
139 {
140 char buffer[1024];
141 enum XML_Error err = XML_GetErrorCode(parser);
142 sprintf(buffer,
143 " %d: %" XML_FMT_STR " (line %"
144 XML_FMT_INT_MOD "u, offset %"
145 XML_FMT_INT_MOD "u)\n reported from %s, line %d\n",
146 err,
147 XML_ErrorString(err),
148 XML_GetCurrentLineNumber(parser),
149 XML_GetCurrentColumnNumber(parser),
150 file, line);
151 _fail_unless(0, file, line, buffer);
152 }
153
154 static enum XML_Status
_XML_Parse_SINGLE_BYTES(XML_Parser parser,const char * s,int len,int isFinal)155 _XML_Parse_SINGLE_BYTES(XML_Parser parser, const char *s, int len, int isFinal)
156 {
157 enum XML_Status res = XML_STATUS_ERROR;
158 int offset = 0;
159
160 if (len == 0) {
161 return XML_Parse(parser, s, len, isFinal);
162 }
163
164 for (; offset < len; offset++) {
165 const int innerIsFinal = (offset == len - 1) && isFinal;
166 const char c = s[offset]; /* to help out-of-bounds detection */
167 res = XML_Parse(parser, &c, sizeof(char), innerIsFinal);
168 if (res != XML_STATUS_OK) {
169 return res;
170 }
171 }
172 return res;
173 }
174
175 #define xml_failure(parser) _xml_failure((parser), __FILE__, __LINE__)
176
177 static void
_expect_failure(const char * text,enum XML_Error errorCode,const char * errorMessage,const char * file,int lineno)178 _expect_failure(const char *text, enum XML_Error errorCode, const char *errorMessage,
179 const char *file, int lineno)
180 {
181 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_OK)
182 /* Hackish use of _fail_unless() macro, but let's us report
183 the right filename and line number. */
184 _fail_unless(0, file, lineno, errorMessage);
185 if (XML_GetErrorCode(parser) != errorCode)
186 _xml_failure(parser, file, lineno);
187 }
188
189 #define expect_failure(text, errorCode, errorMessage) \
190 _expect_failure((text), (errorCode), (errorMessage), \
191 __FILE__, __LINE__)
192
193 /* Dummy handlers for when we need to set a handler to tickle a bug,
194 but it doesn't need to do anything.
195 */
196 static unsigned long dummy_handler_flags = 0;
197
198 #define DUMMY_START_DOCTYPE_HANDLER_FLAG (1UL << 0)
199 #define DUMMY_END_DOCTYPE_HANDLER_FLAG (1UL << 1)
200 #define DUMMY_ENTITY_DECL_HANDLER_FLAG (1UL << 2)
201 #define DUMMY_NOTATION_DECL_HANDLER_FLAG (1UL << 3)
202 #define DUMMY_ELEMENT_DECL_HANDLER_FLAG (1UL << 4)
203 #define DUMMY_ATTLIST_DECL_HANDLER_FLAG (1UL << 5)
204 #define DUMMY_COMMENT_HANDLER_FLAG (1UL << 6)
205 #define DUMMY_PI_HANDLER_FLAG (1UL << 7)
206 #define DUMMY_START_ELEMENT_HANDLER_FLAG (1UL << 8)
207 #define DUMMY_START_CDATA_HANDLER_FLAG (1UL << 9)
208 #define DUMMY_END_CDATA_HANDLER_FLAG (1UL << 10)
209 #define DUMMY_UNPARSED_ENTITY_DECL_HANDLER_FLAG (1UL << 11)
210 #define DUMMY_START_NS_DECL_HANDLER_FLAG (1UL << 12)
211 #define DUMMY_END_NS_DECL_HANDLER_FLAG (1UL << 13)
212 #define DUMMY_START_DOCTYPE_DECL_HANDLER_FLAG (1UL << 14)
213 #define DUMMY_END_DOCTYPE_DECL_HANDLER_FLAG (1UL << 15)
214 #define DUMMY_SKIP_HANDLER_FLAG (1UL << 16)
215 #define DUMMY_DEFAULT_HANDLER_FLAG (1UL << 17)
216
217
218 static void XMLCALL
dummy_xdecl_handler(void * UNUSED_P (userData),const XML_Char * UNUSED_P (version),const XML_Char * UNUSED_P (encoding),int UNUSED_P (standalone))219 dummy_xdecl_handler(void *UNUSED_P(userData),
220 const XML_Char *UNUSED_P(version),
221 const XML_Char *UNUSED_P(encoding),
222 int UNUSED_P(standalone))
223 {}
224
225 static void XMLCALL
dummy_start_doctype_handler(void * UNUSED_P (userData),const XML_Char * UNUSED_P (doctypeName),const XML_Char * UNUSED_P (sysid),const XML_Char * UNUSED_P (pubid),int UNUSED_P (has_internal_subset))226 dummy_start_doctype_handler(void *UNUSED_P(userData),
227 const XML_Char *UNUSED_P(doctypeName),
228 const XML_Char *UNUSED_P(sysid),
229 const XML_Char *UNUSED_P(pubid),
230 int UNUSED_P(has_internal_subset))
231 {
232 dummy_handler_flags |= DUMMY_START_DOCTYPE_HANDLER_FLAG;
233 }
234
235 static void XMLCALL
dummy_end_doctype_handler(void * UNUSED_P (userData))236 dummy_end_doctype_handler(void *UNUSED_P(userData))
237 {
238 dummy_handler_flags |= DUMMY_END_DOCTYPE_HANDLER_FLAG;
239 }
240
241 static void XMLCALL
dummy_entity_decl_handler(void * UNUSED_P (userData),const XML_Char * UNUSED_P (entityName),int UNUSED_P (is_parameter_entity),const XML_Char * UNUSED_P (value),int UNUSED_P (value_length),const XML_Char * UNUSED_P (base),const XML_Char * UNUSED_P (systemId),const XML_Char * UNUSED_P (publicId),const XML_Char * UNUSED_P (notationName))242 dummy_entity_decl_handler(void *UNUSED_P(userData),
243 const XML_Char *UNUSED_P(entityName),
244 int UNUSED_P(is_parameter_entity),
245 const XML_Char *UNUSED_P(value),
246 int UNUSED_P(value_length),
247 const XML_Char *UNUSED_P(base),
248 const XML_Char *UNUSED_P(systemId),
249 const XML_Char *UNUSED_P(publicId),
250 const XML_Char *UNUSED_P(notationName))
251 {
252 dummy_handler_flags |= DUMMY_ENTITY_DECL_HANDLER_FLAG;
253 }
254
255 static void XMLCALL
dummy_notation_decl_handler(void * UNUSED_P (userData),const XML_Char * UNUSED_P (notationName),const XML_Char * UNUSED_P (base),const XML_Char * UNUSED_P (systemId),const XML_Char * UNUSED_P (publicId))256 dummy_notation_decl_handler(void *UNUSED_P(userData),
257 const XML_Char *UNUSED_P(notationName),
258 const XML_Char *UNUSED_P(base),
259 const XML_Char *UNUSED_P(systemId),
260 const XML_Char *UNUSED_P(publicId))
261 {
262 dummy_handler_flags |= DUMMY_NOTATION_DECL_HANDLER_FLAG;
263 }
264
265 static void XMLCALL
dummy_element_decl_handler(void * UNUSED_P (userData),const XML_Char * UNUSED_P (name),XML_Content * model)266 dummy_element_decl_handler(void *UNUSED_P(userData),
267 const XML_Char *UNUSED_P(name),
268 XML_Content *model)
269 {
270 /* The content model must be freed by the handler. Unfortunately
271 * we cannot pass the parser as the userData because this is used
272 * with other handlers that require other userData.
273 */
274 XML_FreeContentModel(parser, model);
275 dummy_handler_flags |= DUMMY_ELEMENT_DECL_HANDLER_FLAG;
276 }
277
278 static void XMLCALL
dummy_attlist_decl_handler(void * UNUSED_P (userData),const XML_Char * UNUSED_P (elname),const XML_Char * UNUSED_P (attname),const XML_Char * UNUSED_P (att_type),const XML_Char * UNUSED_P (dflt),int UNUSED_P (isrequired))279 dummy_attlist_decl_handler(void *UNUSED_P(userData),
280 const XML_Char *UNUSED_P(elname),
281 const XML_Char *UNUSED_P(attname),
282 const XML_Char *UNUSED_P(att_type),
283 const XML_Char *UNUSED_P(dflt),
284 int UNUSED_P(isrequired))
285 {
286 dummy_handler_flags |= DUMMY_ATTLIST_DECL_HANDLER_FLAG;
287 }
288
289 static void XMLCALL
dummy_comment_handler(void * UNUSED_P (userData),const XML_Char * UNUSED_P (data))290 dummy_comment_handler(void *UNUSED_P(userData), const XML_Char *UNUSED_P(data))
291 {
292 dummy_handler_flags |= DUMMY_COMMENT_HANDLER_FLAG;
293 }
294
295 static void XMLCALL
dummy_pi_handler(void * UNUSED_P (userData),const XML_Char * UNUSED_P (target),const XML_Char * UNUSED_P (data))296 dummy_pi_handler(void *UNUSED_P(userData), const XML_Char *UNUSED_P(target), const XML_Char *UNUSED_P(data))
297 {
298 dummy_handler_flags |= DUMMY_PI_HANDLER_FLAG;
299 }
300
301 static void XMLCALL
dummy_start_element(void * UNUSED_P (userData),const XML_Char * UNUSED_P (name),const XML_Char ** UNUSED_P (atts))302 dummy_start_element(void *UNUSED_P(userData),
303 const XML_Char *UNUSED_P(name), const XML_Char **UNUSED_P(atts))
304 {
305 dummy_handler_flags |= DUMMY_START_ELEMENT_HANDLER_FLAG;
306 }
307
308 static void XMLCALL
dummy_end_element(void * UNUSED_P (userData),const XML_Char * UNUSED_P (name))309 dummy_end_element(void *UNUSED_P(userData), const XML_Char *UNUSED_P(name))
310 {}
311
312 static void XMLCALL
dummy_start_cdata_handler(void * UNUSED_P (userData))313 dummy_start_cdata_handler(void *UNUSED_P(userData))
314 {
315 dummy_handler_flags |= DUMMY_START_CDATA_HANDLER_FLAG;
316 }
317
318 static void XMLCALL
dummy_end_cdata_handler(void * UNUSED_P (userData))319 dummy_end_cdata_handler(void *UNUSED_P(userData))
320 {
321 dummy_handler_flags |= DUMMY_END_CDATA_HANDLER_FLAG;
322 }
323
324 static void XMLCALL
dummy_cdata_handler(void * UNUSED_P (userData),const XML_Char * UNUSED_P (s),int UNUSED_P (len))325 dummy_cdata_handler(void *UNUSED_P(userData),
326 const XML_Char *UNUSED_P(s),
327 int UNUSED_P(len))
328 {}
329
330 static void XMLCALL
dummy_start_namespace_decl_handler(void * UNUSED_P (userData),const XML_Char * UNUSED_P (prefix),const XML_Char * UNUSED_P (uri))331 dummy_start_namespace_decl_handler(void *UNUSED_P(userData),
332 const XML_Char *UNUSED_P(prefix),
333 const XML_Char *UNUSED_P(uri))
334 {
335 dummy_handler_flags |= DUMMY_START_NS_DECL_HANDLER_FLAG;
336 }
337
338 static void XMLCALL
dummy_end_namespace_decl_handler(void * UNUSED_P (userData),const XML_Char * UNUSED_P (prefix))339 dummy_end_namespace_decl_handler(void *UNUSED_P(userData),
340 const XML_Char *UNUSED_P(prefix))
341 {
342 dummy_handler_flags |= DUMMY_END_NS_DECL_HANDLER_FLAG;
343 }
344
345 /* This handler is obsolete, but while the code exists we should
346 * ensure that dealing with the handler is covered by tests.
347 */
348 static void XMLCALL
dummy_unparsed_entity_decl_handler(void * UNUSED_P (userData),const XML_Char * UNUSED_P (entityName),const XML_Char * UNUSED_P (base),const XML_Char * UNUSED_P (systemId),const XML_Char * UNUSED_P (publicId),const XML_Char * UNUSED_P (notationName))349 dummy_unparsed_entity_decl_handler(void *UNUSED_P(userData),
350 const XML_Char *UNUSED_P(entityName),
351 const XML_Char *UNUSED_P(base),
352 const XML_Char *UNUSED_P(systemId),
353 const XML_Char *UNUSED_P(publicId),
354 const XML_Char *UNUSED_P(notationName))
355 {
356 dummy_handler_flags |= DUMMY_UNPARSED_ENTITY_DECL_HANDLER_FLAG;
357 }
358
359 static void XMLCALL
dummy_default_handler(void * UNUSED_P (userData),const XML_Char * UNUSED_P (s),int UNUSED_P (len))360 dummy_default_handler(void *UNUSED_P(userData),
361 const XML_Char *UNUSED_P(s),
362 int UNUSED_P(len))
363 {}
364
365 static void XMLCALL
dummy_start_doctype_decl_handler(void * UNUSED_P (userData),const XML_Char * UNUSED_P (doctypeName),const XML_Char * UNUSED_P (sysid),const XML_Char * UNUSED_P (pubid),int UNUSED_P (has_internal_subset))366 dummy_start_doctype_decl_handler(void *UNUSED_P(userData),
367 const XML_Char *UNUSED_P(doctypeName),
368 const XML_Char *UNUSED_P(sysid),
369 const XML_Char *UNUSED_P(pubid),
370 int UNUSED_P(has_internal_subset))
371 {
372 dummy_handler_flags |= DUMMY_START_DOCTYPE_DECL_HANDLER_FLAG;
373 }
374
375 static void XMLCALL
dummy_end_doctype_decl_handler(void * UNUSED_P (userData))376 dummy_end_doctype_decl_handler(void *UNUSED_P(userData))
377 {
378 dummy_handler_flags |= DUMMY_END_DOCTYPE_DECL_HANDLER_FLAG;
379 }
380
381 static void XMLCALL
dummy_skip_handler(void * UNUSED_P (userData),const XML_Char * UNUSED_P (entityName),int UNUSED_P (is_parameter_entity))382 dummy_skip_handler(void *UNUSED_P(userData),
383 const XML_Char *UNUSED_P(entityName),
384 int UNUSED_P(is_parameter_entity))
385 {
386 dummy_handler_flags |= DUMMY_SKIP_HANDLER_FLAG;
387 }
388
389 /* Useful external entity handler */
390 typedef struct ExtOption {
391 const XML_Char *system_id;
392 const char *parse_text;
393 } ExtOption;
394
395 static int XMLCALL
external_entity_optioner(XML_Parser parser,const XML_Char * context,const XML_Char * UNUSED_P (base),const XML_Char * systemId,const XML_Char * UNUSED_P (publicId))396 external_entity_optioner(XML_Parser parser,
397 const XML_Char *context,
398 const XML_Char *UNUSED_P(base),
399 const XML_Char *systemId,
400 const XML_Char *UNUSED_P(publicId))
401 {
402 ExtOption *options = (ExtOption *)XML_GetUserData(parser);
403 XML_Parser ext_parser;
404
405 while (options->parse_text != NULL) {
406 if (!xcstrcmp(systemId, options->system_id)) {
407 enum XML_Status rc;
408 ext_parser =
409 XML_ExternalEntityParserCreate(parser, context, NULL);
410 if (ext_parser == NULL)
411 return XML_STATUS_ERROR;
412 rc = _XML_Parse_SINGLE_BYTES(ext_parser, options->parse_text,
413 (int)strlen(options->parse_text),
414 XML_TRUE);
415 XML_ParserFree(ext_parser);
416 return rc;
417 }
418 options++;
419 }
420 fail("No suitable option found");
421 return XML_STATUS_ERROR;
422 }
423
424 /*
425 * Parameter entity evaluation support.
426 */
427 #define ENTITY_MATCH_FAIL (-1)
428 #define ENTITY_MATCH_NOT_FOUND (0)
429 #define ENTITY_MATCH_SUCCESS (1)
430 static const XML_Char *entity_name_to_match = NULL;
431 static const XML_Char *entity_value_to_match = NULL;
432 static int entity_match_flag = ENTITY_MATCH_NOT_FOUND;
433
434 static void XMLCALL
param_entity_match_handler(void * UNUSED_P (userData),const XML_Char * entityName,int is_parameter_entity,const XML_Char * value,int value_length,const XML_Char * UNUSED_P (base),const XML_Char * UNUSED_P (systemId),const XML_Char * UNUSED_P (publicId),const XML_Char * UNUSED_P (notationName))435 param_entity_match_handler(void *UNUSED_P(userData),
436 const XML_Char *entityName,
437 int is_parameter_entity,
438 const XML_Char *value,
439 int value_length,
440 const XML_Char *UNUSED_P(base),
441 const XML_Char *UNUSED_P(systemId),
442 const XML_Char *UNUSED_P(publicId),
443 const XML_Char *UNUSED_P(notationName))
444 {
445 if (!is_parameter_entity ||
446 entity_name_to_match == NULL ||
447 entity_value_to_match == NULL) {
448 return;
449 }
450 if (!xcstrcmp(entityName, entity_name_to_match)) {
451 /* The cast here is safe because we control the horizontal and
452 * the vertical, and we therefore know our strings are never
453 * going to overflow an int.
454 */
455 if (value_length != (int)xcstrlen(entity_value_to_match) ||
456 xcstrncmp(value, entity_value_to_match, value_length)) {
457 entity_match_flag = ENTITY_MATCH_FAIL;
458 } else {
459 entity_match_flag = ENTITY_MATCH_SUCCESS;
460 }
461 }
462 /* Else leave the match flag alone */
463 }
464
465 /*
466 * Character & encoding tests.
467 */
468
START_TEST(test_nul_byte)469 START_TEST(test_nul_byte)
470 {
471 char text[] = "<doc>\0</doc>";
472
473 /* test that a NUL byte (in US-ASCII data) is an error */
474 if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text) - 1, XML_TRUE) == XML_STATUS_OK)
475 fail("Parser did not report error on NUL-byte.");
476 if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_TOKEN)
477 xml_failure(parser);
478 }
479 END_TEST
480
481
START_TEST(test_u0000_char)482 START_TEST(test_u0000_char)
483 {
484 /* test that a NUL byte (in US-ASCII data) is an error */
485 expect_failure("<doc>�</doc>",
486 XML_ERROR_BAD_CHAR_REF,
487 "Parser did not report error on NUL-byte.");
488 }
489 END_TEST
490
START_TEST(test_siphash_self)491 START_TEST(test_siphash_self)
492 {
493 if (! sip24_valid())
494 fail("SipHash self-test failed");
495 }
496 END_TEST
497
START_TEST(test_siphash_spec)498 START_TEST(test_siphash_spec)
499 {
500 /* https://131002.net/siphash/siphash.pdf (page 19, "Test values") */
501 const char message[] = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09"
502 "\x0a\x0b\x0c\x0d\x0e";
503 const size_t len = sizeof(message) - 1;
504 const uint64_t expected = _SIP_ULL(0xa129ca61U, 0x49be45e5U);
505 struct siphash state;
506 struct sipkey key;
507
508 sip_tokey(&key,
509 "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09"
510 "\x0a\x0b\x0c\x0d\x0e\x0f");
511 sip24_init(&state, &key);
512
513 /* Cover spread across calls */
514 sip24_update(&state, message, 4);
515 sip24_update(&state, message + 4, len - 4);
516
517 /* Cover null length */
518 sip24_update(&state, message, 0);
519
520 if (sip24_final(&state) != expected)
521 fail("sip24_final failed spec test\n");
522
523 /* Cover wrapper */
524 if (siphash24(message, len, &key) != expected)
525 fail("siphash24 failed spec test\n");
526 }
527 END_TEST
528
START_TEST(test_bom_utf8)529 START_TEST(test_bom_utf8)
530 {
531 /* This test is really just making sure we don't core on a UTF-8 BOM. */
532 const char *text = "\357\273\277<e/>";
533
534 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR)
535 xml_failure(parser);
536 }
537 END_TEST
538
START_TEST(test_bom_utf16_be)539 START_TEST(test_bom_utf16_be)
540 {
541 char text[] = "\376\377\0<\0e\0/\0>";
542
543 if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text)-1, XML_TRUE) == XML_STATUS_ERROR)
544 xml_failure(parser);
545 }
546 END_TEST
547
START_TEST(test_bom_utf16_le)548 START_TEST(test_bom_utf16_le)
549 {
550 char text[] = "\377\376<\0e\0/\0>\0";
551
552 if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text)-1, XML_TRUE) == XML_STATUS_ERROR)
553 xml_failure(parser);
554 }
555 END_TEST
556
557 /* Parse whole buffer at once to exercise a different code path */
START_TEST(test_nobom_utf16_le)558 START_TEST(test_nobom_utf16_le)
559 {
560 char text[] = " \0<\0e\0/\0>\0";
561
562 if (XML_Parse(parser, text, sizeof(text)-1, XML_TRUE) == XML_STATUS_ERROR)
563 xml_failure(parser);
564 }
565 END_TEST
566
567 static void XMLCALL
accumulate_characters(void * userData,const XML_Char * s,int len)568 accumulate_characters(void *userData, const XML_Char *s, int len)
569 {
570 CharData_AppendXMLChars((CharData *)userData, s, len);
571 }
572
573 static void XMLCALL
accumulate_attribute(void * userData,const XML_Char * UNUSED_P (name),const XML_Char ** atts)574 accumulate_attribute(void *userData, const XML_Char *UNUSED_P(name),
575 const XML_Char **atts)
576 {
577 CharData *storage = (CharData *)userData;
578
579 /* Check there are attributes to deal with */
580 if (atts == NULL)
581 return;
582
583 while (storage->count < 0 && atts[0] != NULL) {
584 /* "accumulate" the value of the first attribute we see */
585 CharData_AppendXMLChars(storage, atts[1], -1);
586 atts += 2;
587 }
588 }
589
590
591 static void
_run_character_check(const char * text,const XML_Char * expected,const char * file,int line)592 _run_character_check(const char *text, const XML_Char *expected,
593 const char *file, int line)
594 {
595 CharData storage;
596
597 CharData_Init(&storage);
598 XML_SetUserData(parser, &storage);
599 XML_SetCharacterDataHandler(parser, accumulate_characters);
600 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR)
601 _xml_failure(parser, file, line);
602 CharData_CheckXMLChars(&storage, expected);
603 }
604
605 #define run_character_check(text, expected) \
606 _run_character_check(text, expected, __FILE__, __LINE__)
607
608 static void
_run_attribute_check(const char * text,const XML_Char * expected,const char * file,int line)609 _run_attribute_check(const char *text, const XML_Char *expected,
610 const char *file, int line)
611 {
612 CharData storage;
613
614 CharData_Init(&storage);
615 XML_SetUserData(parser, &storage);
616 XML_SetStartElementHandler(parser, accumulate_attribute);
617 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR)
618 _xml_failure(parser, file, line);
619 CharData_CheckXMLChars(&storage, expected);
620 }
621
622 #define run_attribute_check(text, expected) \
623 _run_attribute_check(text, expected, __FILE__, __LINE__)
624
625 typedef struct ExtTest {
626 const char *parse_text;
627 const XML_Char *encoding;
628 CharData *storage;
629 } ExtTest;
630
631 static void XMLCALL
ext_accumulate_characters(void * userData,const XML_Char * s,int len)632 ext_accumulate_characters(void *userData, const XML_Char *s, int len)
633 {
634 ExtTest *test_data = (ExtTest *)userData;
635 accumulate_characters(test_data->storage, s, len);
636 }
637
638 static void
_run_ext_character_check(const char * text,ExtTest * test_data,const XML_Char * expected,const char * file,int line)639 _run_ext_character_check(const char *text,
640 ExtTest *test_data,
641 const XML_Char *expected,
642 const char *file, int line)
643 {
644 CharData storage;
645
646 CharData_Init(&storage);
647 test_data->storage = &storage;
648 XML_SetUserData(parser, test_data);
649 XML_SetCharacterDataHandler(parser, ext_accumulate_characters);
650 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
651 XML_TRUE) == XML_STATUS_ERROR)
652 _xml_failure(parser, file, line);
653 CharData_CheckXMLChars(&storage, expected);
654 }
655
656 #define run_ext_character_check(text, test_data, expected) \
657 _run_ext_character_check(text, test_data, expected, __FILE__, __LINE__)
658
659 /* Regression test for SF bug #491986. */
START_TEST(test_danish_latin1)660 START_TEST(test_danish_latin1)
661 {
662 const char *text =
663 "<?xml version='1.0' encoding='iso-8859-1'?>\n"
664 "<e>J\xF8rgen \xE6\xF8\xE5\xC6\xD8\xC5</e>";
665 #ifdef XML_UNICODE
666 const XML_Char *expected =
667 XCS("J\x00f8rgen \x00e6\x00f8\x00e5\x00c6\x00d8\x00c5");
668 #else
669 const XML_Char *expected =
670 XCS("J\xC3\xB8rgen \xC3\xA6\xC3\xB8\xC3\xA5\xC3\x86\xC3\x98\xC3\x85");
671 #endif
672 run_character_check(text, expected);
673 }
674 END_TEST
675
676
677 /* Regression test for SF bug #514281. */
START_TEST(test_french_charref_hexidecimal)678 START_TEST(test_french_charref_hexidecimal)
679 {
680 const char *text =
681 "<?xml version='1.0' encoding='iso-8859-1'?>\n"
682 "<doc>éèàçêÈ</doc>";
683 #ifdef XML_UNICODE
684 const XML_Char *expected =
685 XCS("\x00e9\x00e8\x00e0\x00e7\x00ea\x00c8");
686 #else
687 const XML_Char *expected =
688 XCS("\xC3\xA9\xC3\xA8\xC3\xA0\xC3\xA7\xC3\xAA\xC3\x88");
689 #endif
690 run_character_check(text, expected);
691 }
692 END_TEST
693
START_TEST(test_french_charref_decimal)694 START_TEST(test_french_charref_decimal)
695 {
696 const char *text =
697 "<?xml version='1.0' encoding='iso-8859-1'?>\n"
698 "<doc>éèàçêÈ</doc>";
699 #ifdef XML_UNICODE
700 const XML_Char *expected =
701 XCS("\x00e9\x00e8\x00e0\x00e7\x00ea\x00c8");
702 #else
703 const XML_Char *expected =
704 XCS("\xC3\xA9\xC3\xA8\xC3\xA0\xC3\xA7\xC3\xAA\xC3\x88");
705 #endif
706 run_character_check(text, expected);
707 }
708 END_TEST
709
START_TEST(test_french_latin1)710 START_TEST(test_french_latin1)
711 {
712 const char *text =
713 "<?xml version='1.0' encoding='iso-8859-1'?>\n"
714 "<doc>\xE9\xE8\xE0\xE7\xEa\xC8</doc>";
715 #ifdef XML_UNICODE
716 const XML_Char *expected =
717 XCS("\x00e9\x00e8\x00e0\x00e7\x00ea\x00c8");
718 #else
719 const XML_Char *expected =
720 XCS("\xC3\xA9\xC3\xA8\xC3\xA0\xC3\xA7\xC3\xAA\xC3\x88");
721 #endif
722 run_character_check(text, expected);
723 }
724 END_TEST
725
START_TEST(test_french_utf8)726 START_TEST(test_french_utf8)
727 {
728 const char *text =
729 "<?xml version='1.0' encoding='utf-8'?>\n"
730 "<doc>\xC3\xA9</doc>";
731 #ifdef XML_UNICODE
732 const XML_Char *expected = XCS("\x00e9");
733 #else
734 const XML_Char *expected = XCS("\xC3\xA9");
735 #endif
736 run_character_check(text, expected);
737 }
738 END_TEST
739
740 /* Regression test for SF bug #600479.
741 XXX There should be a test that exercises all legal XML Unicode
742 characters as PCDATA and attribute value content, and XML Name
743 characters as part of element and attribute names.
744 */
START_TEST(test_utf8_false_rejection)745 START_TEST(test_utf8_false_rejection)
746 {
747 const char *text = "<doc>\xEF\xBA\xBF</doc>";
748 #ifdef XML_UNICODE
749 const XML_Char *expected = XCS("\xfebf");
750 #else
751 const XML_Char *expected = XCS("\xEF\xBA\xBF");
752 #endif
753 run_character_check(text, expected);
754 }
755 END_TEST
756
757 /* Regression test for SF bug #477667.
758 This test assures that any 8-bit character followed by a 7-bit
759 character will not be mistakenly interpreted as a valid UTF-8
760 sequence.
761 */
START_TEST(test_illegal_utf8)762 START_TEST(test_illegal_utf8)
763 {
764 char text[100];
765 int i;
766
767 for (i = 128; i <= 255; ++i) {
768 sprintf(text, "<e>%ccd</e>", i);
769 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_OK) {
770 sprintf(text,
771 "expected token error for '%c' (ordinal %d) in UTF-8 text",
772 i, i);
773 fail(text);
774 }
775 else if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_TOKEN)
776 xml_failure(parser);
777 /* Reset the parser since we use the same parser repeatedly. */
778 XML_ParserReset(parser, NULL);
779 }
780 }
781 END_TEST
782
783
784 /* Examples, not masks: */
785 #define UTF8_LEAD_1 "\x7f" /* 0b01111111 */
786 #define UTF8_LEAD_2 "\xdf" /* 0b11011111 */
787 #define UTF8_LEAD_3 "\xef" /* 0b11101111 */
788 #define UTF8_LEAD_4 "\xf7" /* 0b11110111 */
789 #define UTF8_FOLLOW "\xbf" /* 0b10111111 */
790
START_TEST(test_utf8_auto_align)791 START_TEST(test_utf8_auto_align)
792 {
793 struct TestCase {
794 ptrdiff_t expectedMovementInChars;
795 const char * input;
796 };
797
798 struct TestCase cases[] = {
799 {00, ""},
800
801 {00, UTF8_LEAD_1},
802
803 {-1, UTF8_LEAD_2},
804 {00, UTF8_LEAD_2 UTF8_FOLLOW},
805
806 {-1, UTF8_LEAD_3},
807 {-2, UTF8_LEAD_3 UTF8_FOLLOW},
808 {00, UTF8_LEAD_3 UTF8_FOLLOW UTF8_FOLLOW},
809
810 {-1, UTF8_LEAD_4},
811 {-2, UTF8_LEAD_4 UTF8_FOLLOW},
812 {-3, UTF8_LEAD_4 UTF8_FOLLOW UTF8_FOLLOW},
813 {00, UTF8_LEAD_4 UTF8_FOLLOW UTF8_FOLLOW UTF8_FOLLOW},
814 };
815
816 size_t i = 0;
817 bool success = true;
818 for (; i < sizeof(cases) / sizeof(*cases); i++) {
819 const char * fromLim = cases[i].input + strlen(cases[i].input);
820 const char * const fromLimInitially = fromLim;
821 ptrdiff_t actualMovementInChars;
822
823 _INTERNAL_trim_to_complete_utf8_characters(cases[i].input, &fromLim);
824
825 actualMovementInChars = (fromLim - fromLimInitially);
826 if (actualMovementInChars != cases[i].expectedMovementInChars) {
827 size_t j = 0;
828 success = false;
829 printf("[-] UTF-8 case %2u: Expected movement by %2d chars"
830 ", actually moved by %2d chars: \"",
831 (unsigned)(i + 1),
832 (int)cases[i].expectedMovementInChars,
833 (int)actualMovementInChars);
834 for (; j < strlen(cases[i].input); j++) {
835 printf("\\x%02x", (unsigned char)cases[i].input[j]);
836 }
837 printf("\"\n");
838 }
839 }
840
841 if (! success) {
842 fail("UTF-8 auto-alignment is not bullet-proof\n");
843 }
844 }
845 END_TEST
846
START_TEST(test_utf16)847 START_TEST(test_utf16)
848 {
849 /* <?xml version="1.0" encoding="UTF-16"?>
850 * <doc a='123'>some {A} text</doc>
851 *
852 * where {A} is U+FF21, FULLWIDTH LATIN CAPITAL LETTER A
853 */
854 char text[] =
855 "\000<\000?\000x\000m\000\154\000 \000v\000e\000r\000s\000i\000o"
856 "\000n\000=\000'\0001\000.\000\060\000'\000 \000e\000n\000c\000o"
857 "\000d\000i\000n\000g\000=\000'\000U\000T\000F\000-\0001\000\066"
858 "\000'\000?\000>\000\n"
859 "\000<\000d\000o\000c\000 \000a\000=\000'\0001\0002\0003\000'\000>"
860 "\000s\000o\000m\000e\000 \xff\x21\000 \000t\000e\000x\000t\000"
861 "<\000/\000d\000o\000c\000>";
862 #ifdef XML_UNICODE
863 const XML_Char *expected = XCS("some \xff21 text");
864 #else
865 const XML_Char *expected = XCS("some \357\274\241 text");
866 #endif
867 CharData storage;
868
869 CharData_Init(&storage);
870 XML_SetUserData(parser, &storage);
871 XML_SetCharacterDataHandler(parser, accumulate_characters);
872 if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text)-1, XML_TRUE) == XML_STATUS_ERROR)
873 xml_failure(parser);
874 CharData_CheckXMLChars(&storage, expected);
875 }
876 END_TEST
877
START_TEST(test_utf16_le_epilog_newline)878 START_TEST(test_utf16_le_epilog_newline)
879 {
880 unsigned int first_chunk_bytes = 17;
881 char text[] =
882 "\xFF\xFE" /* BOM */
883 "<\000e\000/\000>\000" /* document element */
884 "\r\000\n\000\r\000\n\000"; /* epilog */
885
886 if (first_chunk_bytes >= sizeof(text) - 1)
887 fail("bad value of first_chunk_bytes");
888 if ( _XML_Parse_SINGLE_BYTES(parser, text, first_chunk_bytes, XML_FALSE)
889 == XML_STATUS_ERROR)
890 xml_failure(parser);
891 else {
892 enum XML_Status rc;
893 rc = _XML_Parse_SINGLE_BYTES(parser, text + first_chunk_bytes,
894 sizeof(text) - first_chunk_bytes - 1, XML_TRUE);
895 if (rc == XML_STATUS_ERROR)
896 xml_failure(parser);
897 }
898 }
899 END_TEST
900
901 /* Test that an outright lie in the encoding is faulted */
START_TEST(test_not_utf16)902 START_TEST(test_not_utf16)
903 {
904 const char *text =
905 "<?xml version='1.0' encoding='utf-16'?>"
906 "<doc>Hi</doc>";
907
908 /* Use a handler to provoke the appropriate code paths */
909 XML_SetXmlDeclHandler(parser, dummy_xdecl_handler);
910 expect_failure(text,
911 XML_ERROR_INCORRECT_ENCODING,
912 "UTF-16 declared in UTF-8 not faulted");
913 }
914 END_TEST
915
916 /* Test that an unknown encoding is rejected */
START_TEST(test_bad_encoding)917 START_TEST(test_bad_encoding)
918 {
919 const char *text = "<doc>Hi</doc>";
920
921 if (!XML_SetEncoding(parser, XCS("unknown-encoding")))
922 fail("XML_SetEncoding failed");
923 expect_failure(text,
924 XML_ERROR_UNKNOWN_ENCODING,
925 "Unknown encoding not faulted");
926 }
927 END_TEST
928
929 /* Regression test for SF bug #481609, #774028. */
START_TEST(test_latin1_umlauts)930 START_TEST(test_latin1_umlauts)
931 {
932 const char *text =
933 "<?xml version='1.0' encoding='iso-8859-1'?>\n"
934 "<e a='\xE4 \xF6 \xFC ä ö ü ä ö ü >'\n"
935 " >\xE4 \xF6 \xFC ä ö ü ä ö ü ></e>";
936 #ifdef XML_UNICODE
937 /* Expected results in UTF-16 */
938 const XML_Char *expected =
939 XCS("\x00e4 \x00f6 \x00fc ")
940 XCS("\x00e4 \x00f6 \x00fc ")
941 XCS("\x00e4 \x00f6 \x00fc >");
942 #else
943 /* Expected results in UTF-8 */
944 const XML_Char *expected =
945 XCS("\xC3\xA4 \xC3\xB6 \xC3\xBC ")
946 XCS("\xC3\xA4 \xC3\xB6 \xC3\xBC ")
947 XCS("\xC3\xA4 \xC3\xB6 \xC3\xBC >");
948 #endif
949
950 run_character_check(text, expected);
951 XML_ParserReset(parser, NULL);
952 run_attribute_check(text, expected);
953 /* Repeat with a default handler */
954 XML_ParserReset(parser, NULL);
955 XML_SetDefaultHandler(parser, dummy_default_handler);
956 run_character_check(text, expected);
957 XML_ParserReset(parser, NULL);
958 XML_SetDefaultHandler(parser, dummy_default_handler);
959 run_attribute_check(text, expected);
960 }
961 END_TEST
962
963 /* Test that an element name with a 4-byte UTF-8 character is rejected */
START_TEST(test_long_utf8_character)964 START_TEST(test_long_utf8_character)
965 {
966 const char *text =
967 "<?xml version='1.0' encoding='utf-8'?>\n"
968 /* 0xf0 0x90 0x80 0x80 = U+10000, the first Linear B character */
969 "<do\xf0\x90\x80\x80/>";
970 expect_failure(text,
971 XML_ERROR_INVALID_TOKEN,
972 "4-byte UTF-8 character in element name not faulted");
973 }
974 END_TEST
975
976 /* Test that a long latin-1 attribute (too long to convert in one go)
977 * is correctly converted
978 */
START_TEST(test_long_latin1_attribute)979 START_TEST(test_long_latin1_attribute)
980 {
981 const char *text =
982 "<?xml version='1.0' encoding='iso-8859-1'?>\n"
983 "<doc att='"
984 /* 64 characters per line */
985 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
986 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
987 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
988 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
989 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
990 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
991 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
992 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
993 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
994 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
995 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
996 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
997 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
998 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
999 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
1000 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
1001 /* Last character splits across a buffer boundary */
1002 "\xe4'>\n</doc>";
1003 #ifdef XML_UNICODE
1004 const XML_Char *expected =
1005 /* 64 characters per line */
1006 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1007 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1008 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1009 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1010 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1011 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1012 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1013 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1014 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1015 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1016 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1017 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1018 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1019 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1020 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1021 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO")
1022 XCS("\x00e4");
1023 #else
1024 const XML_Char *expected =
1025 /* 64 characters per line */
1026 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1027 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1028 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1029 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1030 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1031 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1032 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1033 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1034 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1035 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1036 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1037 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1038 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1039 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1040 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1041 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO")
1042 XCS("\xc3\xa4");
1043 #endif
1044
1045 run_attribute_check(text, expected);
1046 }
1047 END_TEST
1048
1049
1050 /* Test that a long ASCII attribute (too long to convert in one go)
1051 * is correctly converted
1052 */
START_TEST(test_long_ascii_attribute)1053 START_TEST(test_long_ascii_attribute)
1054 {
1055 const char *text =
1056 "<?xml version='1.0' encoding='us-ascii'?>\n"
1057 "<doc att='"
1058 /* 64 characters per line */
1059 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
1060 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
1061 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
1062 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
1063 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
1064 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
1065 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
1066 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
1067 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
1068 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
1069 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
1070 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
1071 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
1072 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
1073 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
1074 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
1075 "01234'>\n</doc>";
1076 const XML_Char *expected =
1077 /* 64 characters per line */
1078 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1079 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1080 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1081 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1082 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1083 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1084 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1085 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1086 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1087 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1088 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1089 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1090 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1091 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1092 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1093 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
1094 XCS("01234");
1095
1096 run_attribute_check(text, expected);
1097 }
1098 END_TEST
1099
1100 /* Regression test #1 for SF bug #653180. */
START_TEST(test_line_number_after_parse)1101 START_TEST(test_line_number_after_parse)
1102 {
1103 const char *text =
1104 "<tag>\n"
1105 "\n"
1106 "\n</tag>";
1107 XML_Size lineno;
1108
1109 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_FALSE) == XML_STATUS_ERROR)
1110 xml_failure(parser);
1111 lineno = XML_GetCurrentLineNumber(parser);
1112 if (lineno != 4) {
1113 char buffer[100];
1114 sprintf(buffer,
1115 "expected 4 lines, saw %" XML_FMT_INT_MOD "u", lineno);
1116 fail(buffer);
1117 }
1118 }
1119 END_TEST
1120
1121 /* Regression test #2 for SF bug #653180. */
START_TEST(test_column_number_after_parse)1122 START_TEST(test_column_number_after_parse)
1123 {
1124 const char *text = "<tag></tag>";
1125 XML_Size colno;
1126
1127 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_FALSE) == XML_STATUS_ERROR)
1128 xml_failure(parser);
1129 colno = XML_GetCurrentColumnNumber(parser);
1130 if (colno != 11) {
1131 char buffer[100];
1132 sprintf(buffer,
1133 "expected 11 columns, saw %" XML_FMT_INT_MOD "u", colno);
1134 fail(buffer);
1135 }
1136 }
1137 END_TEST
1138
1139 #define STRUCT_START_TAG 0
1140 #define STRUCT_END_TAG 1
1141 static void XMLCALL
start_element_event_handler2(void * userData,const XML_Char * name,const XML_Char ** UNUSED_P (attr))1142 start_element_event_handler2(void *userData, const XML_Char *name,
1143 const XML_Char **UNUSED_P(attr))
1144 {
1145 StructData *storage = (StructData *) userData;
1146 StructData_AddItem(storage, name,
1147 XML_GetCurrentColumnNumber(parser),
1148 XML_GetCurrentLineNumber(parser),
1149 STRUCT_START_TAG);
1150 }
1151
1152 static void XMLCALL
end_element_event_handler2(void * userData,const XML_Char * name)1153 end_element_event_handler2(void *userData, const XML_Char *name)
1154 {
1155 StructData *storage = (StructData *) userData;
1156 StructData_AddItem(storage, name,
1157 XML_GetCurrentColumnNumber(parser),
1158 XML_GetCurrentLineNumber(parser),
1159 STRUCT_END_TAG);
1160 }
1161
1162 /* Regression test #3 for SF bug #653180. */
START_TEST(test_line_and_column_numbers_inside_handlers)1163 START_TEST(test_line_and_column_numbers_inside_handlers)
1164 {
1165 const char *text =
1166 "<a>\n" /* Unix end-of-line */
1167 " <b>\r\n" /* Windows end-of-line */
1168 " <c/>\r" /* Mac OS end-of-line */
1169 " </b>\n"
1170 " <d>\n"
1171 " <f/>\n"
1172 " </d>\n"
1173 "</a>";
1174 const StructDataEntry expected[] = {
1175 { XCS("a"), 0, 1, STRUCT_START_TAG },
1176 { XCS("b"), 2, 2, STRUCT_START_TAG },
1177 { XCS("c"), 4, 3, STRUCT_START_TAG },
1178 { XCS("c"), 8, 3, STRUCT_END_TAG },
1179 { XCS("b"), 2, 4, STRUCT_END_TAG },
1180 { XCS("d"), 2, 5, STRUCT_START_TAG },
1181 { XCS("f"), 4, 6, STRUCT_START_TAG },
1182 { XCS("f"), 8, 6, STRUCT_END_TAG },
1183 { XCS("d"), 2, 7, STRUCT_END_TAG },
1184 { XCS("a"), 0, 8, STRUCT_END_TAG }
1185 };
1186 const int expected_count = sizeof(expected) / sizeof(StructDataEntry);
1187 StructData storage;
1188
1189 StructData_Init(&storage);
1190 XML_SetUserData(parser, &storage);
1191 XML_SetStartElementHandler(parser, start_element_event_handler2);
1192 XML_SetEndElementHandler(parser, end_element_event_handler2);
1193 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR)
1194 xml_failure(parser);
1195
1196 StructData_CheckItems(&storage, expected, expected_count);
1197 StructData_Dispose(&storage);
1198 }
1199 END_TEST
1200
1201 /* Regression test #4 for SF bug #653180. */
START_TEST(test_line_number_after_error)1202 START_TEST(test_line_number_after_error)
1203 {
1204 const char *text =
1205 "<a>\n"
1206 " <b>\n"
1207 " </a>"; /* missing </b> */
1208 XML_Size lineno;
1209 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_FALSE) != XML_STATUS_ERROR)
1210 fail("Expected a parse error");
1211
1212 lineno = XML_GetCurrentLineNumber(parser);
1213 if (lineno != 3) {
1214 char buffer[100];
1215 sprintf(buffer, "expected 3 lines, saw %" XML_FMT_INT_MOD "u", lineno);
1216 fail(buffer);
1217 }
1218 }
1219 END_TEST
1220
1221 /* Regression test #5 for SF bug #653180. */
START_TEST(test_column_number_after_error)1222 START_TEST(test_column_number_after_error)
1223 {
1224 const char *text =
1225 "<a>\n"
1226 " <b>\n"
1227 " </a>"; /* missing </b> */
1228 XML_Size colno;
1229 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_FALSE) != XML_STATUS_ERROR)
1230 fail("Expected a parse error");
1231
1232 colno = XML_GetCurrentColumnNumber(parser);
1233 if (colno != 4) {
1234 char buffer[100];
1235 sprintf(buffer,
1236 "expected 4 columns, saw %" XML_FMT_INT_MOD "u", colno);
1237 fail(buffer);
1238 }
1239 }
1240 END_TEST
1241
1242 /* Regression test for SF bug #478332. */
START_TEST(test_really_long_lines)1243 START_TEST(test_really_long_lines)
1244 {
1245 /* This parses an input line longer than INIT_DATA_BUF_SIZE
1246 characters long (defined to be 1024 in xmlparse.c). We take a
1247 really cheesy approach to building the input buffer, because
1248 this avoids writing bugs in buffer-filling code.
1249 */
1250 const char *text =
1251 "<e>"
1252 /* 64 chars */
1253 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
1254 /* until we have at least 1024 characters on the line: */
1255 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
1256 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
1257 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
1258 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
1259 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
1260 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
1261 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
1262 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
1263 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
1264 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
1265 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
1266 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
1267 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
1268 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
1269 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
1270 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
1271 "</e>";
1272 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR)
1273 xml_failure(parser);
1274 }
1275 END_TEST
1276
1277 /* Test cdata processing across a buffer boundary */
START_TEST(test_really_long_encoded_lines)1278 START_TEST(test_really_long_encoded_lines)
1279 {
1280 /* As above, except that we want to provoke an output buffer
1281 * overflow with a non-trivial encoding. For this we need to pass
1282 * the whole cdata in one go, not byte-by-byte.
1283 */
1284 void *buffer;
1285 const char *text =
1286 "<?xml version='1.0' encoding='iso-8859-1'?>"
1287 "<e>"
1288 /* 64 chars */
1289 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
1290 /* until we have at least 1024 characters on the line: */
1291 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
1292 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
1293 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
1294 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
1295 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
1296 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
1297 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
1298 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
1299 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
1300 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
1301 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
1302 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
1303 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
1304 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
1305 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
1306 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
1307 "</e>";
1308 int parse_len = (int)strlen(text);
1309
1310 /* Need a cdata handler to provoke the code path we want to test */
1311 XML_SetCharacterDataHandler(parser, dummy_cdata_handler);
1312 buffer = XML_GetBuffer(parser, parse_len);
1313 if (buffer == NULL)
1314 fail("Could not allocate parse buffer");
1315 memcpy(buffer, text, parse_len);
1316 if (XML_ParseBuffer(parser, parse_len, XML_TRUE) == XML_STATUS_ERROR)
1317 xml_failure(parser);
1318 }
1319 END_TEST
1320
1321
1322 /*
1323 * Element event tests.
1324 */
1325
1326 static void XMLCALL
start_element_event_handler(void * userData,const XML_Char * name,const XML_Char ** UNUSED_P (atts))1327 start_element_event_handler(void *userData,
1328 const XML_Char *name,
1329 const XML_Char **UNUSED_P(atts))
1330 {
1331 CharData_AppendXMLChars((CharData *)userData, name, -1);
1332 }
1333
1334 static void XMLCALL
end_element_event_handler(void * userData,const XML_Char * name)1335 end_element_event_handler(void *userData, const XML_Char *name)
1336 {
1337 CharData *storage = (CharData *) userData;
1338 CharData_AppendXMLChars(storage, XCS("/"), 1);
1339 CharData_AppendXMLChars(storage, name, -1);
1340 }
1341
START_TEST(test_end_element_events)1342 START_TEST(test_end_element_events)
1343 {
1344 const char *text = "<a><b><c/></b><d><f/></d></a>";
1345 const XML_Char *expected = XCS("/c/b/f/d/a");
1346 CharData storage;
1347
1348 CharData_Init(&storage);
1349 XML_SetUserData(parser, &storage);
1350 XML_SetEndElementHandler(parser, end_element_event_handler);
1351 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR)
1352 xml_failure(parser);
1353 CharData_CheckXMLChars(&storage, expected);
1354 }
1355 END_TEST
1356
1357
1358 /*
1359 * Attribute tests.
1360 */
1361
1362 /* Helpers used by the following test; this checks any "attr" and "refs"
1363 attributes to make sure whitespace has been normalized.
1364
1365 Return true if whitespace has been normalized in a string, using
1366 the rules for attribute value normalization. The 'is_cdata' flag
1367 is needed since CDATA attributes don't need to have multiple
1368 whitespace characters collapsed to a single space, while other
1369 attribute data types do. (Section 3.3.3 of the recommendation.)
1370 */
1371 static int
is_whitespace_normalized(const XML_Char * s,int is_cdata)1372 is_whitespace_normalized(const XML_Char *s, int is_cdata)
1373 {
1374 int blanks = 0;
1375 int at_start = 1;
1376 while (*s) {
1377 if (*s == XCS(' '))
1378 ++blanks;
1379 else if (*s == XCS('\t') || *s == XCS('\n') || *s == XCS('\r'))
1380 return 0;
1381 else {
1382 if (at_start) {
1383 at_start = 0;
1384 if (blanks && !is_cdata)
1385 /* illegal leading blanks */
1386 return 0;
1387 }
1388 else if (blanks > 1 && !is_cdata)
1389 return 0;
1390 blanks = 0;
1391 }
1392 ++s;
1393 }
1394 if (blanks && !is_cdata)
1395 return 0;
1396 return 1;
1397 }
1398
1399 /* Check the attribute whitespace checker: */
1400 static void
testhelper_is_whitespace_normalized(void)1401 testhelper_is_whitespace_normalized(void)
1402 {
1403 assert(is_whitespace_normalized(XCS("abc"), 0));
1404 assert(is_whitespace_normalized(XCS("abc"), 1));
1405 assert(is_whitespace_normalized(XCS("abc def ghi"), 0));
1406 assert(is_whitespace_normalized(XCS("abc def ghi"), 1));
1407 assert(!is_whitespace_normalized(XCS(" abc def ghi"), 0));
1408 assert(is_whitespace_normalized(XCS(" abc def ghi"), 1));
1409 assert(!is_whitespace_normalized(XCS("abc def ghi"), 0));
1410 assert(is_whitespace_normalized(XCS("abc def ghi"), 1));
1411 assert(!is_whitespace_normalized(XCS("abc def ghi "), 0));
1412 assert(is_whitespace_normalized(XCS("abc def ghi "), 1));
1413 assert(!is_whitespace_normalized(XCS(" "), 0));
1414 assert(is_whitespace_normalized(XCS(" "), 1));
1415 assert(!is_whitespace_normalized(XCS("\t"), 0));
1416 assert(!is_whitespace_normalized(XCS("\t"), 1));
1417 assert(!is_whitespace_normalized(XCS("\n"), 0));
1418 assert(!is_whitespace_normalized(XCS("\n"), 1));
1419 assert(!is_whitespace_normalized(XCS("\r"), 0));
1420 assert(!is_whitespace_normalized(XCS("\r"), 1));
1421 assert(!is_whitespace_normalized(XCS("abc\t def"), 1));
1422 }
1423
1424 static void XMLCALL
check_attr_contains_normalized_whitespace(void * UNUSED_P (userData),const XML_Char * UNUSED_P (name),const XML_Char ** atts)1425 check_attr_contains_normalized_whitespace(void *UNUSED_P(userData),
1426 const XML_Char *UNUSED_P(name),
1427 const XML_Char **atts)
1428 {
1429 int i;
1430 for (i = 0; atts[i] != NULL; i += 2) {
1431 const XML_Char *attrname = atts[i];
1432 const XML_Char *value = atts[i + 1];
1433 if (xcstrcmp(XCS("attr"), attrname) == 0
1434 || xcstrcmp(XCS("ents"), attrname) == 0
1435 || xcstrcmp(XCS("refs"), attrname) == 0) {
1436 if (!is_whitespace_normalized(value, 0)) {
1437 char buffer[256];
1438 sprintf(buffer, "attribute value not normalized: %"
1439 XML_FMT_STR "='%" XML_FMT_STR "'",
1440 attrname, value);
1441 fail(buffer);
1442 }
1443 }
1444 }
1445 }
1446
START_TEST(test_attr_whitespace_normalization)1447 START_TEST(test_attr_whitespace_normalization)
1448 {
1449 const char *text =
1450 "<!DOCTYPE doc [\n"
1451 " <!ATTLIST doc\n"
1452 " attr NMTOKENS #REQUIRED\n"
1453 " ents ENTITIES #REQUIRED\n"
1454 " refs IDREFS #REQUIRED>\n"
1455 "]>\n"
1456 "<doc attr=' a b c\t\td\te\t' refs=' id-1 \t id-2\t\t' \n"
1457 " ents=' ent-1 \t\r\n"
1458 " ent-2 ' >\n"
1459 " <e id='id-1'/>\n"
1460 " <e id='id-2'/>\n"
1461 "</doc>";
1462
1463 XML_SetStartElementHandler(parser,
1464 check_attr_contains_normalized_whitespace);
1465 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR)
1466 xml_failure(parser);
1467 }
1468 END_TEST
1469
1470
1471 /*
1472 * XML declaration tests.
1473 */
1474
START_TEST(test_xmldecl_misplaced)1475 START_TEST(test_xmldecl_misplaced)
1476 {
1477 expect_failure("\n"
1478 "<?xml version='1.0'?>\n"
1479 "<a/>",
1480 XML_ERROR_MISPLACED_XML_PI,
1481 "failed to report misplaced XML declaration");
1482 }
1483 END_TEST
1484
START_TEST(test_xmldecl_invalid)1485 START_TEST(test_xmldecl_invalid)
1486 {
1487 expect_failure("<?xml version='1.0' \xc3\xa7?>\n<doc/>",
1488 XML_ERROR_XML_DECL,
1489 "Failed to report invalid XML declaration");
1490 }
1491 END_TEST
1492
START_TEST(test_xmldecl_missing_attr)1493 START_TEST(test_xmldecl_missing_attr)
1494 {
1495 expect_failure("<?xml ='1.0'?>\n<doc/>\n",
1496 XML_ERROR_XML_DECL,
1497 "Failed to report missing XML declaration attribute");
1498 }
1499 END_TEST
1500
START_TEST(test_xmldecl_missing_value)1501 START_TEST(test_xmldecl_missing_value)
1502 {
1503 expect_failure("<?xml version='1.0' encoding='us-ascii' standalone?>\n"
1504 "<doc/>",
1505 XML_ERROR_XML_DECL,
1506 "Failed to report missing attribute value");
1507 }
1508 END_TEST
1509
1510 /* Regression test for SF bug #584832. */
1511 static int XMLCALL
UnknownEncodingHandler(void * UNUSED_P (data),const XML_Char * encoding,XML_Encoding * info)1512 UnknownEncodingHandler(void *UNUSED_P(data),const XML_Char *encoding,XML_Encoding *info)
1513 {
1514 if (xcstrcmp(encoding, XCS("unsupported-encoding")) == 0) {
1515 int i;
1516 for (i = 0; i < 256; ++i)
1517 info->map[i] = i;
1518 info->data = NULL;
1519 info->convert = NULL;
1520 info->release = NULL;
1521 return XML_STATUS_OK;
1522 }
1523 return XML_STATUS_ERROR;
1524 }
1525
START_TEST(test_unknown_encoding_internal_entity)1526 START_TEST(test_unknown_encoding_internal_entity)
1527 {
1528 const char *text =
1529 "<?xml version='1.0' encoding='unsupported-encoding'?>\n"
1530 "<!DOCTYPE test [<!ENTITY foo 'bar'>]>\n"
1531 "<test a='&foo;'/>";
1532
1533 XML_SetUnknownEncodingHandler(parser, UnknownEncodingHandler, NULL);
1534 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR)
1535 xml_failure(parser);
1536 }
1537 END_TEST
1538
1539 /* Test unrecognised encoding handler */
dummy_release(void * UNUSED_P (data))1540 static void dummy_release(void *UNUSED_P(data))
1541 {
1542 }
1543
1544 static int XMLCALL
UnrecognisedEncodingHandler(void * UNUSED_P (data),const XML_Char * UNUSED_P (encoding),XML_Encoding * info)1545 UnrecognisedEncodingHandler(void *UNUSED_P(data),
1546 const XML_Char *UNUSED_P(encoding),
1547 XML_Encoding *info)
1548 {
1549 info->data = NULL;
1550 info->convert = NULL;
1551 info->release = dummy_release;
1552 return XML_STATUS_ERROR;
1553 }
1554
START_TEST(test_unrecognised_encoding_internal_entity)1555 START_TEST(test_unrecognised_encoding_internal_entity)
1556 {
1557 const char *text =
1558 "<?xml version='1.0' encoding='unsupported-encoding'?>\n"
1559 "<!DOCTYPE test [<!ENTITY foo 'bar'>]>\n"
1560 "<test a='&foo;'/>";
1561
1562 XML_SetUnknownEncodingHandler(parser,
1563 UnrecognisedEncodingHandler,
1564 NULL);
1565 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR)
1566 fail("Unrecognised encoding not rejected");
1567 }
1568 END_TEST
1569
1570 /* Regression test for SF bug #620106. */
1571 static int XMLCALL
external_entity_loader(XML_Parser parser,const XML_Char * context,const XML_Char * UNUSED_P (base),const XML_Char * UNUSED_P (systemId),const XML_Char * UNUSED_P (publicId))1572 external_entity_loader(XML_Parser parser,
1573 const XML_Char *context,
1574 const XML_Char *UNUSED_P(base),
1575 const XML_Char *UNUSED_P(systemId),
1576 const XML_Char *UNUSED_P(publicId))
1577 {
1578 ExtTest *test_data = (ExtTest *)XML_GetUserData(parser);
1579 XML_Parser extparser;
1580
1581 extparser = XML_ExternalEntityParserCreate(parser, context, NULL);
1582 if (extparser == NULL)
1583 fail("Could not create external entity parser.");
1584 if (test_data->encoding != NULL) {
1585 if (!XML_SetEncoding(extparser, test_data->encoding))
1586 fail("XML_SetEncoding() ignored for external entity");
1587 }
1588 if ( _XML_Parse_SINGLE_BYTES(extparser,
1589 test_data->parse_text,
1590 (int)strlen(test_data->parse_text),
1591 XML_TRUE)
1592 == XML_STATUS_ERROR) {
1593 xml_failure(extparser);
1594 return XML_STATUS_ERROR;
1595 }
1596 XML_ParserFree(extparser);
1597 return XML_STATUS_OK;
1598 }
1599
START_TEST(test_ext_entity_set_encoding)1600 START_TEST(test_ext_entity_set_encoding)
1601 {
1602 const char *text =
1603 "<!DOCTYPE doc [\n"
1604 " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n"
1605 "]>\n"
1606 "<doc>&en;</doc>";
1607 ExtTest test_data = {
1608 /* This text says it's an unsupported encoding, but it's really
1609 UTF-8, which we tell Expat using XML_SetEncoding().
1610 */
1611 "<?xml encoding='iso-8859-3'?>\xC3\xA9",
1612 XCS("utf-8"),
1613 NULL
1614 };
1615 #ifdef XML_UNICODE
1616 const XML_Char *expected = XCS("\x00e9");
1617 #else
1618 const XML_Char *expected = XCS("\xc3\xa9");
1619 #endif
1620
1621 XML_SetExternalEntityRefHandler(parser, external_entity_loader);
1622 run_ext_character_check(text, &test_data, expected);
1623 }
1624 END_TEST
1625
1626 /* Test external entities with no handler */
START_TEST(test_ext_entity_no_handler)1627 START_TEST(test_ext_entity_no_handler)
1628 {
1629 const char *text =
1630 "<!DOCTYPE doc [\n"
1631 " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n"
1632 "]>\n"
1633 "<doc>&en;</doc>";
1634
1635 XML_SetDefaultHandler(parser, dummy_default_handler);
1636 run_character_check(text, XCS(""));
1637 }
1638 END_TEST
1639
1640 /* Test UTF-8 BOM is accepted */
START_TEST(test_ext_entity_set_bom)1641 START_TEST(test_ext_entity_set_bom)
1642 {
1643 const char *text =
1644 "<!DOCTYPE doc [\n"
1645 " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n"
1646 "]>\n"
1647 "<doc>&en;</doc>";
1648 ExtTest test_data = {
1649 "\xEF\xBB\xBF" /* BOM */
1650 "<?xml encoding='iso-8859-3'?>"
1651 "\xC3\xA9",
1652 XCS("utf-8"),
1653 NULL
1654 };
1655 #ifdef XML_UNICODE
1656 const XML_Char *expected = XCS("\x00e9");
1657 #else
1658 const XML_Char *expected = XCS("\xc3\xa9");
1659 #endif
1660
1661 XML_SetExternalEntityRefHandler(parser, external_entity_loader);
1662 run_ext_character_check(text, &test_data, expected);
1663 }
1664 END_TEST
1665
1666
1667 /* Test that bad encodings are faulted */
1668 typedef struct ext_faults
1669 {
1670 const char *parse_text;
1671 const char *fail_text;
1672 const XML_Char *encoding;
1673 enum XML_Error error;
1674 } ExtFaults;
1675
1676 static int XMLCALL
external_entity_faulter(XML_Parser parser,const XML_Char * context,const XML_Char * UNUSED_P (base),const XML_Char * UNUSED_P (systemId),const XML_Char * UNUSED_P (publicId))1677 external_entity_faulter(XML_Parser parser,
1678 const XML_Char *context,
1679 const XML_Char *UNUSED_P(base),
1680 const XML_Char *UNUSED_P(systemId),
1681 const XML_Char *UNUSED_P(publicId))
1682 {
1683 XML_Parser ext_parser;
1684 ExtFaults *fault = (ExtFaults *)XML_GetUserData(parser);
1685
1686 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
1687 if (ext_parser == NULL)
1688 fail("Could not create external entity parser");
1689 if (fault->encoding != NULL) {
1690 if (!XML_SetEncoding(ext_parser, fault->encoding))
1691 fail("XML_SetEncoding failed");
1692 }
1693 if (_XML_Parse_SINGLE_BYTES(ext_parser,
1694 fault->parse_text,
1695 (int)strlen(fault->parse_text),
1696 XML_TRUE) != XML_STATUS_ERROR)
1697 fail(fault->fail_text);
1698 if (XML_GetErrorCode(ext_parser) != fault->error)
1699 xml_failure(ext_parser);
1700
1701 XML_ParserFree(ext_parser);
1702 return XML_STATUS_ERROR;
1703 }
1704
START_TEST(test_ext_entity_bad_encoding)1705 START_TEST(test_ext_entity_bad_encoding)
1706 {
1707 const char *text =
1708 "<!DOCTYPE doc [\n"
1709 " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n"
1710 "]>\n"
1711 "<doc>&en;</doc>";
1712 ExtFaults fault = {
1713 "<?xml encoding='iso-8859-3'?>u",
1714 "Unsupported encoding not faulted",
1715 XCS("unknown"),
1716 XML_ERROR_UNKNOWN_ENCODING
1717 };
1718
1719 XML_SetExternalEntityRefHandler(parser, external_entity_faulter);
1720 XML_SetUserData(parser, &fault);
1721 expect_failure(text,
1722 XML_ERROR_EXTERNAL_ENTITY_HANDLING,
1723 "Bad encoding should not have been accepted");
1724 }
1725 END_TEST
1726
1727 /* Try handing an invalid encoding to an external entity parser */
START_TEST(test_ext_entity_bad_encoding_2)1728 START_TEST(test_ext_entity_bad_encoding_2)
1729 {
1730 const char *text =
1731 "<?xml version='1.0' encoding='us-ascii'?>\n"
1732 "<!DOCTYPE doc SYSTEM 'foo'>\n"
1733 "<doc>&entity;</doc>";
1734 ExtFaults fault = {
1735 "<!ELEMENT doc (#PCDATA)*>",
1736 "Unknown encoding not faulted",
1737 XCS("unknown-encoding"),
1738 XML_ERROR_UNKNOWN_ENCODING
1739 };
1740
1741 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
1742 XML_SetExternalEntityRefHandler(parser, external_entity_faulter);
1743 XML_SetUserData(parser, &fault);
1744 expect_failure(text, XML_ERROR_EXTERNAL_ENTITY_HANDLING,
1745 "Bad encoding not faulted in external entity handler");
1746 }
1747 END_TEST
1748
1749 /* Test that no error is reported for unknown entities if we don't
1750 read an external subset. This was fixed in Expat 1.95.5.
1751 */
START_TEST(test_wfc_undeclared_entity_unread_external_subset)1752 START_TEST(test_wfc_undeclared_entity_unread_external_subset) {
1753 const char *text =
1754 "<!DOCTYPE doc SYSTEM 'foo'>\n"
1755 "<doc>&entity;</doc>";
1756
1757 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR)
1758 xml_failure(parser);
1759 }
1760 END_TEST
1761
1762 /* Test that an error is reported for unknown entities if we don't
1763 have an external subset.
1764 */
START_TEST(test_wfc_undeclared_entity_no_external_subset)1765 START_TEST(test_wfc_undeclared_entity_no_external_subset) {
1766 expect_failure("<doc>&entity;</doc>",
1767 XML_ERROR_UNDEFINED_ENTITY,
1768 "Parser did not report undefined entity w/out a DTD.");
1769 }
1770 END_TEST
1771
1772 /* Test that an error is reported for unknown entities if we don't
1773 read an external subset, but have been declared standalone.
1774 */
START_TEST(test_wfc_undeclared_entity_standalone)1775 START_TEST(test_wfc_undeclared_entity_standalone) {
1776 const char *text =
1777 "<?xml version='1.0' encoding='us-ascii' standalone='yes'?>\n"
1778 "<!DOCTYPE doc SYSTEM 'foo'>\n"
1779 "<doc>&entity;</doc>";
1780
1781 expect_failure(text,
1782 XML_ERROR_UNDEFINED_ENTITY,
1783 "Parser did not report undefined entity (standalone).");
1784 }
1785 END_TEST
1786
1787 /* Test that an error is reported for unknown entities if we have read
1788 an external subset, and standalone is true.
1789 */
START_TEST(test_wfc_undeclared_entity_with_external_subset_standalone)1790 START_TEST(test_wfc_undeclared_entity_with_external_subset_standalone) {
1791 const char *text =
1792 "<?xml version='1.0' encoding='us-ascii' standalone='yes'?>\n"
1793 "<!DOCTYPE doc SYSTEM 'foo'>\n"
1794 "<doc>&entity;</doc>";
1795 ExtTest test_data = {
1796 "<!ELEMENT doc (#PCDATA)*>",
1797 NULL,
1798 NULL
1799 };
1800
1801 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
1802 XML_SetUserData(parser, &test_data);
1803 XML_SetExternalEntityRefHandler(parser, external_entity_loader);
1804 expect_failure(text,
1805 XML_ERROR_UNDEFINED_ENTITY,
1806 "Parser did not report undefined entity (external DTD).");
1807 }
1808 END_TEST
1809
1810 /* Test that external entity handling is not done if the parsing flag
1811 * is set to UNLESS_STANDALONE
1812 */
START_TEST(test_entity_with_external_subset_unless_standalone)1813 START_TEST(test_entity_with_external_subset_unless_standalone) {
1814 const char *text =
1815 "<?xml version='1.0' encoding='us-ascii' standalone='yes'?>\n"
1816 "<!DOCTYPE doc SYSTEM 'foo'>\n"
1817 "<doc>&entity;</doc>";
1818 ExtTest test_data = { "<!ENTITY entity 'bar'>", NULL, NULL };
1819
1820 XML_SetParamEntityParsing(parser,
1821 XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE);
1822 XML_SetUserData(parser, &test_data);
1823 XML_SetExternalEntityRefHandler(parser, external_entity_loader);
1824 expect_failure(text,
1825 XML_ERROR_UNDEFINED_ENTITY,
1826 "Parser did not report undefined entity");
1827 }
1828 END_TEST
1829
1830 /* Test that no error is reported for unknown entities if we have read
1831 an external subset, and standalone is false.
1832 */
START_TEST(test_wfc_undeclared_entity_with_external_subset)1833 START_TEST(test_wfc_undeclared_entity_with_external_subset) {
1834 const char *text =
1835 "<?xml version='1.0' encoding='us-ascii'?>\n"
1836 "<!DOCTYPE doc SYSTEM 'foo'>\n"
1837 "<doc>&entity;</doc>";
1838 ExtTest test_data = {
1839 "<!ELEMENT doc (#PCDATA)*>",
1840 NULL,
1841 NULL
1842 };
1843
1844 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
1845 XML_SetExternalEntityRefHandler(parser, external_entity_loader);
1846 run_ext_character_check(text, &test_data, XCS(""));
1847 }
1848 END_TEST
1849
1850 /* Test that an error is reported if our NotStandalone handler fails */
1851 static int XMLCALL
reject_not_standalone_handler(void * UNUSED_P (userData))1852 reject_not_standalone_handler(void *UNUSED_P(userData))
1853 {
1854 return XML_STATUS_ERROR;
1855 }
1856
START_TEST(test_not_standalone_handler_reject)1857 START_TEST(test_not_standalone_handler_reject)
1858 {
1859 const char *text =
1860 "<?xml version='1.0' encoding='us-ascii'?>\n"
1861 "<!DOCTYPE doc SYSTEM 'foo'>\n"
1862 "<doc>&entity;</doc>";
1863 ExtTest test_data = {
1864 "<!ELEMENT doc (#PCDATA)*>",
1865 NULL,
1866 NULL
1867 };
1868
1869 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
1870 XML_SetUserData(parser, &test_data);
1871 XML_SetExternalEntityRefHandler(parser, external_entity_loader);
1872 XML_SetNotStandaloneHandler(parser, reject_not_standalone_handler);
1873 expect_failure(text, XML_ERROR_NOT_STANDALONE,
1874 "NotStandalone handler failed to reject");
1875
1876 /* Try again but without external entity handling */
1877 XML_ParserReset(parser, NULL);
1878 XML_SetNotStandaloneHandler(parser, reject_not_standalone_handler);
1879 expect_failure(text, XML_ERROR_NOT_STANDALONE,
1880 "NotStandalone handler failed to reject");
1881 }
1882 END_TEST
1883
1884 /* Test that no error is reported if our NotStandalone handler succeeds */
1885 static int XMLCALL
accept_not_standalone_handler(void * UNUSED_P (userData))1886 accept_not_standalone_handler(void *UNUSED_P(userData))
1887 {
1888 return XML_STATUS_OK;
1889 }
1890
START_TEST(test_not_standalone_handler_accept)1891 START_TEST(test_not_standalone_handler_accept)
1892 {
1893 const char *text =
1894 "<?xml version='1.0' encoding='us-ascii'?>\n"
1895 "<!DOCTYPE doc SYSTEM 'foo'>\n"
1896 "<doc>&entity;</doc>";
1897 ExtTest test_data = {
1898 "<!ELEMENT doc (#PCDATA)*>",
1899 NULL,
1900 NULL
1901 };
1902
1903 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
1904 XML_SetExternalEntityRefHandler(parser, external_entity_loader);
1905 XML_SetNotStandaloneHandler(parser, accept_not_standalone_handler);
1906 run_ext_character_check(text, &test_data, XCS(""));
1907
1908 /* Repeat wtihout the external entity handler */
1909 XML_ParserReset(parser, NULL);
1910 XML_SetNotStandaloneHandler(parser, accept_not_standalone_handler);
1911 run_character_check(text, XCS(""));
1912 }
1913 END_TEST
1914
START_TEST(test_wfc_no_recursive_entity_refs)1915 START_TEST(test_wfc_no_recursive_entity_refs)
1916 {
1917 const char *text =
1918 "<!DOCTYPE doc [\n"
1919 " <!ENTITY entity '&entity;'>\n"
1920 "]>\n"
1921 "<doc>&entity;</doc>";
1922
1923 expect_failure(text,
1924 XML_ERROR_RECURSIVE_ENTITY_REF,
1925 "Parser did not report recursive entity reference.");
1926 }
1927 END_TEST
1928
1929 /* Test incomplete external entities are faulted */
START_TEST(test_ext_entity_invalid_parse)1930 START_TEST(test_ext_entity_invalid_parse)
1931 {
1932 const char *text =
1933 "<!DOCTYPE doc [\n"
1934 " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n"
1935 "]>\n"
1936 "<doc>&en;</doc>";
1937 const ExtFaults faults[] = {
1938 {
1939 "<",
1940 "Incomplete element declaration not faulted",
1941 NULL,
1942 XML_ERROR_UNCLOSED_TOKEN
1943 },
1944 {
1945 "<\xe2\x82", /* First two bytes of a three-byte char */
1946 "Incomplete character not faulted",
1947 NULL,
1948 XML_ERROR_PARTIAL_CHAR
1949 },
1950 {
1951 "<tag>\xe2\x82",
1952 "Incomplete character in CDATA not faulted",
1953 NULL,
1954 XML_ERROR_PARTIAL_CHAR
1955 },
1956 { NULL, NULL, NULL, XML_ERROR_NONE }
1957 };
1958 const ExtFaults *fault = faults;
1959
1960 for (; fault->parse_text != NULL; fault++) {
1961 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
1962 XML_SetExternalEntityRefHandler(parser, external_entity_faulter);
1963 XML_SetUserData(parser, (void *)fault);
1964 expect_failure(text,
1965 XML_ERROR_EXTERNAL_ENTITY_HANDLING,
1966 "Parser did not report external entity error");
1967 XML_ParserReset(parser, NULL);
1968 }
1969 }
1970 END_TEST
1971
1972
1973 /* Regression test for SF bug #483514. */
START_TEST(test_dtd_default_handling)1974 START_TEST(test_dtd_default_handling)
1975 {
1976 const char *text =
1977 "<!DOCTYPE doc [\n"
1978 "<!ENTITY e SYSTEM 'http://example.org/e'>\n"
1979 "<!NOTATION n SYSTEM 'http://example.org/n'>\n"
1980 "<!ELEMENT doc EMPTY>\n"
1981 "<!ATTLIST doc a CDATA #IMPLIED>\n"
1982 "<?pi in dtd?>\n"
1983 "<!--comment in dtd-->\n"
1984 "]><doc/>";
1985
1986 XML_SetDefaultHandler(parser, accumulate_characters);
1987 XML_SetStartDoctypeDeclHandler(parser, dummy_start_doctype_handler);
1988 XML_SetEndDoctypeDeclHandler(parser, dummy_end_doctype_handler);
1989 XML_SetEntityDeclHandler(parser, dummy_entity_decl_handler);
1990 XML_SetNotationDeclHandler(parser, dummy_notation_decl_handler);
1991 XML_SetElementDeclHandler(parser, dummy_element_decl_handler);
1992 XML_SetAttlistDeclHandler(parser, dummy_attlist_decl_handler);
1993 XML_SetProcessingInstructionHandler(parser, dummy_pi_handler);
1994 XML_SetCommentHandler(parser, dummy_comment_handler);
1995 XML_SetStartCdataSectionHandler(parser, dummy_start_cdata_handler);
1996 XML_SetEndCdataSectionHandler(parser, dummy_end_cdata_handler);
1997 run_character_check(text, XCS("\n\n\n\n\n\n\n<doc/>"));
1998 }
1999 END_TEST
2000
2001 /* Test handling of attribute declarations */
2002 typedef struct AttTest {
2003 const char *definition;
2004 const XML_Char *element_name;
2005 const XML_Char *attr_name;
2006 const XML_Char *attr_type;
2007 const XML_Char *default_value;
2008 int is_required;
2009 } AttTest;
2010
2011 static void XMLCALL
verify_attlist_decl_handler(void * userData,const XML_Char * element_name,const XML_Char * attr_name,const XML_Char * attr_type,const XML_Char * default_value,int is_required)2012 verify_attlist_decl_handler(void *userData,
2013 const XML_Char *element_name,
2014 const XML_Char *attr_name,
2015 const XML_Char *attr_type,
2016 const XML_Char *default_value,
2017 int is_required)
2018 {
2019 AttTest *at = (AttTest *)userData;
2020
2021 if (xcstrcmp(element_name, at->element_name))
2022 fail("Unexpected element name in attribute declaration");
2023 if (xcstrcmp(attr_name, at->attr_name))
2024 fail("Unexpected attribute name in attribute declaration");
2025 if (xcstrcmp(attr_type, at->attr_type))
2026 fail("Unexpected attribute type in attribute declaration");
2027 if ((default_value == NULL && at->default_value != NULL) ||
2028 (default_value != NULL && at->default_value == NULL) ||
2029 (default_value != NULL && xcstrcmp(default_value, at->default_value)))
2030 fail("Unexpected default value in attribute declaration");
2031 if (is_required != at->is_required)
2032 fail("Requirement mismatch in attribute declaration");
2033 }
2034
START_TEST(test_dtd_attr_handling)2035 START_TEST(test_dtd_attr_handling)
2036 {
2037 const char *prolog =
2038 "<!DOCTYPE doc [\n"
2039 "<!ELEMENT doc EMPTY>\n";
2040 AttTest attr_data[] = {
2041 {
2042 "<!ATTLIST doc a ( one | two | three ) #REQUIRED>\n"
2043 "]>"
2044 "<doc a='two'/>",
2045 XCS("doc"),
2046 XCS("a"),
2047 XCS("(one|two|three)"), /* Extraneous spaces will be removed */
2048 NULL,
2049 XML_TRUE
2050 },
2051 {
2052 "<!NOTATION foo SYSTEM 'http://example.org/foo'>\n"
2053 "<!ATTLIST doc a NOTATION (foo) #IMPLIED>\n"
2054 "]>"
2055 "<doc/>",
2056 XCS("doc"),
2057 XCS("a"),
2058 XCS("NOTATION(foo)"),
2059 NULL,
2060 XML_FALSE
2061 },
2062 {
2063 "<!ATTLIST doc a NOTATION (foo) 'bar'>\n"
2064 "]>"
2065 "<doc/>",
2066 XCS("doc"),
2067 XCS("a"),
2068 XCS("NOTATION(foo)"),
2069 XCS("bar"),
2070 XML_FALSE
2071 },
2072 {
2073 "<!ATTLIST doc a CDATA '\xdb\xb2'>\n"
2074 "]>"
2075 "<doc/>",
2076 XCS("doc"),
2077 XCS("a"),
2078 XCS("CDATA"),
2079 #ifdef XML_UNICODE
2080 XCS("\x06f2"),
2081 #else
2082 XCS("\xdb\xb2"),
2083 #endif
2084 XML_FALSE
2085 },
2086 { NULL, NULL, NULL, NULL, NULL, XML_FALSE }
2087 };
2088 AttTest *test;
2089
2090 for (test = attr_data; test->definition != NULL; test++) {
2091 XML_SetAttlistDeclHandler(parser, verify_attlist_decl_handler);
2092 XML_SetUserData(parser, test);
2093 if (_XML_Parse_SINGLE_BYTES(parser, prolog, (int)strlen(prolog),
2094 XML_FALSE) == XML_STATUS_ERROR)
2095 xml_failure(parser);
2096 if (_XML_Parse_SINGLE_BYTES(parser,
2097 test->definition,
2098 (int)strlen(test->definition),
2099 XML_TRUE) == XML_STATUS_ERROR)
2100 xml_failure(parser);
2101 XML_ParserReset(parser, NULL);
2102 }
2103 }
2104 END_TEST
2105
2106 /* See related SF bug #673791.
2107 When namespace processing is enabled, setting the namespace URI for
2108 a prefix is not allowed; this test ensures that it *is* allowed
2109 when namespace processing is not enabled.
2110 (See Namespaces in XML, section 2.)
2111 */
START_TEST(test_empty_ns_without_namespaces)2112 START_TEST(test_empty_ns_without_namespaces)
2113 {
2114 const char *text =
2115 "<doc xmlns:prefix='http://example.org/'>\n"
2116 " <e xmlns:prefix=''/>\n"
2117 "</doc>";
2118
2119 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR)
2120 xml_failure(parser);
2121 }
2122 END_TEST
2123
2124 /* Regression test for SF bug #824420.
2125 Checks that an xmlns:prefix attribute set in an attribute's default
2126 value isn't misinterpreted.
2127 */
START_TEST(test_ns_in_attribute_default_without_namespaces)2128 START_TEST(test_ns_in_attribute_default_without_namespaces)
2129 {
2130 const char *text =
2131 "<!DOCTYPE e:element [\n"
2132 " <!ATTLIST e:element\n"
2133 " xmlns:e CDATA 'http://example.org/'>\n"
2134 " ]>\n"
2135 "<e:element/>";
2136
2137 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR)
2138 xml_failure(parser);
2139 }
2140 END_TEST
2141
2142 static const char *long_character_data_text =
2143 "<?xml version='1.0' encoding='iso-8859-1'?><s>"
2144 "012345678901234567890123456789012345678901234567890123456789"
2145 "012345678901234567890123456789012345678901234567890123456789"
2146 "012345678901234567890123456789012345678901234567890123456789"
2147 "012345678901234567890123456789012345678901234567890123456789"
2148 "012345678901234567890123456789012345678901234567890123456789"
2149 "012345678901234567890123456789012345678901234567890123456789"
2150 "012345678901234567890123456789012345678901234567890123456789"
2151 "012345678901234567890123456789012345678901234567890123456789"
2152 "012345678901234567890123456789012345678901234567890123456789"
2153 "012345678901234567890123456789012345678901234567890123456789"
2154 "012345678901234567890123456789012345678901234567890123456789"
2155 "012345678901234567890123456789012345678901234567890123456789"
2156 "012345678901234567890123456789012345678901234567890123456789"
2157 "012345678901234567890123456789012345678901234567890123456789"
2158 "012345678901234567890123456789012345678901234567890123456789"
2159 "012345678901234567890123456789012345678901234567890123456789"
2160 "012345678901234567890123456789012345678901234567890123456789"
2161 "012345678901234567890123456789012345678901234567890123456789"
2162 "012345678901234567890123456789012345678901234567890123456789"
2163 "012345678901234567890123456789012345678901234567890123456789"
2164 "</s>";
2165
2166 static XML_Bool resumable = XML_FALSE;
2167
2168 static void
clearing_aborting_character_handler(void * UNUSED_P (userData),const XML_Char * UNUSED_P (s),int UNUSED_P (len))2169 clearing_aborting_character_handler(void *UNUSED_P(userData),
2170 const XML_Char *UNUSED_P(s), int UNUSED_P(len))
2171 {
2172 XML_StopParser(parser, resumable);
2173 XML_SetCharacterDataHandler(parser, NULL);
2174 }
2175
2176 /* Regression test for SF bug #1515266: missing check of stopped
2177 parser in doContext() 'for' loop. */
START_TEST(test_stop_parser_between_char_data_calls)2178 START_TEST(test_stop_parser_between_char_data_calls)
2179 {
2180 /* The sample data must be big enough that there are two calls to
2181 the character data handler from within the inner "for" loop of
2182 the XML_TOK_DATA_CHARS case in doContent(), and the character
2183 handler must stop the parser and clear the character data
2184 handler.
2185 */
2186 const char *text = long_character_data_text;
2187
2188 XML_SetCharacterDataHandler(parser, clearing_aborting_character_handler);
2189 resumable = XML_FALSE;
2190 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR)
2191 xml_failure(parser);
2192 if (XML_GetErrorCode(parser) != XML_ERROR_ABORTED)
2193 xml_failure(parser);
2194 }
2195 END_TEST
2196
2197 /* Regression test for SF bug #1515266: missing check of stopped
2198 parser in doContext() 'for' loop. */
START_TEST(test_suspend_parser_between_char_data_calls)2199 START_TEST(test_suspend_parser_between_char_data_calls)
2200 {
2201 /* The sample data must be big enough that there are two calls to
2202 the character data handler from within the inner "for" loop of
2203 the XML_TOK_DATA_CHARS case in doContent(), and the character
2204 handler must stop the parser and clear the character data
2205 handler.
2206 */
2207 const char *text = long_character_data_text;
2208
2209 XML_SetCharacterDataHandler(parser, clearing_aborting_character_handler);
2210 resumable = XML_TRUE;
2211 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_SUSPENDED)
2212 xml_failure(parser);
2213 if (XML_GetErrorCode(parser) != XML_ERROR_NONE)
2214 xml_failure(parser);
2215 /* Try parsing directly */
2216 if (XML_Parse(parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR)
2217 fail("Attempt to continue parse while suspended not faulted");
2218 if (XML_GetErrorCode(parser) != XML_ERROR_SUSPENDED)
2219 fail("Suspended parse not faulted with correct error");
2220 }
2221 END_TEST
2222
2223
2224 static XML_Bool abortable = XML_FALSE;
2225
2226 static void
parser_stop_character_handler(void * UNUSED_P (userData),const XML_Char * UNUSED_P (s),int UNUSED_P (len))2227 parser_stop_character_handler(void *UNUSED_P(userData),
2228 const XML_Char *UNUSED_P(s),
2229 int UNUSED_P(len))
2230 {
2231 XML_StopParser(parser, resumable);
2232 XML_SetCharacterDataHandler(parser, NULL);
2233 if (!resumable) {
2234 /* Check that aborting an aborted parser is faulted */
2235 if (XML_StopParser(parser, XML_FALSE) != XML_STATUS_ERROR)
2236 fail("Aborting aborted parser not faulted");
2237 if (XML_GetErrorCode(parser) != XML_ERROR_FINISHED)
2238 xml_failure(parser);
2239 } else if (abortable) {
2240 /* Check that aborting a suspended parser works */
2241 if (XML_StopParser(parser, XML_FALSE) == XML_STATUS_ERROR)
2242 xml_failure(parser);
2243 } else {
2244 /* Check that suspending a suspended parser works */
2245 if (XML_StopParser(parser, XML_TRUE) != XML_STATUS_ERROR)
2246 fail("Suspending suspended parser not faulted");
2247 if (XML_GetErrorCode(parser) != XML_ERROR_SUSPENDED)
2248 xml_failure(parser);
2249 }
2250 }
2251
2252 /* Test repeated calls to XML_StopParser are handled correctly */
START_TEST(test_repeated_stop_parser_between_char_data_calls)2253 START_TEST(test_repeated_stop_parser_between_char_data_calls)
2254 {
2255 const char *text = long_character_data_text;
2256
2257 XML_SetCharacterDataHandler(parser, parser_stop_character_handler);
2258 resumable = XML_FALSE;
2259 abortable = XML_FALSE;
2260 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
2261 XML_TRUE) != XML_STATUS_ERROR)
2262 fail("Failed to double-stop parser");
2263
2264 XML_ParserReset(parser, NULL);
2265 XML_SetCharacterDataHandler(parser, parser_stop_character_handler);
2266 resumable = XML_TRUE;
2267 abortable = XML_FALSE;
2268 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
2269 XML_TRUE) != XML_STATUS_SUSPENDED)
2270 fail("Failed to double-suspend parser");
2271
2272 XML_ParserReset(parser, NULL);
2273 XML_SetCharacterDataHandler(parser, parser_stop_character_handler);
2274 resumable = XML_TRUE;
2275 abortable = XML_TRUE;
2276 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
2277 XML_TRUE) != XML_STATUS_ERROR)
2278 fail("Failed to suspend-abort parser");
2279 }
2280 END_TEST
2281
2282
START_TEST(test_good_cdata_ascii)2283 START_TEST(test_good_cdata_ascii)
2284 {
2285 const char *text = "<a><![CDATA[<greeting>Hello, world!</greeting>]]></a>";
2286 const XML_Char *expected = XCS("<greeting>Hello, world!</greeting>");
2287
2288 CharData storage;
2289 CharData_Init(&storage);
2290 XML_SetUserData(parser, &storage);
2291 XML_SetCharacterDataHandler(parser, accumulate_characters);
2292 /* Add start and end handlers for coverage */
2293 XML_SetStartCdataSectionHandler(parser, dummy_start_cdata_handler);
2294 XML_SetEndCdataSectionHandler(parser, dummy_end_cdata_handler);
2295
2296 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR)
2297 xml_failure(parser);
2298 CharData_CheckXMLChars(&storage, expected);
2299
2300 /* Try again, this time with a default handler */
2301 XML_ParserReset(parser, NULL);
2302 CharData_Init(&storage);
2303 XML_SetUserData(parser, &storage);
2304 XML_SetCharacterDataHandler(parser, accumulate_characters);
2305 XML_SetDefaultHandler(parser, dummy_default_handler);
2306
2307 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR)
2308 xml_failure(parser);
2309 CharData_CheckXMLChars(&storage, expected);
2310 }
2311 END_TEST
2312
START_TEST(test_good_cdata_utf16)2313 START_TEST(test_good_cdata_utf16)
2314 {
2315 /* Test data is:
2316 * <?xml version='1.0' encoding='utf-16'?>
2317 * <a><![CDATA[hello]]></a>
2318 */
2319 const char text[] =
2320 "\0<\0?\0x\0m\0l\0"
2321 " \0v\0e\0r\0s\0i\0o\0n\0=\0'\0\x31\0.\0\x30\0'\0"
2322 " \0e\0n\0c\0o\0d\0i\0n\0g\0=\0'\0u\0t\0f\0-\0""1\0""6\0'"
2323 "\0?\0>\0\n"
2324 "\0<\0a\0>\0<\0!\0[\0C\0D\0A\0T\0A\0[\0h\0e\0l\0l\0o\0]\0]\0>\0<\0/\0a\0>";
2325 const XML_Char *expected = XCS("hello");
2326
2327 CharData storage;
2328 CharData_Init(&storage);
2329 XML_SetUserData(parser, &storage);
2330 XML_SetCharacterDataHandler(parser, accumulate_characters);
2331
2332 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text) - 1, XML_TRUE) == XML_STATUS_ERROR)
2333 xml_failure(parser);
2334 CharData_CheckXMLChars(&storage, expected);
2335 }
2336 END_TEST
2337
START_TEST(test_good_cdata_utf16_le)2338 START_TEST(test_good_cdata_utf16_le)
2339 {
2340 /* Test data is:
2341 * <?xml version='1.0' encoding='utf-16'?>
2342 * <a><![CDATA[hello]]></a>
2343 */
2344 const char text[] =
2345 "<\0?\0x\0m\0l\0"
2346 " \0v\0e\0r\0s\0i\0o\0n\0=\0'\0\x31\0.\0\x30\0'\0"
2347 " \0e\0n\0c\0o\0d\0i\0n\0g\0=\0'\0u\0t\0f\0-\0""1\0""6\0'"
2348 "\0?\0>\0\n"
2349 "\0<\0a\0>\0<\0!\0[\0C\0D\0A\0T\0A\0[\0h\0e\0l\0l\0o\0]\0]\0>\0<\0/\0a\0>\0";
2350 const XML_Char *expected = XCS("hello");
2351
2352 CharData storage;
2353 CharData_Init(&storage);
2354 XML_SetUserData(parser, &storage);
2355 XML_SetCharacterDataHandler(parser, accumulate_characters);
2356
2357 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text) - 1, XML_TRUE) == XML_STATUS_ERROR)
2358 xml_failure(parser);
2359 CharData_CheckXMLChars(&storage, expected);
2360 }
2361 END_TEST
2362
2363 /* Test UTF16 conversion of a long cdata string */
2364
2365 /* 16 characters: handy macro to reduce visual clutter */
2366 #define A_TO_P_IN_UTF16 "\0A\0B\0C\0D\0E\0F\0G\0H\0I\0J\0K\0L\0M\0N\0O\0P"
2367
START_TEST(test_long_cdata_utf16)2368 START_TEST(test_long_cdata_utf16)
2369 {
2370 /* Test data is:
2371 * <?xlm version='1.0' encoding='utf-16'?>
2372 * <a><![CDATA[
2373 * ABCDEFGHIJKLMNOP
2374 * ]]></a>
2375 */
2376 const char text[] =
2377 "\0<\0?\0x\0m\0l\0 "
2378 "\0v\0e\0r\0s\0i\0o\0n\0=\0'\0\x31\0.\0\x30\0'\0 "
2379 "\0e\0n\0c\0o\0d\0i\0n\0g\0=\0'\0u\0t\0f\0-\0\x31\0\x36\0'\0?\0>"
2380 "\0<\0a\0>\0<\0!\0[\0C\0D\0A\0T\0A\0["
2381 /* 64 characters per line */
2382 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16
2383 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16
2384 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16
2385 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16
2386 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16
2387 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16
2388 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16
2389 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16
2390 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16
2391 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16
2392 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16
2393 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16
2394 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16
2395 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16
2396 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16
2397 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16 A_TO_P_IN_UTF16
2398 A_TO_P_IN_UTF16
2399 "\0]\0]\0>\0<\0/\0a\0>";
2400 const XML_Char *expected =
2401 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
2402 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
2403 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
2404 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
2405 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
2406 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
2407 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
2408 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
2409 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
2410 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
2411 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
2412 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
2413 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
2414 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
2415 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
2416 XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
2417 XCS("ABCDEFGHIJKLMNOP";)
2418 CharData storage;
2419 void *buffer;
2420
2421 CharData_Init(&storage);
2422 XML_SetUserData(parser, &storage);
2423 XML_SetCharacterDataHandler(parser, accumulate_characters);
2424 buffer = XML_GetBuffer(parser, sizeof(text) - 1);
2425 if (buffer == NULL)
2426 fail("Could not allocate parse buffer");
2427 memcpy(buffer, text, sizeof(text) - 1);
2428 if (XML_ParseBuffer(parser,
2429 sizeof(text) - 1,
2430 XML_TRUE) == XML_STATUS_ERROR)
2431 xml_failure(parser);
2432 CharData_CheckXMLChars(&storage, expected);
2433 }
2434 END_TEST
2435
2436 /* Test handling of multiple unit UTF-16 characters */
START_TEST(test_multichar_cdata_utf16)2437 START_TEST(test_multichar_cdata_utf16)
2438 {
2439 /* Test data is:
2440 * <?xml version='1.0' encoding='utf-16'?>
2441 * <a><![CDATA[{MINIM}{CROTCHET}]]></a>
2442 *
2443 * where {MINIM} is U+1d15e (a minim or half-note)
2444 * UTF-16: 0xd834 0xdd5e
2445 * UTF-8: 0xf0 0x9d 0x85 0x9e
2446 * and {CROTCHET} is U+1d15f (a crotchet or quarter-note)
2447 * UTF-16: 0xd834 0xdd5f
2448 * UTF-8: 0xf0 0x9d 0x85 0x9f
2449 */
2450 const char text[] =
2451 "\0<\0?\0x\0m\0l\0"
2452 " \0v\0e\0r\0s\0i\0o\0n\0=\0'\0\x31\0.\0\x30\0'\0"
2453 " \0e\0n\0c\0o\0d\0i\0n\0g\0=\0'\0u\0t\0f\0-\0""1\0""6\0'"
2454 "\0?\0>\0\n"
2455 "\0<\0a\0>\0<\0!\0[\0C\0D\0A\0T\0A\0["
2456 "\xd8\x34\xdd\x5e\xd8\x34\xdd\x5f"
2457 "\0]\0]\0>\0<\0/\0a\0>";
2458 #ifdef XML_UNICODE
2459 const XML_Char *expected = XCS("\xd834\xdd5e\xd834\xdd5f");
2460 #else
2461 const XML_Char *expected = XCS("\xf0\x9d\x85\x9e\xf0\x9d\x85\x9f");
2462 #endif
2463 CharData storage;
2464
2465 CharData_Init(&storage);
2466 XML_SetUserData(parser, &storage);
2467 XML_SetCharacterDataHandler(parser, accumulate_characters);
2468
2469 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text) - 1, XML_TRUE) == XML_STATUS_ERROR)
2470 xml_failure(parser);
2471 CharData_CheckXMLChars(&storage, expected);
2472 }
2473 END_TEST
2474
2475 /* Test that an element name with a UTF-16 surrogate pair is rejected */
START_TEST(test_utf16_bad_surrogate_pair)2476 START_TEST(test_utf16_bad_surrogate_pair)
2477 {
2478 /* Test data is:
2479 * <?xml version='1.0' encoding='utf-16'?>
2480 * <a><![CDATA[{BADLINB}]]></a>
2481 *
2482 * where {BADLINB} is U+10000 (the first Linear B character)
2483 * with the UTF-16 surrogate pair in the wrong order, i.e.
2484 * 0xdc00 0xd800
2485 */
2486 const char text[] =
2487 "\0<\0?\0x\0m\0l\0"
2488 " \0v\0e\0r\0s\0i\0o\0n\0=\0'\0\x31\0.\0\x30\0'\0"
2489 " \0e\0n\0c\0o\0d\0i\0n\0g\0=\0'\0u\0t\0f\0-\0""1\0""6\0'"
2490 "\0?\0>\0\n"
2491 "\0<\0a\0>\0<\0!\0[\0C\0D\0A\0T\0A\0["
2492 "\xdc\x00\xd8\x00"
2493 "\0]\0]\0>\0<\0/\0a\0>";
2494
2495 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text) - 1,
2496 XML_TRUE) != XML_STATUS_ERROR)
2497 fail("Reversed UTF-16 surrogate pair not faulted");
2498 if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_TOKEN)
2499 xml_failure(parser);
2500 }
2501 END_TEST
2502
2503
START_TEST(test_bad_cdata)2504 START_TEST(test_bad_cdata)
2505 {
2506 struct CaseData {
2507 const char *text;
2508 enum XML_Error expectedError;
2509 };
2510
2511 struct CaseData cases[] = {
2512 {"<a><", XML_ERROR_UNCLOSED_TOKEN},
2513 {"<a><!", XML_ERROR_UNCLOSED_TOKEN},
2514 {"<a><![", XML_ERROR_UNCLOSED_TOKEN},
2515 {"<a><![C", XML_ERROR_UNCLOSED_TOKEN},
2516 {"<a><![CD", XML_ERROR_UNCLOSED_TOKEN},
2517 {"<a><![CDA", XML_ERROR_UNCLOSED_TOKEN},
2518 {"<a><![CDAT", XML_ERROR_UNCLOSED_TOKEN},
2519 {"<a><![CDATA", XML_ERROR_UNCLOSED_TOKEN},
2520
2521 {"<a><![CDATA[", XML_ERROR_UNCLOSED_CDATA_SECTION},
2522 {"<a><![CDATA[]", XML_ERROR_UNCLOSED_CDATA_SECTION},
2523 {"<a><![CDATA[]]", XML_ERROR_UNCLOSED_CDATA_SECTION},
2524
2525 {"<a><!<a/>", XML_ERROR_INVALID_TOKEN},
2526 {"<a><![<a/>", XML_ERROR_UNCLOSED_TOKEN}, /* ?! */
2527 {"<a><![C<a/>", XML_ERROR_UNCLOSED_TOKEN}, /* ?! */
2528 {"<a><![CD<a/>", XML_ERROR_INVALID_TOKEN},
2529 {"<a><![CDA<a/>", XML_ERROR_INVALID_TOKEN},
2530 {"<a><![CDAT<a/>", XML_ERROR_INVALID_TOKEN},
2531 {"<a><![CDATA<a/>", XML_ERROR_INVALID_TOKEN},
2532
2533 {"<a><![CDATA[<a/>", XML_ERROR_UNCLOSED_CDATA_SECTION},
2534 {"<a><![CDATA[]<a/>", XML_ERROR_UNCLOSED_CDATA_SECTION},
2535 {"<a><![CDATA[]]<a/>", XML_ERROR_UNCLOSED_CDATA_SECTION}
2536 };
2537
2538 size_t i = 0;
2539 for (; i < sizeof(cases) / sizeof(struct CaseData); i++) {
2540 const enum XML_Status actualStatus = _XML_Parse_SINGLE_BYTES(
2541 parser, cases[i].text, (int)strlen(cases[i].text), XML_TRUE);
2542 const enum XML_Error actualError = XML_GetErrorCode(parser);
2543
2544 assert(actualStatus == XML_STATUS_ERROR);
2545
2546 if (actualError != cases[i].expectedError) {
2547 char message[100];
2548 sprintf(message, "Expected error %d but got error %d for case %u: \"%s\"\n",
2549 cases[i].expectedError, actualError, (unsigned int)i + 1, cases[i].text);
2550 fail(message);
2551 }
2552
2553 XML_ParserReset(parser, NULL);
2554 }
2555 }
2556 END_TEST
2557
2558 /* Test failures in UTF-16 CDATA */
START_TEST(test_bad_cdata_utf16)2559 START_TEST(test_bad_cdata_utf16)
2560 {
2561 struct CaseData {
2562 size_t text_bytes;
2563 const char *text;
2564 enum XML_Error expected_error;
2565 };
2566
2567 const char prolog[] =
2568 "\0<\0?\0x\0m\0l\0"
2569 " \0v\0e\0r\0s\0i\0o\0n\0=\0'\0\x31\0.\0\x30\0'\0"
2570 " \0e\0n\0c\0o\0d\0i\0n\0g\0=\0'\0u\0t\0f\0-\0""1\0""6\0'"
2571 "\0?\0>\0\n"
2572 "\0<\0a\0>";
2573 struct CaseData cases[] = {
2574 {1, "\0", XML_ERROR_UNCLOSED_TOKEN},
2575 {2, "\0<", XML_ERROR_UNCLOSED_TOKEN},
2576 {3, "\0<\0", XML_ERROR_UNCLOSED_TOKEN},
2577 {4, "\0<\0!", XML_ERROR_UNCLOSED_TOKEN},
2578 {5, "\0<\0!\0", XML_ERROR_UNCLOSED_TOKEN},
2579 {6, "\0<\0!\0[", XML_ERROR_UNCLOSED_TOKEN},
2580 {7, "\0<\0!\0[\0", XML_ERROR_UNCLOSED_TOKEN},
2581 {8, "\0<\0!\0[\0C", XML_ERROR_UNCLOSED_TOKEN},
2582 {9, "\0<\0!\0[\0C\0", XML_ERROR_UNCLOSED_TOKEN},
2583 {10, "\0<\0!\0[\0C\0D", XML_ERROR_UNCLOSED_TOKEN},
2584 {11, "\0<\0!\0[\0C\0D\0", XML_ERROR_UNCLOSED_TOKEN},
2585 {12, "\0<\0!\0[\0C\0D\0A", XML_ERROR_UNCLOSED_TOKEN},
2586 {13, "\0<\0!\0[\0C\0D\0A\0", XML_ERROR_UNCLOSED_TOKEN},
2587 {14, "\0<\0!\0[\0C\0D\0A\0T", XML_ERROR_UNCLOSED_TOKEN},
2588 {15, "\0<\0!\0[\0C\0D\0A\0T\0", XML_ERROR_UNCLOSED_TOKEN},
2589 {16, "\0<\0!\0[\0C\0D\0A\0T\0A", XML_ERROR_UNCLOSED_TOKEN},
2590 {17, "\0<\0!\0[\0C\0D\0A\0T\0A\0", XML_ERROR_UNCLOSED_TOKEN},
2591 {18, "\0<\0!\0[\0C\0D\0A\0T\0A\0[",
2592 XML_ERROR_UNCLOSED_CDATA_SECTION},
2593 {19, "\0<\0!\0[\0C\0D\0A\0T\0A\0[\0",
2594 XML_ERROR_UNCLOSED_CDATA_SECTION},
2595 {20, "\0<\0!\0[\0C\0D\0A\0T\0A\0[\0Z",
2596 XML_ERROR_UNCLOSED_CDATA_SECTION},
2597 /* Now add a four-byte UTF-16 character */
2598 {21, "\0<\0!\0[\0C\0D\0A\0T\0A\0[\0Z\xd8",
2599 XML_ERROR_UNCLOSED_CDATA_SECTION},
2600 {22, "\0<\0!\0[\0C\0D\0A\0T\0A\0[\0Z\xd8\x34",
2601 XML_ERROR_PARTIAL_CHAR},
2602 {23, "\0<\0!\0[\0C\0D\0A\0T\0A\0[\0Z\xd8\x34\xdd",
2603 XML_ERROR_PARTIAL_CHAR},
2604 {24, "\0<\0!\0[\0C\0D\0A\0T\0A\0[\0Z\xd8\x34\xdd\x5e",
2605 XML_ERROR_UNCLOSED_CDATA_SECTION}
2606 };
2607 size_t i;
2608
2609 for (i = 0; i < sizeof(cases)/sizeof(struct CaseData); i++) {
2610 enum XML_Status actual_status;
2611 enum XML_Error actual_error;
2612
2613 if (_XML_Parse_SINGLE_BYTES(parser, prolog, (int)sizeof(prolog)-1,
2614 XML_FALSE) == XML_STATUS_ERROR)
2615 xml_failure(parser);
2616 actual_status = _XML_Parse_SINGLE_BYTES(parser,
2617 cases[i].text,
2618 (int)cases[i].text_bytes,
2619 XML_TRUE);
2620 assert(actual_status == XML_STATUS_ERROR);
2621 actual_error = XML_GetErrorCode(parser);
2622 if (actual_error != cases[i].expected_error) {
2623 char message[1024];
2624
2625 sprintf(message,
2626 "Expected error %d (%" XML_FMT_STR
2627 "), got %d (%" XML_FMT_STR ") for case %lu\n",
2628 cases[i].expected_error,
2629 XML_ErrorString(cases[i].expected_error),
2630 actual_error,
2631 XML_ErrorString(actual_error),
2632 (long unsigned)(i+1));
2633 fail(message);
2634 }
2635 XML_ParserReset(parser, NULL);
2636 }
2637 }
2638 END_TEST
2639
2640 static const char *long_cdata_text =
2641 "<s><![CDATA["
2642 "012345678901234567890123456789012345678901234567890123456789"
2643 "012345678901234567890123456789012345678901234567890123456789"
2644 "012345678901234567890123456789012345678901234567890123456789"
2645 "012345678901234567890123456789012345678901234567890123456789"
2646 "012345678901234567890123456789012345678901234567890123456789"
2647 "012345678901234567890123456789012345678901234567890123456789"
2648 "012345678901234567890123456789012345678901234567890123456789"
2649 "012345678901234567890123456789012345678901234567890123456789"
2650 "012345678901234567890123456789012345678901234567890123456789"
2651 "012345678901234567890123456789012345678901234567890123456789"
2652 "012345678901234567890123456789012345678901234567890123456789"
2653 "012345678901234567890123456789012345678901234567890123456789"
2654 "012345678901234567890123456789012345678901234567890123456789"
2655 "012345678901234567890123456789012345678901234567890123456789"
2656 "012345678901234567890123456789012345678901234567890123456789"
2657 "012345678901234567890123456789012345678901234567890123456789"
2658 "012345678901234567890123456789012345678901234567890123456789"
2659 "012345678901234567890123456789012345678901234567890123456789"
2660 "012345678901234567890123456789012345678901234567890123456789"
2661 "012345678901234567890123456789012345678901234567890123456789"
2662 "]]></s>";
2663
2664 /* Test stopping the parser in cdata handler */
START_TEST(test_stop_parser_between_cdata_calls)2665 START_TEST(test_stop_parser_between_cdata_calls)
2666 {
2667 const char *text = long_cdata_text;
2668
2669 XML_SetCharacterDataHandler(parser,
2670 clearing_aborting_character_handler);
2671 resumable = XML_FALSE;
2672 expect_failure(text, XML_ERROR_ABORTED,
2673 "Parse not aborted in CDATA handler");
2674 }
2675 END_TEST
2676
2677 /* Test suspending the parser in cdata handler */
START_TEST(test_suspend_parser_between_cdata_calls)2678 START_TEST(test_suspend_parser_between_cdata_calls)
2679 {
2680 const char *text = long_cdata_text;
2681 enum XML_Status result;
2682
2683 XML_SetCharacterDataHandler(parser,
2684 clearing_aborting_character_handler);
2685 resumable = XML_TRUE;
2686 result = _XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE);
2687 if (result != XML_STATUS_SUSPENDED) {
2688 if (result == XML_STATUS_ERROR)
2689 xml_failure(parser);
2690 fail("Parse not suspended in CDATA handler");
2691 }
2692 if (XML_GetErrorCode(parser) != XML_ERROR_NONE)
2693 xml_failure(parser);
2694 }
2695 END_TEST
2696
2697 /* Test memory allocation functions */
START_TEST(test_memory_allocation)2698 START_TEST(test_memory_allocation)
2699 {
2700 char *buffer = (char *)XML_MemMalloc(parser, 256);
2701 char *p;
2702
2703 if (buffer == NULL) {
2704 fail("Allocation failed");
2705 } else {
2706 /* Try writing to memory; some OSes try to cheat! */
2707 buffer[0] = 'T';
2708 buffer[1] = 'E';
2709 buffer[2] = 'S';
2710 buffer[3] = 'T';
2711 buffer[4] = '\0';
2712 if (strcmp(buffer, "TEST") != 0) {
2713 fail("Memory not writable");
2714 } else {
2715 p = (char *)XML_MemRealloc(parser, buffer, 512);
2716 if (p == NULL) {
2717 fail("Reallocation failed");
2718 } else {
2719 /* Write again, just to be sure */
2720 buffer = p;
2721 buffer[0] = 'V';
2722 if (strcmp(buffer, "VEST") != 0) {
2723 fail("Reallocated memory not writable");
2724 }
2725 }
2726 }
2727 XML_MemFree(parser, buffer);
2728 }
2729 }
2730 END_TEST
2731
2732 static void XMLCALL
record_default_handler(void * userData,const XML_Char * UNUSED_P (s),int UNUSED_P (len))2733 record_default_handler(void *userData,
2734 const XML_Char *UNUSED_P(s),
2735 int UNUSED_P(len))
2736 {
2737 CharData_AppendXMLChars((CharData *)userData, XCS("D"), 1);
2738 }
2739
2740 static void XMLCALL
record_cdata_handler(void * userData,const XML_Char * UNUSED_P (s),int UNUSED_P (len))2741 record_cdata_handler(void *userData,
2742 const XML_Char *UNUSED_P(s),
2743 int UNUSED_P(len))
2744 {
2745 CharData_AppendXMLChars((CharData *)userData, XCS("C"), 1);
2746 XML_DefaultCurrent(parser);
2747 }
2748
2749 static void XMLCALL
record_cdata_nodefault_handler(void * userData,const XML_Char * UNUSED_P (s),int UNUSED_P (len))2750 record_cdata_nodefault_handler(void *userData,
2751 const XML_Char *UNUSED_P(s),
2752 int UNUSED_P(len))
2753 {
2754 CharData_AppendXMLChars((CharData *)userData, XCS("c"), 1);
2755 }
2756
2757 static void XMLCALL
record_skip_handler(void * userData,const XML_Char * UNUSED_P (entityName),int is_parameter_entity)2758 record_skip_handler(void *userData,
2759 const XML_Char *UNUSED_P(entityName),
2760 int is_parameter_entity)
2761 {
2762 CharData_AppendXMLChars((CharData *)userData,
2763 is_parameter_entity ? XCS("E") : XCS("e"), 1);
2764 }
2765
2766 /* Test XML_DefaultCurrent() passes handling on correctly */
START_TEST(test_default_current)2767 START_TEST(test_default_current)
2768 {
2769 const char *text = "<doc>hell]</doc>";
2770 const char *entity_text =
2771 "<!DOCTYPE doc [\n"
2772 "<!ENTITY entity '%'>\n"
2773 "]>\n"
2774 "<doc>&entity;</doc>";
2775 CharData storage;
2776
2777 XML_SetDefaultHandler(parser, record_default_handler);
2778 XML_SetCharacterDataHandler(parser, record_cdata_handler);
2779 CharData_Init(&storage);
2780 XML_SetUserData(parser, &storage);
2781 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
2782 XML_TRUE) == XML_STATUS_ERROR)
2783 xml_failure(parser);
2784 CharData_CheckXMLChars(&storage, XCS("DCDCDCDCDCDD"));
2785
2786 /* Again, without the defaulting */
2787 XML_ParserReset(parser, NULL);
2788 XML_SetDefaultHandler(parser, record_default_handler);
2789 XML_SetCharacterDataHandler(parser, record_cdata_nodefault_handler);
2790 CharData_Init(&storage);
2791 XML_SetUserData(parser, &storage);
2792 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
2793 XML_TRUE) == XML_STATUS_ERROR)
2794 xml_failure(parser);
2795 CharData_CheckXMLChars(&storage, XCS("DcccccD"));
2796
2797 /* Now with an internal entity to complicate matters */
2798 XML_ParserReset(parser, NULL);
2799 XML_SetDefaultHandler(parser, record_default_handler);
2800 XML_SetCharacterDataHandler(parser, record_cdata_handler);
2801 CharData_Init(&storage);
2802 XML_SetUserData(parser, &storage);
2803 if (_XML_Parse_SINGLE_BYTES(parser, entity_text, (int)strlen(entity_text),
2804 XML_TRUE) == XML_STATUS_ERROR)
2805 xml_failure(parser);
2806 /* The default handler suppresses the entity */
2807 CharData_CheckXMLChars(&storage, XCS("DDDDDDDDDDDDDDDDDDD"));
2808
2809 /* Again, with a skip handler */
2810 XML_ParserReset(parser, NULL);
2811 XML_SetDefaultHandler(parser, record_default_handler);
2812 XML_SetCharacterDataHandler(parser, record_cdata_handler);
2813 XML_SetSkippedEntityHandler(parser, record_skip_handler);
2814 CharData_Init(&storage);
2815 XML_SetUserData(parser, &storage);
2816 if (_XML_Parse_SINGLE_BYTES(parser, entity_text, (int)strlen(entity_text),
2817 XML_TRUE) == XML_STATUS_ERROR)
2818 xml_failure(parser);
2819 /* The default handler suppresses the entity */
2820 CharData_CheckXMLChars(&storage, XCS("DDDDDDDDDDDDDDDDDeD"));
2821
2822 /* This time, allow the entity through */
2823 XML_ParserReset(parser, NULL);
2824 XML_SetDefaultHandlerExpand(parser, record_default_handler);
2825 XML_SetCharacterDataHandler(parser, record_cdata_handler);
2826 CharData_Init(&storage);
2827 XML_SetUserData(parser, &storage);
2828 if (_XML_Parse_SINGLE_BYTES(parser, entity_text, (int)strlen(entity_text),
2829 XML_TRUE) == XML_STATUS_ERROR)
2830 xml_failure(parser);
2831 CharData_CheckXMLChars(&storage, XCS("DDDDDDDDDDDDDDDDDCDD"));
2832
2833 /* Finally, without passing the cdata to the default handler */
2834 XML_ParserReset(parser, NULL);
2835 XML_SetDefaultHandlerExpand(parser, record_default_handler);
2836 XML_SetCharacterDataHandler(parser, record_cdata_nodefault_handler);
2837 CharData_Init(&storage);
2838 XML_SetUserData(parser, &storage);
2839 if (_XML_Parse_SINGLE_BYTES(parser, entity_text, (int)strlen(entity_text),
2840 XML_TRUE) == XML_STATUS_ERROR)
2841 xml_failure(parser);
2842 CharData_CheckXMLChars(&storage, XCS("DDDDDDDDDDDDDDDDDcD"));
2843 }
2844 END_TEST
2845
2846 /* Test DTD element parsing code paths */
START_TEST(test_dtd_elements)2847 START_TEST(test_dtd_elements)
2848 {
2849 const char *text =
2850 "<!DOCTYPE doc [\n"
2851 "<!ELEMENT doc (chapter)>\n"
2852 "<!ELEMENT chapter (#PCDATA)>\n"
2853 "]>\n"
2854 "<doc><chapter>Wombats are go</chapter></doc>";
2855
2856 XML_SetElementDeclHandler(parser, dummy_element_decl_handler);
2857 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
2858 XML_TRUE) == XML_STATUS_ERROR)
2859 xml_failure(parser);
2860 }
2861 END_TEST
2862
2863 /* Test foreign DTD handling */
START_TEST(test_set_foreign_dtd)2864 START_TEST(test_set_foreign_dtd)
2865 {
2866 const char *text1 =
2867 "<?xml version='1.0' encoding='us-ascii'?>\n";
2868 const char *text2 =
2869 "<doc>&entity;</doc>";
2870 ExtTest test_data = {
2871 "<!ELEMENT doc (#PCDATA)*>",
2872 NULL,
2873 NULL
2874 };
2875
2876 /* Check hash salt is passed through too */
2877 XML_SetHashSalt(parser, 0x12345678);
2878 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
2879 XML_SetUserData(parser, &test_data);
2880 XML_SetExternalEntityRefHandler(parser, external_entity_loader);
2881 /* Add a default handler to exercise more code paths */
2882 XML_SetDefaultHandler(parser, dummy_default_handler);
2883 if (XML_UseForeignDTD(parser, XML_TRUE) != XML_ERROR_NONE)
2884 fail("Could not set foreign DTD");
2885 if (_XML_Parse_SINGLE_BYTES(parser, text1, (int)strlen(text1),
2886 XML_FALSE) == XML_STATUS_ERROR)
2887 xml_failure(parser);
2888
2889 /* Ensure that trying to set the DTD after parsing has started
2890 * is faulted, even if it's the same setting.
2891 */
2892 if (XML_UseForeignDTD(parser, XML_TRUE) !=
2893 XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING)
2894 fail("Failed to reject late foreign DTD setting");
2895 /* Ditto for the hash salt */
2896 if (XML_SetHashSalt(parser, 0x23456789))
2897 fail("Failed to reject late hash salt change");
2898
2899 /* Now finish the parse */
2900 if (_XML_Parse_SINGLE_BYTES(parser, text2, (int)strlen(text2),
2901 XML_TRUE) == XML_STATUS_ERROR)
2902 xml_failure(parser);
2903 }
2904 END_TEST
2905
2906 /* Test foreign DTD handling with a failing NotStandalone handler */
START_TEST(test_foreign_dtd_not_standalone)2907 START_TEST(test_foreign_dtd_not_standalone)
2908 {
2909 const char *text =
2910 "<?xml version='1.0' encoding='us-ascii'?>\n"
2911 "<doc>&entity;</doc>";
2912 ExtTest test_data = {
2913 "<!ELEMENT doc (#PCDATA)*>",
2914 NULL,
2915 NULL
2916 };
2917
2918 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
2919 XML_SetUserData(parser, &test_data);
2920 XML_SetExternalEntityRefHandler(parser, external_entity_loader);
2921 XML_SetNotStandaloneHandler(parser, reject_not_standalone_handler);
2922 if (XML_UseForeignDTD(parser, XML_TRUE) != XML_ERROR_NONE)
2923 fail("Could not set foreign DTD");
2924 expect_failure(text, XML_ERROR_NOT_STANDALONE,
2925 "NotStandalonehandler failed to reject");
2926 }
2927 END_TEST
2928
2929 /* Test invalid character in a foreign DTD is faulted */
START_TEST(test_invalid_foreign_dtd)2930 START_TEST(test_invalid_foreign_dtd)
2931 {
2932 const char *text =
2933 "<?xml version='1.0' encoding='us-ascii'?>\n"
2934 "<doc>&entity;</doc>";
2935 ExtFaults test_data = {
2936 "$",
2937 "Dollar not faulted",
2938 NULL,
2939 XML_ERROR_INVALID_TOKEN
2940 };
2941
2942 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
2943 XML_SetUserData(parser, &test_data);
2944 XML_SetExternalEntityRefHandler(parser, external_entity_faulter);
2945 XML_UseForeignDTD(parser, XML_TRUE);
2946 expect_failure(text,
2947 XML_ERROR_EXTERNAL_ENTITY_HANDLING,
2948 "Bad DTD should not have been accepted");
2949 }
2950 END_TEST
2951
2952 /* Test foreign DTD use with a doctype */
START_TEST(test_foreign_dtd_with_doctype)2953 START_TEST(test_foreign_dtd_with_doctype)
2954 {
2955 const char *text1 =
2956 "<?xml version='1.0' encoding='us-ascii'?>\n"
2957 "<!DOCTYPE doc [<!ENTITY entity 'hello world'>]>\n";
2958 const char *text2 =
2959 "<doc>&entity;</doc>";
2960 ExtTest test_data = {
2961 "<!ELEMENT doc (#PCDATA)*>",
2962 NULL,
2963 NULL
2964 };
2965
2966 /* Check hash salt is passed through too */
2967 XML_SetHashSalt(parser, 0x12345678);
2968 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
2969 XML_SetUserData(parser, &test_data);
2970 XML_SetExternalEntityRefHandler(parser, external_entity_loader);
2971 /* Add a default handler to exercise more code paths */
2972 XML_SetDefaultHandler(parser, dummy_default_handler);
2973 if (XML_UseForeignDTD(parser, XML_TRUE) != XML_ERROR_NONE)
2974 fail("Could not set foreign DTD");
2975 if (_XML_Parse_SINGLE_BYTES(parser, text1, (int)strlen(text1),
2976 XML_FALSE) == XML_STATUS_ERROR)
2977 xml_failure(parser);
2978
2979 /* Ensure that trying to set the DTD after parsing has started
2980 * is faulted, even if it's the same setting.
2981 */
2982 if (XML_UseForeignDTD(parser, XML_TRUE) !=
2983 XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING)
2984 fail("Failed to reject late foreign DTD setting");
2985 /* Ditto for the hash salt */
2986 if (XML_SetHashSalt(parser, 0x23456789))
2987 fail("Failed to reject late hash salt change");
2988
2989 /* Now finish the parse */
2990 if (_XML_Parse_SINGLE_BYTES(parser, text2, (int)strlen(text2),
2991 XML_TRUE) == XML_STATUS_ERROR)
2992 xml_failure(parser);
2993 }
2994 END_TEST
2995
2996 /* Test XML_UseForeignDTD with no external subset present */
2997 static int XMLCALL
external_entity_null_loader(XML_Parser UNUSED_P (parser),const XML_Char * UNUSED_P (context),const XML_Char * UNUSED_P (base),const XML_Char * UNUSED_P (systemId),const XML_Char * UNUSED_P (publicId))2998 external_entity_null_loader(XML_Parser UNUSED_P(parser),
2999 const XML_Char *UNUSED_P(context),
3000 const XML_Char *UNUSED_P(base),
3001 const XML_Char *UNUSED_P(systemId),
3002 const XML_Char *UNUSED_P(publicId))
3003 {
3004 return XML_STATUS_OK;
3005 }
3006
START_TEST(test_foreign_dtd_without_external_subset)3007 START_TEST(test_foreign_dtd_without_external_subset)
3008 {
3009 const char *text =
3010 "<!DOCTYPE doc [<!ENTITY foo 'bar'>]>\n"
3011 "<doc>&foo;</doc>";
3012
3013 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
3014 XML_SetUserData(parser, NULL);
3015 XML_SetExternalEntityRefHandler(parser, external_entity_null_loader);
3016 XML_UseForeignDTD(parser, XML_TRUE);
3017 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
3018 XML_TRUE) == XML_STATUS_ERROR)
3019 xml_failure(parser);
3020 }
3021 END_TEST
3022
START_TEST(test_empty_foreign_dtd)3023 START_TEST(test_empty_foreign_dtd)
3024 {
3025 const char *text =
3026 "<?xml version='1.0' encoding='us-ascii'?>\n"
3027 "<doc>&entity;</doc>";
3028
3029 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
3030 XML_SetExternalEntityRefHandler(parser, external_entity_null_loader);
3031 XML_UseForeignDTD(parser, XML_TRUE);
3032 expect_failure(text, XML_ERROR_UNDEFINED_ENTITY,
3033 "Undefined entity not faulted");
3034 }
3035 END_TEST
3036
3037 /* Test XML Base is set and unset appropriately */
START_TEST(test_set_base)3038 START_TEST(test_set_base)
3039 {
3040 const XML_Char *old_base;
3041 const XML_Char *new_base = XCS("/local/file/name.xml");
3042
3043 old_base = XML_GetBase(parser);
3044 if (XML_SetBase(parser, new_base) != XML_STATUS_OK)
3045 fail("Unable to set base");
3046 if (xcstrcmp(XML_GetBase(parser), new_base) != 0)
3047 fail("Base setting not correct");
3048 if (XML_SetBase(parser, NULL) != XML_STATUS_OK)
3049 fail("Unable to NULL base");
3050 if (XML_GetBase(parser) != NULL)
3051 fail("Base setting not nulled");
3052 XML_SetBase(parser, old_base);
3053 }
3054 END_TEST
3055
3056 /* Test attribute counts, indexing, etc */
3057 typedef struct attrInfo {
3058 const XML_Char *name;
3059 const XML_Char *value;
3060 } AttrInfo;
3061
3062 typedef struct elementInfo {
3063 const XML_Char *name;
3064 int attr_count;
3065 const XML_Char *id_name;
3066 AttrInfo *attributes;
3067 } ElementInfo;
3068
3069 static void XMLCALL
counting_start_element_handler(void * userData,const XML_Char * name,const XML_Char ** atts)3070 counting_start_element_handler(void *userData,
3071 const XML_Char *name,
3072 const XML_Char **atts)
3073 {
3074 ElementInfo *info = (ElementInfo *)userData;
3075 AttrInfo *attr;
3076 int count, id, i;
3077
3078 while (info->name != NULL) {
3079 if (!xcstrcmp(name, info->name))
3080 break;
3081 info++;
3082 }
3083 if (info->name == NULL)
3084 fail("Element not recognised");
3085 /* The attribute count is twice what you might expect. It is a
3086 * count of items in atts, an array which contains alternating
3087 * attribute names and attribute values. For the naive user this
3088 * is possibly a little unexpected, but it is what the
3089 * documentation in expat.h tells us to expect.
3090 */
3091 count = XML_GetSpecifiedAttributeCount(parser);
3092 if (info->attr_count * 2 != count) {
3093 fail("Not got expected attribute count");
3094 return;
3095 }
3096 id = XML_GetIdAttributeIndex(parser);
3097 if (id == -1 && info->id_name != NULL) {
3098 fail("ID not present");
3099 return;
3100 }
3101 if (id != -1 && xcstrcmp(atts[id], info->id_name)) {
3102 fail("ID does not have the correct name");
3103 return;
3104 }
3105 for (i = 0; i < info->attr_count; i++) {
3106 attr = info->attributes;
3107 while (attr->name != NULL) {
3108 if (!xcstrcmp(atts[0], attr->name))
3109 break;
3110 attr++;
3111 }
3112 if (attr->name == NULL) {
3113 fail("Attribute not recognised");
3114 return;
3115 }
3116 if (xcstrcmp(atts[1], attr->value)) {
3117 fail("Attribute has wrong value");
3118 return;
3119 }
3120 /* Remember, two entries in atts per attribute (see above) */
3121 atts += 2;
3122 }
3123 }
3124
START_TEST(test_attributes)3125 START_TEST(test_attributes)
3126 {
3127 const char *text =
3128 "<!DOCTYPE doc [\n"
3129 "<!ELEMENT doc (tag)>\n"
3130 "<!ATTLIST doc id ID #REQUIRED>\n"
3131 "]>"
3132 "<doc a='1' id='one' b='2'>"
3133 "<tag c='3'/>"
3134 "</doc>";
3135 AttrInfo doc_info[] = {
3136 { XCS("a"), XCS("1") },
3137 { XCS("b"), XCS("2") },
3138 { XCS("id"), XCS("one") },
3139 { NULL, NULL }
3140 };
3141 AttrInfo tag_info[] = {
3142 { XCS("c"), XCS("3") },
3143 { NULL, NULL }
3144 };
3145 ElementInfo info[] = {
3146 { XCS("doc"), 3, XCS("id"), NULL },
3147 { XCS("tag"), 1, NULL, NULL },
3148 { NULL, 0, NULL, NULL }
3149 };
3150 info[0].attributes = doc_info;
3151 info[1].attributes = tag_info;
3152
3153 XML_SetStartElementHandler(parser, counting_start_element_handler);
3154 XML_SetUserData(parser, info);
3155 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR)
3156 xml_failure(parser);
3157 }
3158 END_TEST
3159
3160 /* Test reset works correctly in the middle of processing an internal
3161 * entity. Exercises some obscure code in XML_ParserReset().
3162 */
START_TEST(test_reset_in_entity)3163 START_TEST(test_reset_in_entity)
3164 {
3165 const char *text =
3166 "<!DOCTYPE doc [\n"
3167 "<!ENTITY wombat 'wom'>\n"
3168 "<!ENTITY entity 'hi &wom; there'>\n"
3169 "]>\n"
3170 "<doc>&entity;</doc>";
3171 XML_ParsingStatus status;
3172
3173 resumable = XML_TRUE;
3174 XML_SetCharacterDataHandler(parser, clearing_aborting_character_handler);
3175 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_FALSE) == XML_STATUS_ERROR)
3176 xml_failure(parser);
3177 XML_GetParsingStatus(parser, &status);
3178 if (status.parsing != XML_SUSPENDED)
3179 fail("Parsing status not SUSPENDED");
3180 XML_ParserReset(parser, NULL);
3181 XML_GetParsingStatus(parser, &status);
3182 if (status.parsing != XML_INITIALIZED)
3183 fail("Parsing status doesn't reset to INITIALIZED");
3184 }
3185 END_TEST
3186
3187 /* Test that resume correctly passes through parse errors */
START_TEST(test_resume_invalid_parse)3188 START_TEST(test_resume_invalid_parse)
3189 {
3190 const char *text = "<doc>Hello</doc"; /* Missing closing wedge */
3191
3192 resumable = XML_TRUE;
3193 XML_SetCharacterDataHandler(parser,
3194 clearing_aborting_character_handler);
3195 if (XML_Parse(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR)
3196 xml_failure(parser);
3197 if (XML_ResumeParser(parser) == XML_STATUS_OK)
3198 fail("Resumed invalid parse not faulted");
3199 if (XML_GetErrorCode(parser) != XML_ERROR_UNCLOSED_TOKEN)
3200 fail("Invalid parse not correctly faulted");
3201 }
3202 END_TEST
3203
3204 /* Test that re-suspended parses are correctly passed through */
START_TEST(test_resume_resuspended)3205 START_TEST(test_resume_resuspended)
3206 {
3207 const char *text = "<doc>Hello<meep/>world</doc>";
3208
3209 resumable = XML_TRUE;
3210 XML_SetCharacterDataHandler(parser,
3211 clearing_aborting_character_handler);
3212 if (XML_Parse(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR)
3213 xml_failure(parser);
3214 resumable = XML_TRUE;
3215 XML_SetCharacterDataHandler(parser,
3216 clearing_aborting_character_handler);
3217 if (XML_ResumeParser(parser) != XML_STATUS_SUSPENDED)
3218 fail("Resumption not suspended");
3219 /* This one should succeed and finish up */
3220 if (XML_ResumeParser(parser) != XML_STATUS_OK)
3221 xml_failure(parser);
3222 }
3223 END_TEST
3224
3225 /* Test that CDATA shows up correctly through a default handler */
START_TEST(test_cdata_default)3226 START_TEST(test_cdata_default)
3227 {
3228 const char *text = "<doc><![CDATA[Hello\nworld]]></doc>";
3229 const XML_Char *expected = XCS("<doc><![CDATA[Hello\nworld]]></doc>");
3230 CharData storage;
3231
3232 CharData_Init(&storage);
3233 XML_SetUserData(parser, &storage);
3234 XML_SetDefaultHandler(parser, accumulate_characters);
3235
3236 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
3237 XML_TRUE) == XML_STATUS_ERROR)
3238 xml_failure(parser);
3239 CharData_CheckXMLChars(&storage, expected);
3240 }
3241 END_TEST
3242
3243 /* Test resetting a subordinate parser does exactly nothing */
3244 static int XMLCALL
external_entity_resetter(XML_Parser parser,const XML_Char * context,const XML_Char * UNUSED_P (base),const XML_Char * UNUSED_P (systemId),const XML_Char * UNUSED_P (publicId))3245 external_entity_resetter(XML_Parser parser,
3246 const XML_Char *context,
3247 const XML_Char *UNUSED_P(base),
3248 const XML_Char *UNUSED_P(systemId),
3249 const XML_Char *UNUSED_P(publicId))
3250 {
3251 const char *text = "<!ELEMENT doc (#PCDATA)*>";
3252 XML_Parser ext_parser;
3253 XML_ParsingStatus status;
3254
3255 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
3256 if (ext_parser == NULL)
3257 fail("Could not create external entity parser");
3258 XML_GetParsingStatus(ext_parser, &status);
3259 if (status.parsing != XML_INITIALIZED) {
3260 fail("Parsing status is not INITIALIZED");
3261 return XML_STATUS_ERROR;
3262 }
3263 if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text),
3264 XML_TRUE) == XML_STATUS_ERROR) {
3265 xml_failure(parser);
3266 return XML_STATUS_ERROR;
3267 }
3268 XML_GetParsingStatus(ext_parser, &status);
3269 if (status.parsing != XML_FINISHED) {
3270 fail("Parsing status is not FINISHED");
3271 return XML_STATUS_ERROR;
3272 }
3273 /* Check we can't parse here */
3274 if (XML_Parse(ext_parser, text, (int)strlen(text),
3275 XML_TRUE) != XML_STATUS_ERROR)
3276 fail("Parsing when finished not faulted");
3277 if (XML_GetErrorCode(ext_parser) != XML_ERROR_FINISHED)
3278 fail("Parsing when finished faulted with wrong code");
3279 XML_ParserReset(ext_parser, NULL);
3280 XML_GetParsingStatus(ext_parser, &status);
3281 if (status.parsing != XML_FINISHED) {
3282 fail("Parsing status not still FINISHED");
3283 return XML_STATUS_ERROR;
3284 }
3285 XML_ParserFree(ext_parser);
3286 return XML_STATUS_OK;
3287 }
3288
START_TEST(test_subordinate_reset)3289 START_TEST(test_subordinate_reset)
3290 {
3291 const char *text =
3292 "<?xml version='1.0' encoding='us-ascii'?>\n"
3293 "<!DOCTYPE doc SYSTEM 'foo'>\n"
3294 "<doc>&entity;</doc>";
3295
3296 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
3297 XML_SetExternalEntityRefHandler(parser, external_entity_resetter);
3298 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR)
3299 xml_failure(parser);
3300 }
3301 END_TEST
3302
3303
3304 /* Test suspending a subordinate parser */
3305
3306 static void XMLCALL
entity_suspending_decl_handler(void * userData,const XML_Char * UNUSED_P (name),XML_Content * model)3307 entity_suspending_decl_handler(void *userData,
3308 const XML_Char *UNUSED_P(name),
3309 XML_Content *model)
3310 {
3311 XML_Parser ext_parser = (XML_Parser)userData;
3312
3313 if (XML_StopParser(ext_parser, XML_TRUE) != XML_STATUS_ERROR)
3314 fail("Attempting to suspend a subordinate parser not faulted");
3315 if (XML_GetErrorCode(ext_parser) != XML_ERROR_SUSPEND_PE)
3316 fail("Suspending subordinate parser get wrong code");
3317 XML_SetElementDeclHandler(ext_parser, NULL);
3318 XML_FreeContentModel(parser, model);
3319 }
3320
3321 static int XMLCALL
external_entity_suspender(XML_Parser parser,const XML_Char * context,const XML_Char * UNUSED_P (base),const XML_Char * UNUSED_P (systemId),const XML_Char * UNUSED_P (publicId))3322 external_entity_suspender(XML_Parser parser,
3323 const XML_Char *context,
3324 const XML_Char *UNUSED_P(base),
3325 const XML_Char *UNUSED_P(systemId),
3326 const XML_Char *UNUSED_P(publicId))
3327 {
3328 const char *text = "<!ELEMENT doc (#PCDATA)*>";
3329 XML_Parser ext_parser;
3330
3331 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
3332 if (ext_parser == NULL)
3333 fail("Could not create external entity parser");
3334 XML_SetElementDeclHandler(ext_parser, entity_suspending_decl_handler);
3335 XML_SetUserData(ext_parser, ext_parser);
3336 if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text),
3337 XML_TRUE) == XML_STATUS_ERROR) {
3338 xml_failure(ext_parser);
3339 return XML_STATUS_ERROR;
3340 }
3341 XML_ParserFree(ext_parser);
3342 return XML_STATUS_OK;
3343 }
3344
START_TEST(test_subordinate_suspend)3345 START_TEST(test_subordinate_suspend)
3346 {
3347 const char *text =
3348 "<?xml version='1.0' encoding='us-ascii'?>\n"
3349 "<!DOCTYPE doc SYSTEM 'foo'>\n"
3350 "<doc>&entity;</doc>";
3351
3352 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
3353 XML_SetExternalEntityRefHandler(parser, external_entity_suspender);
3354 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR)
3355 xml_failure(parser);
3356 }
3357 END_TEST
3358
3359 /* Test suspending a subordinate parser from an XML declaration */
3360 /* Increases code coverage of the tests */
3361 static void XMLCALL
entity_suspending_xdecl_handler(void * userData,const XML_Char * UNUSED_P (version),const XML_Char * UNUSED_P (encoding),int UNUSED_P (standalone))3362 entity_suspending_xdecl_handler(void *userData,
3363 const XML_Char *UNUSED_P(version),
3364 const XML_Char *UNUSED_P(encoding),
3365 int UNUSED_P(standalone))
3366 {
3367 XML_Parser ext_parser = (XML_Parser)userData;
3368
3369 XML_StopParser(ext_parser, resumable);
3370 XML_SetXmlDeclHandler(ext_parser, NULL);
3371 }
3372
3373 static int XMLCALL
external_entity_suspend_xmldecl(XML_Parser parser,const XML_Char * context,const XML_Char * UNUSED_P (base),const XML_Char * UNUSED_P (systemId),const XML_Char * UNUSED_P (publicId))3374 external_entity_suspend_xmldecl(XML_Parser parser,
3375 const XML_Char *context,
3376 const XML_Char *UNUSED_P(base),
3377 const XML_Char *UNUSED_P(systemId),
3378 const XML_Char *UNUSED_P(publicId))
3379 {
3380 const char *text = "<?xml version='1.0' encoding='us-ascii'?>";
3381 XML_Parser ext_parser;
3382 XML_ParsingStatus status;
3383 enum XML_Status rc;
3384
3385 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
3386 if (ext_parser == NULL)
3387 fail("Could not create external entity parser");
3388 XML_SetXmlDeclHandler(ext_parser, entity_suspending_xdecl_handler);
3389 XML_SetUserData(ext_parser, ext_parser);
3390 rc = _XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE);
3391 XML_GetParsingStatus(ext_parser, &status);
3392 if (resumable) {
3393 if (rc == XML_STATUS_ERROR)
3394 xml_failure(ext_parser);
3395 if (status.parsing != XML_SUSPENDED)
3396 fail("Ext Parsing status not SUSPENDED");
3397 } else {
3398 if (rc != XML_STATUS_ERROR)
3399 fail("Ext parsing not aborted");
3400 if (XML_GetErrorCode(ext_parser) != XML_ERROR_ABORTED)
3401 xml_failure(ext_parser);
3402 if (status.parsing != XML_FINISHED)
3403 fail("Ext Parsing status not FINISHED");
3404 }
3405
3406 XML_ParserFree(ext_parser);
3407 return XML_STATUS_OK;
3408 }
3409
START_TEST(test_subordinate_xdecl_suspend)3410 START_TEST(test_subordinate_xdecl_suspend)
3411 {
3412 const char *text =
3413 "<!DOCTYPE doc [\n"
3414 " <!ENTITY entity SYSTEM 'http://example.org/dummy.ent'>\n"
3415 "]>\n"
3416 "<doc>&entity;</doc>";
3417
3418 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
3419 XML_SetExternalEntityRefHandler(parser,
3420 external_entity_suspend_xmldecl);
3421 resumable = XML_TRUE;
3422 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
3423 XML_TRUE) == XML_STATUS_ERROR)
3424 xml_failure(parser);
3425 }
3426 END_TEST
3427
START_TEST(test_subordinate_xdecl_abort)3428 START_TEST(test_subordinate_xdecl_abort)
3429 {
3430 const char *text =
3431 "<!DOCTYPE doc [\n"
3432 " <!ENTITY entity SYSTEM 'http://example.org/dummy.ent'>\n"
3433 "]>\n"
3434 "<doc>&entity;</doc>";
3435
3436 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
3437 XML_SetExternalEntityRefHandler(parser,
3438 external_entity_suspend_xmldecl);
3439 resumable = XML_FALSE;
3440 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
3441 XML_TRUE) == XML_STATUS_ERROR)
3442 xml_failure(parser);
3443 }
3444 END_TEST
3445
3446 /* Test external entity fault handling with suspension */
3447 static int XMLCALL
external_entity_suspending_faulter(XML_Parser parser,const XML_Char * context,const XML_Char * UNUSED_P (base),const XML_Char * UNUSED_P (systemId),const XML_Char * UNUSED_P (publicId))3448 external_entity_suspending_faulter(XML_Parser parser,
3449 const XML_Char *context,
3450 const XML_Char *UNUSED_P(base),
3451 const XML_Char *UNUSED_P(systemId),
3452 const XML_Char *UNUSED_P(publicId))
3453 {
3454 XML_Parser ext_parser;
3455 ExtFaults *fault = (ExtFaults *)XML_GetUserData(parser);
3456 void *buffer;
3457 int parse_len = (int)strlen(fault->parse_text);
3458
3459 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
3460 if (ext_parser == NULL)
3461 fail("Could not create external entity parser");
3462 XML_SetXmlDeclHandler(ext_parser, entity_suspending_xdecl_handler);
3463 XML_SetUserData(ext_parser, ext_parser);
3464 resumable = XML_TRUE;
3465 buffer = XML_GetBuffer(ext_parser, parse_len);
3466 if (buffer == NULL)
3467 fail("Could not allocate parse buffer");
3468 memcpy(buffer, fault->parse_text, parse_len);
3469 if (XML_ParseBuffer(ext_parser, parse_len,
3470 XML_FALSE) != XML_STATUS_SUSPENDED)
3471 fail("XML declaration did not suspend");
3472 if (XML_ResumeParser(ext_parser) != XML_STATUS_OK)
3473 xml_failure(ext_parser);
3474 if (XML_ParseBuffer(ext_parser, 0, XML_TRUE) != XML_STATUS_ERROR)
3475 fail(fault->fail_text);
3476 if (XML_GetErrorCode(ext_parser) != fault->error)
3477 xml_failure(ext_parser);
3478
3479 XML_ParserFree(ext_parser);
3480 return XML_STATUS_ERROR;
3481 }
3482
START_TEST(test_ext_entity_invalid_suspended_parse)3483 START_TEST(test_ext_entity_invalid_suspended_parse)
3484 {
3485 const char *text =
3486 "<!DOCTYPE doc [\n"
3487 " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n"
3488 "]>\n"
3489 "<doc>&en;</doc>";
3490 ExtFaults faults[] = {
3491 {
3492 "<?xml version='1.0' encoding='us-ascii'?><",
3493 "Incomplete element declaration not faulted",
3494 NULL,
3495 XML_ERROR_UNCLOSED_TOKEN
3496 },
3497 {
3498 /* First two bytes of a three-byte char */
3499 "<?xml version='1.0' encoding='utf-8'?>\xe2\x82",
3500 "Incomplete character not faulted",
3501 NULL,
3502 XML_ERROR_PARTIAL_CHAR
3503 },
3504 { NULL, NULL, NULL, XML_ERROR_NONE }
3505 };
3506 ExtFaults *fault;
3507
3508 for (fault = &faults[0]; fault->parse_text != NULL; fault++) {
3509 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
3510 XML_SetExternalEntityRefHandler(parser,
3511 external_entity_suspending_faulter);
3512 XML_SetUserData(parser, fault);
3513 expect_failure(text,
3514 XML_ERROR_EXTERNAL_ENTITY_HANDLING,
3515 "Parser did not report external entity error");
3516 XML_ParserReset(parser, NULL);
3517 }
3518 }
3519 END_TEST
3520
3521
3522
3523 /* Test setting an explicit encoding */
START_TEST(test_explicit_encoding)3524 START_TEST(test_explicit_encoding)
3525 {
3526 const char *text1 = "<doc>Hello ";
3527 const char *text2 = " World</doc>";
3528
3529 /* Just check that we can set the encoding to NULL before starting */
3530 if (XML_SetEncoding(parser, NULL) != XML_STATUS_OK)
3531 fail("Failed to initialise encoding to NULL");
3532 /* Say we are UTF-8 */
3533 if (XML_SetEncoding(parser, XCS("utf-8")) != XML_STATUS_OK)
3534 fail("Failed to set explicit encoding");
3535 if (_XML_Parse_SINGLE_BYTES(parser, text1, (int)strlen(text1),
3536 XML_FALSE) == XML_STATUS_ERROR)
3537 xml_failure(parser);
3538 /* Try to switch encodings mid-parse */
3539 if (XML_SetEncoding(parser, XCS("us-ascii")) != XML_STATUS_ERROR)
3540 fail("Allowed encoding change");
3541 if (_XML_Parse_SINGLE_BYTES(parser, text2, (int)strlen(text2),
3542 XML_TRUE) == XML_STATUS_ERROR)
3543 xml_failure(parser);
3544 /* Try now the parse is over */
3545 if (XML_SetEncoding(parser, NULL) != XML_STATUS_OK)
3546 fail("Failed to unset encoding");
3547 }
3548 END_TEST
3549
3550
3551 /* Test handling of trailing CR (rather than newline) */
3552 static void XMLCALL
cr_cdata_handler(void * userData,const XML_Char * s,int len)3553 cr_cdata_handler(void *userData, const XML_Char *s, int len)
3554 {
3555 int *pfound = (int *)userData;
3556
3557 /* Internal processing turns the CR into a newline for the
3558 * character data handler, but not for the default handler
3559 */
3560 if (len == 1 && (*s == XCS('\n') || *s == XCS('\r')))
3561 *pfound = 1;
3562 }
3563
START_TEST(test_trailing_cr)3564 START_TEST(test_trailing_cr)
3565 {
3566 const char *text = "<doc>\r";
3567 int found_cr;
3568
3569 /* Try with a character handler, for code coverage */
3570 XML_SetCharacterDataHandler(parser, cr_cdata_handler);
3571 XML_SetUserData(parser, &found_cr);
3572 found_cr = 0;
3573 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
3574 XML_TRUE) == XML_STATUS_OK)
3575 fail("Failed to fault unclosed doc");
3576 if (found_cr == 0)
3577 fail("Did not catch the carriage return");
3578 XML_ParserReset(parser, NULL);
3579
3580 /* Now with a default handler instead */
3581 XML_SetDefaultHandler(parser, cr_cdata_handler);
3582 XML_SetUserData(parser, &found_cr);
3583 found_cr = 0;
3584 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
3585 XML_TRUE) == XML_STATUS_OK)
3586 fail("Failed to fault unclosed doc");
3587 if (found_cr == 0)
3588 fail("Did not catch default carriage return");
3589 }
3590 END_TEST
3591
3592 /* Test trailing CR in an external entity parse */
3593 static int XMLCALL
external_entity_cr_catcher(XML_Parser parser,const XML_Char * context,const XML_Char * UNUSED_P (base),const XML_Char * UNUSED_P (systemId),const XML_Char * UNUSED_P (publicId))3594 external_entity_cr_catcher(XML_Parser parser,
3595 const XML_Char *context,
3596 const XML_Char *UNUSED_P(base),
3597 const XML_Char *UNUSED_P(systemId),
3598 const XML_Char *UNUSED_P(publicId))
3599 {
3600 const char *text = "\r";
3601 XML_Parser ext_parser;
3602
3603 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
3604 if (ext_parser == NULL)
3605 fail("Could not create external entity parser");
3606 XML_SetCharacterDataHandler(ext_parser, cr_cdata_handler);
3607 if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text),
3608 XML_TRUE) == XML_STATUS_ERROR)
3609 xml_failure(ext_parser);
3610 XML_ParserFree(ext_parser);
3611 return XML_STATUS_OK;
3612 }
3613
3614 static int XMLCALL
external_entity_bad_cr_catcher(XML_Parser parser,const XML_Char * context,const XML_Char * UNUSED_P (base),const XML_Char * UNUSED_P (systemId),const XML_Char * UNUSED_P (publicId))3615 external_entity_bad_cr_catcher(XML_Parser parser,
3616 const XML_Char *context,
3617 const XML_Char *UNUSED_P(base),
3618 const XML_Char *UNUSED_P(systemId),
3619 const XML_Char *UNUSED_P(publicId))
3620 {
3621 const char *text = "<tag>\r";
3622 XML_Parser ext_parser;
3623
3624 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
3625 if (ext_parser == NULL)
3626 fail("Could not create external entity parser");
3627 XML_SetCharacterDataHandler(ext_parser, cr_cdata_handler);
3628 if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text),
3629 XML_TRUE) == XML_STATUS_OK)
3630 fail("Async entity error not caught");
3631 if (XML_GetErrorCode(ext_parser) != XML_ERROR_ASYNC_ENTITY)
3632 xml_failure(ext_parser);
3633 XML_ParserFree(ext_parser);
3634 return XML_STATUS_OK;
3635 }
3636
START_TEST(test_ext_entity_trailing_cr)3637 START_TEST(test_ext_entity_trailing_cr)
3638 {
3639 const char *text =
3640 "<!DOCTYPE doc [\n"
3641 " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n"
3642 "]>\n"
3643 "<doc>&en;</doc>";
3644 int found_cr;
3645
3646 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
3647 XML_SetExternalEntityRefHandler(parser, external_entity_cr_catcher);
3648 XML_SetUserData(parser, &found_cr);
3649 found_cr = 0;
3650 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
3651 XML_TRUE) != XML_STATUS_OK)
3652 xml_failure(parser);
3653 if (found_cr == 0)
3654 fail("No carriage return found");
3655 XML_ParserReset(parser, NULL);
3656
3657 /* Try again with a different trailing CR */
3658 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
3659 XML_SetExternalEntityRefHandler(parser, external_entity_bad_cr_catcher);
3660 XML_SetUserData(parser, &found_cr);
3661 found_cr = 0;
3662 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
3663 XML_TRUE) != XML_STATUS_OK)
3664 xml_failure(parser);
3665 if (found_cr == 0)
3666 fail("No carriage return found");
3667 }
3668 END_TEST
3669
3670 /* Test handling of trailing square bracket */
3671 static void XMLCALL
rsqb_handler(void * userData,const XML_Char * s,int len)3672 rsqb_handler(void *userData, const XML_Char *s, int len)
3673 {
3674 int *pfound = (int *)userData;
3675
3676 if (len == 1 && *s == XCS(']'))
3677 *pfound = 1;
3678 }
3679
START_TEST(test_trailing_rsqb)3680 START_TEST(test_trailing_rsqb)
3681 {
3682 const char *text8 = "<doc>]";
3683 const char text16[] = "\xFF\xFE<\000d\000o\000c\000>\000]\000";
3684 int found_rsqb;
3685 int text8_len = (int)strlen(text8);
3686
3687 XML_SetCharacterDataHandler(parser, rsqb_handler);
3688 XML_SetUserData(parser, &found_rsqb);
3689 found_rsqb = 0;
3690 if (_XML_Parse_SINGLE_BYTES(parser, text8, text8_len,
3691 XML_TRUE) == XML_STATUS_OK)
3692 fail("Failed to fault unclosed doc");
3693 if (found_rsqb == 0)
3694 fail("Did not catch the right square bracket");
3695
3696 /* Try again with a different encoding */
3697 XML_ParserReset(parser, NULL);
3698 XML_SetCharacterDataHandler(parser, rsqb_handler);
3699 XML_SetUserData(parser, &found_rsqb);
3700 found_rsqb = 0;
3701 if (_XML_Parse_SINGLE_BYTES(parser, text16, (int)sizeof(text16)-1,
3702 XML_TRUE) == XML_STATUS_OK)
3703 fail("Failed to fault unclosed doc");
3704 if (found_rsqb == 0)
3705 fail("Did not catch the right square bracket");
3706
3707 /* And finally with a default handler */
3708 XML_ParserReset(parser, NULL);
3709 XML_SetDefaultHandler(parser, rsqb_handler);
3710 XML_SetUserData(parser, &found_rsqb);
3711 found_rsqb = 0;
3712 if (_XML_Parse_SINGLE_BYTES(parser, text16, (int)sizeof(text16)-1,
3713 XML_TRUE) == XML_STATUS_OK)
3714 fail("Failed to fault unclosed doc");
3715 if (found_rsqb == 0)
3716 fail("Did not catch the right square bracket");
3717 }
3718 END_TEST
3719
3720 /* Test trailing right square bracket in an external entity parse */
3721 static int XMLCALL
external_entity_rsqb_catcher(XML_Parser parser,const XML_Char * context,const XML_Char * UNUSED_P (base),const XML_Char * UNUSED_P (systemId),const XML_Char * UNUSED_P (publicId))3722 external_entity_rsqb_catcher(XML_Parser parser,
3723 const XML_Char *context,
3724 const XML_Char *UNUSED_P(base),
3725 const XML_Char *UNUSED_P(systemId),
3726 const XML_Char *UNUSED_P(publicId))
3727 {
3728 const char *text = "<tag>]";
3729 XML_Parser ext_parser;
3730
3731 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
3732 if (ext_parser == NULL)
3733 fail("Could not create external entity parser");
3734 XML_SetCharacterDataHandler(ext_parser, rsqb_handler);
3735 if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text),
3736 XML_TRUE) != XML_STATUS_ERROR)
3737 fail("Async entity error not caught");
3738 if (XML_GetErrorCode(ext_parser) != XML_ERROR_ASYNC_ENTITY)
3739 xml_failure(ext_parser);
3740 XML_ParserFree(ext_parser);
3741 return XML_STATUS_OK;
3742 }
3743
START_TEST(test_ext_entity_trailing_rsqb)3744 START_TEST(test_ext_entity_trailing_rsqb)
3745 {
3746 const char *text =
3747 "<!DOCTYPE doc [\n"
3748 " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n"
3749 "]>\n"
3750 "<doc>&en;</doc>";
3751 int found_rsqb;
3752
3753 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
3754 XML_SetExternalEntityRefHandler(parser, external_entity_rsqb_catcher);
3755 XML_SetUserData(parser, &found_rsqb);
3756 found_rsqb = 0;
3757 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
3758 XML_TRUE) != XML_STATUS_OK)
3759 xml_failure(parser);
3760 if (found_rsqb == 0)
3761 fail("No right square bracket found");
3762 }
3763 END_TEST
3764
3765 /* Test CDATA handling in an external entity */
3766 static int XMLCALL
external_entity_good_cdata_ascii(XML_Parser parser,const XML_Char * context,const XML_Char * UNUSED_P (base),const XML_Char * UNUSED_P (systemId),const XML_Char * UNUSED_P (publicId))3767 external_entity_good_cdata_ascii(XML_Parser parser,
3768 const XML_Char *context,
3769 const XML_Char *UNUSED_P(base),
3770 const XML_Char *UNUSED_P(systemId),
3771 const XML_Char *UNUSED_P(publicId))
3772 {
3773 const char *text =
3774 "<a><![CDATA[<greeting>Hello, world!</greeting>]]></a>";
3775 const XML_Char *expected = XCS("<greeting>Hello, world!</greeting>");
3776 CharData storage;
3777 XML_Parser ext_parser;
3778
3779 CharData_Init(&storage);
3780 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
3781 if (ext_parser == NULL)
3782 fail("Could not create external entity parser");
3783 XML_SetUserData(ext_parser, &storage);
3784 XML_SetCharacterDataHandler(ext_parser, accumulate_characters);
3785
3786 if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text),
3787 XML_TRUE) == XML_STATUS_ERROR)
3788 xml_failure(ext_parser);
3789 CharData_CheckXMLChars(&storage, expected);
3790
3791 XML_ParserFree(ext_parser);
3792 return XML_STATUS_OK;
3793 }
3794
START_TEST(test_ext_entity_good_cdata)3795 START_TEST(test_ext_entity_good_cdata)
3796 {
3797 const char *text =
3798 "<!DOCTYPE doc [\n"
3799 " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n"
3800 "]>\n"
3801 "<doc>&en;</doc>";
3802
3803 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
3804 XML_SetExternalEntityRefHandler(parser,
3805 external_entity_good_cdata_ascii);
3806 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
3807 XML_TRUE) != XML_STATUS_OK)
3808 xml_failure(parser);
3809 }
3810 END_TEST
3811
3812 /* Test user parameter settings */
3813 /* Variable holding the expected handler userData */
3814 static void *handler_data = NULL;
3815 /* Count of the number of times the comment handler has been invoked */
3816 static int comment_count = 0;
3817 /* Count of the number of skipped entities */
3818 static int skip_count = 0;
3819 /* Count of the number of times the XML declaration handler is invoked */
3820 static int xdecl_count = 0;
3821
3822 static void XMLCALL
xml_decl_handler(void * userData,const XML_Char * UNUSED_P (version),const XML_Char * UNUSED_P (encoding),int standalone)3823 xml_decl_handler(void *userData,
3824 const XML_Char *UNUSED_P(version),
3825 const XML_Char *UNUSED_P(encoding),
3826 int standalone)
3827 {
3828 if (userData != handler_data)
3829 fail("User data (xml decl) not correctly set");
3830 if (standalone != -1)
3831 fail("Standalone not flagged as not present in XML decl");
3832 xdecl_count++;
3833 }
3834
3835 static void XMLCALL
param_check_skip_handler(void * userData,const XML_Char * UNUSED_P (entityName),int UNUSED_P (is_parameter_entity))3836 param_check_skip_handler(void *userData,
3837 const XML_Char *UNUSED_P(entityName),
3838 int UNUSED_P(is_parameter_entity))
3839 {
3840 if (userData != handler_data)
3841 fail("User data (skip) not correctly set");
3842 skip_count++;
3843 }
3844
3845 static void XMLCALL
data_check_comment_handler(void * userData,const XML_Char * UNUSED_P (data))3846 data_check_comment_handler(void *userData, const XML_Char *UNUSED_P(data))
3847 {
3848 /* Check that the userData passed through is what we expect */
3849 if (userData != handler_data)
3850 fail("User data (parser) not correctly set");
3851 /* Check that the user data in the parser is appropriate */
3852 if (XML_GetUserData(userData) != (void *)1)
3853 fail("User data in parser not correctly set");
3854 comment_count++;
3855 }
3856
3857 static int XMLCALL
external_entity_param_checker(XML_Parser parser,const XML_Char * context,const XML_Char * UNUSED_P (base),const XML_Char * UNUSED_P (systemId),const XML_Char * UNUSED_P (publicId))3858 external_entity_param_checker(XML_Parser parser,
3859 const XML_Char *context,
3860 const XML_Char *UNUSED_P(base),
3861 const XML_Char *UNUSED_P(systemId),
3862 const XML_Char *UNUSED_P(publicId))
3863 {
3864 const char *text =
3865 "<!-- Subordinate parser -->\n"
3866 "<!ELEMENT doc (#PCDATA)*>";
3867 XML_Parser ext_parser;
3868
3869 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
3870 if (ext_parser == NULL)
3871 fail("Could not create external entity parser");
3872 handler_data = ext_parser;
3873 if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text),
3874 XML_TRUE) == XML_STATUS_ERROR) {
3875 xml_failure(parser);
3876 return XML_STATUS_ERROR;
3877 }
3878 handler_data = parser;
3879 XML_ParserFree(ext_parser);
3880 return XML_STATUS_OK;
3881 }
3882
START_TEST(test_user_parameters)3883 START_TEST(test_user_parameters)
3884 {
3885 const char *text =
3886 "<?xml version='1.0' encoding='us-ascii'?>\n"
3887 "<!-- Primary parse -->\n"
3888 "<!DOCTYPE doc SYSTEM 'foo'>\n"
3889 "<doc>&entity;";
3890 const char *epilog =
3891 "<!-- Back to primary parser -->\n"
3892 "</doc>";
3893
3894 comment_count = 0;
3895 skip_count = 0;
3896 xdecl_count = 0;
3897 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
3898 XML_SetXmlDeclHandler(parser, xml_decl_handler);
3899 XML_SetExternalEntityRefHandler(parser, external_entity_param_checker);
3900 XML_SetCommentHandler(parser, data_check_comment_handler);
3901 XML_SetSkippedEntityHandler(parser, param_check_skip_handler);
3902 XML_UseParserAsHandlerArg(parser);
3903 XML_SetUserData(parser, (void *)1);
3904 handler_data = parser;
3905 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
3906 XML_FALSE) == XML_STATUS_ERROR)
3907 xml_failure(parser);
3908 if (comment_count != 2)
3909 fail("Comment handler not invoked enough times");
3910 /* Ensure we can't change policy mid-parse */
3911 if (XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_NEVER))
3912 fail("Changed param entity parsing policy while parsing");
3913 if (_XML_Parse_SINGLE_BYTES(parser, epilog, (int)strlen(epilog),
3914 XML_TRUE) == XML_STATUS_ERROR)
3915 xml_failure(parser);
3916 if (comment_count != 3)
3917 fail("Comment handler not invoked enough times");
3918 if (skip_count != 1)
3919 fail("Skip handler not invoked enough times");
3920 if (xdecl_count != 1)
3921 fail("XML declaration handler not invoked");
3922 }
3923 END_TEST
3924
3925 /* Test that an explicit external entity handler argument replaces
3926 * the parser as the first argument.
3927 *
3928 * We do not call the first parameter to the external entity handler
3929 * 'parser' for once, since the first time the handler is called it
3930 * will actually be a text string. We need to be able to access the
3931 * global 'parser' variable to create our external entity parser from,
3932 * since there are code paths we need to ensure get executed.
3933 */
3934 static int XMLCALL
external_entity_ref_param_checker(XML_Parser parameter,const XML_Char * context,const XML_Char * UNUSED_P (base),const XML_Char * UNUSED_P (systemId),const XML_Char * UNUSED_P (publicId))3935 external_entity_ref_param_checker(XML_Parser parameter,
3936 const XML_Char *context,
3937 const XML_Char *UNUSED_P(base),
3938 const XML_Char *UNUSED_P(systemId),
3939 const XML_Char *UNUSED_P(publicId))
3940 {
3941 const char *text = "<!ELEMENT doc (#PCDATA)*>";
3942 XML_Parser ext_parser;
3943
3944 if ((void *)parameter != handler_data)
3945 fail("External entity ref handler parameter not correct");
3946
3947 /* Here we use the global 'parser' variable */
3948 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
3949 if (ext_parser == NULL)
3950 fail("Could not create external entity parser");
3951 if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text),
3952 XML_TRUE) == XML_STATUS_ERROR)
3953 xml_failure(ext_parser);
3954
3955 XML_ParserFree(ext_parser);
3956 return XML_STATUS_OK;
3957 }
3958
START_TEST(test_ext_entity_ref_parameter)3959 START_TEST(test_ext_entity_ref_parameter)
3960 {
3961 const char *text =
3962 "<?xml version='1.0' encoding='us-ascii'?>\n"
3963 "<!DOCTYPE doc SYSTEM 'foo'>\n"
3964 "<doc>&entity;</doc>";
3965
3966 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
3967 XML_SetExternalEntityRefHandler(parser,
3968 external_entity_ref_param_checker);
3969 /* Set a handler arg that is not NULL and not parser (which is
3970 * what NULL would cause to be passed.
3971 */
3972 XML_SetExternalEntityRefHandlerArg(parser, (void *)text);
3973 handler_data = (void *)text;
3974 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
3975 XML_TRUE) == XML_STATUS_ERROR)
3976 xml_failure(parser);
3977
3978 /* Now try again with unset args */
3979 XML_ParserReset(parser, NULL);
3980 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
3981 XML_SetExternalEntityRefHandler(parser,
3982 external_entity_ref_param_checker);
3983 XML_SetExternalEntityRefHandlerArg(parser, NULL);
3984 handler_data = (void *)parser;
3985 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
3986 XML_TRUE) == XML_STATUS_ERROR)
3987 xml_failure(parser);
3988 }
3989 END_TEST
3990
3991 /* Test the parsing of an empty string */
START_TEST(test_empty_parse)3992 START_TEST(test_empty_parse)
3993 {
3994 const char *text = "<doc></doc>";
3995 const char *partial = "<doc>";
3996
3997 if (XML_Parse(parser, NULL, 0, XML_FALSE) == XML_STATUS_ERROR)
3998 fail("Parsing empty string faulted");
3999 if (XML_Parse(parser, NULL, 0, XML_TRUE) != XML_STATUS_ERROR)
4000 fail("Parsing final empty string not faulted");
4001 if (XML_GetErrorCode(parser) != XML_ERROR_NO_ELEMENTS)
4002 fail("Parsing final empty string faulted for wrong reason");
4003
4004 /* Now try with valid text before the empty end */
4005 XML_ParserReset(parser, NULL);
4006 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
4007 XML_FALSE) == XML_STATUS_ERROR)
4008 xml_failure(parser);
4009 if (XML_Parse(parser, NULL, 0, XML_TRUE) == XML_STATUS_ERROR)
4010 fail("Parsing final empty string faulted");
4011
4012 /* Now try with invalid text before the empty end */
4013 XML_ParserReset(parser, NULL);
4014 if (_XML_Parse_SINGLE_BYTES(parser, partial, (int)strlen(partial),
4015 XML_FALSE) == XML_STATUS_ERROR)
4016 xml_failure(parser);
4017 if (XML_Parse(parser, NULL, 0, XML_TRUE) != XML_STATUS_ERROR)
4018 fail("Parsing final incomplete empty string not faulted");
4019 }
4020 END_TEST
4021
4022 /* Test odd corners of the XML_GetBuffer interface */
4023 static enum XML_Status
get_feature(enum XML_FeatureEnum feature_id,long * presult)4024 get_feature(enum XML_FeatureEnum feature_id, long *presult)
4025 {
4026 const XML_Feature *feature = XML_GetFeatureList();
4027
4028 if (feature == NULL)
4029 return XML_STATUS_ERROR;
4030 for (; feature->feature != XML_FEATURE_END; feature++) {
4031 if (feature->feature == feature_id) {
4032 *presult = feature->value;
4033 return XML_STATUS_OK;
4034 }
4035 }
4036 return XML_STATUS_ERROR;
4037 }
4038
4039 /* Having an element name longer than 1024 characters exercises some
4040 * of the pool allocation code in the parser that otherwise does not
4041 * get executed. The count at the end of the line is the number of
4042 * characters (bytes) in the element name by that point.x
4043 */
4044 static const char *get_buffer_test_text =
4045 "<documentwitharidiculouslylongelementnametotease" /* 0x030 */
4046 "aparticularcorneroftheallocationinXML_GetBuffers" /* 0x060 */
4047 "othatwecanimprovethecoverageyetagain012345678901" /* 0x090 */
4048 "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x0c0 */
4049 "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x0f0 */
4050 "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x120 */
4051 "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x150 */
4052 "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x180 */
4053 "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x1b0 */
4054 "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x1e0 */
4055 "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x210 */
4056 "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x240 */
4057 "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x270 */
4058 "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x2a0 */
4059 "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x2d0 */
4060 "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x300 */
4061 "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x330 */
4062 "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x360 */
4063 "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x390 */
4064 "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x3c0 */
4065 "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x3f0 */
4066 "123456789abcdef0123456789abcdef0123456789>\n<ef0"; /* 0x420 */
4067
4068 /* Test odd corners of the XML_GetBuffer interface */
START_TEST(test_get_buffer_1)4069 START_TEST(test_get_buffer_1)
4070 {
4071 const char *text = get_buffer_test_text;
4072 void *buffer;
4073 long context_bytes;
4074
4075 /* Attempt to allocate a negative length buffer */
4076 if (XML_GetBuffer(parser, -12) != NULL)
4077 fail("Negative length buffer not failed");
4078
4079 /* Now get a small buffer and extend it past valid length */
4080 buffer = XML_GetBuffer(parser, 1536);
4081 if (buffer == NULL)
4082 fail("1.5K buffer failed");
4083 memcpy(buffer, text, strlen(text));
4084 if (XML_ParseBuffer(parser, (int)strlen(text), XML_FALSE) == XML_STATUS_ERROR)
4085 xml_failure(parser);
4086 if (XML_GetBuffer(parser, INT_MAX) != NULL)
4087 fail("INT_MAX buffer not failed");
4088
4089 /* Now try extending it a more reasonable but still too large
4090 * amount. The allocator in XML_GetBuffer() doubles the buffer
4091 * size until it exceeds the requested amount or INT_MAX. If it
4092 * exceeds INT_MAX, it rejects the request, so we want a request
4093 * between INT_MAX and INT_MAX/2. A gap of 1K seems comfortable,
4094 * with an extra byte just to ensure that the request is off any
4095 * boundary. The request will be inflated internally by
4096 * XML_CONTEXT_BYTES (if defined), so we subtract that from our
4097 * request.
4098 */
4099 if (get_feature(XML_FEATURE_CONTEXT_BYTES,
4100 &context_bytes) != XML_STATUS_OK)
4101 context_bytes = 0;
4102 if (XML_GetBuffer(parser, INT_MAX - (context_bytes + 1025)) != NULL)
4103 fail("INT_MAX- buffer not failed");
4104
4105 /* Now try extending it a carefully crafted amount */
4106 if (XML_GetBuffer(parser, 1000) == NULL)
4107 fail("1000 buffer failed");
4108 }
4109 END_TEST
4110
4111 /* Test more corners of the XML_GetBuffer interface */
START_TEST(test_get_buffer_2)4112 START_TEST(test_get_buffer_2)
4113 {
4114 const char *text = get_buffer_test_text;
4115 void *buffer;
4116
4117 /* Now get a decent buffer */
4118 buffer = XML_GetBuffer(parser, 1536);
4119 if (buffer == NULL)
4120 fail("1.5K buffer failed");
4121 memcpy(buffer, text, strlen(text));
4122 if (XML_ParseBuffer(parser, (int)strlen(text), XML_FALSE) == XML_STATUS_ERROR)
4123 xml_failure(parser);
4124
4125 /* Extend it, to catch a different code path */
4126 if (XML_GetBuffer(parser, 1024) == NULL)
4127 fail("1024 buffer failed");
4128 }
4129 END_TEST
4130
4131 /* Test position information macros */
START_TEST(test_byte_info_at_end)4132 START_TEST(test_byte_info_at_end)
4133 {
4134 const char *text = "<doc></doc>";
4135
4136 if (XML_GetCurrentByteIndex(parser) != -1 ||
4137 XML_GetCurrentByteCount(parser) != 0)
4138 fail("Byte index/count incorrect at start of parse");
4139 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
4140 XML_TRUE) == XML_STATUS_ERROR)
4141 xml_failure(parser);
4142 /* At end, the count will be zero and the index the end of string */
4143 if (XML_GetCurrentByteCount(parser) != 0)
4144 fail("Terminal byte count incorrect");
4145 if (XML_GetCurrentByteIndex(parser) != (XML_Index)strlen(text))
4146 fail("Terminal byte index incorrect");
4147 }
4148 END_TEST
4149
4150 /* Test position information from errors */
4151 #define PRE_ERROR_STR "<doc></"
4152 #define POST_ERROR_STR "wombat></doc>"
START_TEST(test_byte_info_at_error)4153 START_TEST(test_byte_info_at_error)
4154 {
4155 const char *text = PRE_ERROR_STR POST_ERROR_STR;
4156
4157 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
4158 XML_TRUE) == XML_STATUS_OK)
4159 fail("Syntax error not faulted");
4160 if (XML_GetCurrentByteCount(parser) != 0)
4161 fail("Error byte count incorrect");
4162 if (XML_GetCurrentByteIndex(parser) != strlen(PRE_ERROR_STR))
4163 fail("Error byte index incorrect");
4164 }
4165 END_TEST
4166 #undef PRE_ERROR_STR
4167 #undef POST_ERROR_STR
4168
4169 /* Test position information in handler */
4170 typedef struct ByteTestData {
4171 int start_element_len;
4172 int cdata_len;
4173 int total_string_len;
4174 } ByteTestData;
4175
4176 static void
byte_character_handler(void * userData,const XML_Char * UNUSED_P (s),int len)4177 byte_character_handler(void *userData,
4178 const XML_Char *UNUSED_P(s),
4179 int len)
4180 {
4181 #ifdef XML_CONTEXT_BYTES
4182 int offset, size;
4183 const char *buffer;
4184 ByteTestData *data = (ByteTestData *)userData;
4185
4186 buffer = XML_GetInputContext(parser, &offset, &size);
4187 if (buffer == NULL)
4188 fail("Failed to get context buffer");
4189 if (offset != data->start_element_len)
4190 fail("Context offset in unexpected position");
4191 if (len != data->cdata_len)
4192 fail("CDATA length reported incorrectly");
4193 if (size != data->total_string_len)
4194 fail("Context size is not full buffer");
4195 if (XML_GetCurrentByteIndex(parser) != offset)
4196 fail("Character byte index incorrect");
4197 if (XML_GetCurrentByteCount(parser) != len)
4198 fail("Character byte count incorrect");
4199 #else
4200 (void)userData;
4201 (void)len;
4202 #endif
4203 }
4204
4205 #define START_ELEMENT "<e>"
4206 #define CDATA_TEXT "Hello"
4207 #define END_ELEMENT "</e>"
START_TEST(test_byte_info_at_cdata)4208 START_TEST(test_byte_info_at_cdata)
4209 {
4210 const char *text = START_ELEMENT CDATA_TEXT END_ELEMENT;
4211 int offset, size;
4212 ByteTestData data;
4213
4214 /* Check initial context is empty */
4215 if (XML_GetInputContext(parser, &offset, &size) != NULL)
4216 fail("Unexpected context at start of parse");
4217
4218 data.start_element_len = (int)strlen(START_ELEMENT);
4219 data.cdata_len = (int)strlen(CDATA_TEXT);
4220 data.total_string_len = (int)strlen(text);
4221 XML_SetCharacterDataHandler(parser, byte_character_handler);
4222 XML_SetUserData(parser, &data);
4223 if (XML_Parse(parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_OK)
4224 xml_failure(parser);
4225 }
4226 END_TEST
4227 #undef START_ELEMENT
4228 #undef CDATA_TEXT
4229 #undef END_ELEMENT
4230
4231 /* Test predefined entities are correctly recognised */
START_TEST(test_predefined_entities)4232 START_TEST(test_predefined_entities)
4233 {
4234 const char *text = "<doc><>&"'</doc>";
4235 const XML_Char *expected = XCS("<doc><>&"'</doc>");
4236 const XML_Char *result = XCS("<>&\"'");
4237 CharData storage;
4238
4239 XML_SetDefaultHandler(parser, accumulate_characters);
4240 /* run_character_check uses XML_SetCharacterDataHandler(), which
4241 * unfortunately heads off a code path that we need to exercise.
4242 */
4243 CharData_Init(&storage);
4244 XML_SetUserData(parser, &storage);
4245 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
4246 XML_TRUE) == XML_STATUS_ERROR)
4247 xml_failure(parser);
4248 /* The default handler doesn't translate the entities */
4249 CharData_CheckXMLChars(&storage, expected);
4250
4251 /* Now try again and check the translation */
4252 XML_ParserReset(parser, NULL);
4253 run_character_check(text, result);
4254 }
4255 END_TEST
4256
4257 /* Regression test that an invalid tag in an external parameter
4258 * reference in an external DTD is correctly faulted.
4259 *
4260 * Only a few specific tags are legal in DTDs ignoring comments and
4261 * processing instructions, all of which begin with an exclamation
4262 * mark. "<el/>" is not one of them, so the parser should raise an
4263 * error on encountering it.
4264 */
4265 static int XMLCALL
external_entity_param(XML_Parser parser,const XML_Char * context,const XML_Char * UNUSED_P (base),const XML_Char * systemId,const XML_Char * UNUSED_P (publicId))4266 external_entity_param(XML_Parser parser,
4267 const XML_Char *context,
4268 const XML_Char *UNUSED_P(base),
4269 const XML_Char *systemId,
4270 const XML_Char *UNUSED_P(publicId))
4271 {
4272 const char *text1 =
4273 "<!ELEMENT doc EMPTY>\n"
4274 "<!ENTITY % e1 SYSTEM '004-2.ent'>\n"
4275 "<!ENTITY % e2 '%e1;'>\n"
4276 "%e1;\n";
4277 const char *text2 =
4278 "<!ELEMENT el EMPTY>\n"
4279 "<el/>\n";
4280 XML_Parser ext_parser;
4281
4282 if (systemId == NULL)
4283 return XML_STATUS_OK;
4284
4285 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
4286 if (ext_parser == NULL)
4287 fail("Could not create external entity parser");
4288
4289 if (!xcstrcmp(systemId, XCS("004-1.ent"))) {
4290 if (_XML_Parse_SINGLE_BYTES(ext_parser, text1, (int)strlen(text1),
4291 XML_TRUE) != XML_STATUS_ERROR)
4292 fail("Inner DTD with invalid tag not rejected");
4293 if (XML_GetErrorCode(ext_parser) != XML_ERROR_EXTERNAL_ENTITY_HANDLING)
4294 xml_failure(ext_parser);
4295 }
4296 else if (!xcstrcmp(systemId, XCS("004-2.ent"))) {
4297 if (_XML_Parse_SINGLE_BYTES(ext_parser, text2, (int)strlen(text2),
4298 XML_TRUE) != XML_STATUS_ERROR)
4299 fail("Invalid tag in external param not rejected");
4300 if (XML_GetErrorCode(ext_parser) != XML_ERROR_SYNTAX)
4301 xml_failure(ext_parser);
4302 } else {
4303 fail("Unknown system ID");
4304 }
4305
4306 XML_ParserFree(ext_parser);
4307 return XML_STATUS_ERROR;
4308 }
4309
START_TEST(test_invalid_tag_in_dtd)4310 START_TEST(test_invalid_tag_in_dtd)
4311 {
4312 const char *text =
4313 "<!DOCTYPE doc SYSTEM '004-1.ent'>\n"
4314 "<doc></doc>\n";
4315
4316 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
4317 XML_SetExternalEntityRefHandler(parser, external_entity_param);
4318 expect_failure(text, XML_ERROR_EXTERNAL_ENTITY_HANDLING,
4319 "Invalid tag IN DTD external param not rejected");
4320 }
4321 END_TEST
4322
4323 /* Test entities not quite the predefined ones are not mis-recognised */
START_TEST(test_not_predefined_entities)4324 START_TEST(test_not_predefined_entities)
4325 {
4326 const char *text[] = {
4327 "<doc>&pt;</doc>",
4328 "<doc>&amo;</doc>",
4329 "<doc>&quid;</doc>",
4330 "<doc>&apod;</doc>",
4331 NULL
4332 };
4333 int i = 0;
4334
4335 while (text[i] != NULL) {
4336 expect_failure(text[i], XML_ERROR_UNDEFINED_ENTITY,
4337 "Undefined entity not rejected");
4338 XML_ParserReset(parser, NULL);
4339 i++;
4340 }
4341 }
4342 END_TEST
4343
4344 /* Test conditional inclusion (IGNORE) */
4345 static int XMLCALL
external_entity_load_ignore(XML_Parser parser,const XML_Char * context,const XML_Char * UNUSED_P (base),const XML_Char * UNUSED_P (systemId),const XML_Char * UNUSED_P (publicId))4346 external_entity_load_ignore(XML_Parser parser,
4347 const XML_Char *context,
4348 const XML_Char *UNUSED_P(base),
4349 const XML_Char *UNUSED_P(systemId),
4350 const XML_Char *UNUSED_P(publicId))
4351 {
4352 const char *text = "<![IGNORE[<!ELEMENT e (#PCDATA)*>]]>";
4353 XML_Parser ext_parser;
4354
4355 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
4356 if (ext_parser == NULL)
4357 fail("Could not create external entity parser");
4358 if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text),
4359 XML_TRUE) == XML_STATUS_ERROR)
4360 xml_failure(parser);
4361
4362 XML_ParserFree(ext_parser);
4363 return XML_STATUS_OK;
4364 }
4365
START_TEST(test_ignore_section)4366 START_TEST(test_ignore_section)
4367 {
4368 const char *text =
4369 "<!DOCTYPE doc SYSTEM 'foo'>\n"
4370 "<doc><e>&entity;</e></doc>";
4371 const XML_Char *expected =
4372 XCS("<![IGNORE[<!ELEMENT e (#PCDATA)*>]]>\n&entity;");
4373 CharData storage;
4374
4375 CharData_Init(&storage);
4376 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
4377 XML_SetUserData(parser, &storage);
4378 XML_SetExternalEntityRefHandler(parser, external_entity_load_ignore);
4379 XML_SetDefaultHandler(parser, accumulate_characters);
4380 XML_SetStartDoctypeDeclHandler(parser, dummy_start_doctype_handler);
4381 XML_SetEndDoctypeDeclHandler(parser, dummy_end_doctype_handler);
4382 XML_SetElementDeclHandler(parser, dummy_element_decl_handler);
4383 XML_SetStartElementHandler(parser, dummy_start_element);
4384 XML_SetEndElementHandler(parser, dummy_end_element);
4385 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
4386 XML_TRUE) == XML_STATUS_ERROR)
4387 xml_failure(parser);
4388 CharData_CheckXMLChars(&storage, expected);
4389 }
4390 END_TEST
4391
4392 static int XMLCALL
external_entity_load_ignore_utf16(XML_Parser parser,const XML_Char * context,const XML_Char * UNUSED_P (base),const XML_Char * UNUSED_P (systemId),const XML_Char * UNUSED_P (publicId))4393 external_entity_load_ignore_utf16(XML_Parser parser,
4394 const XML_Char *context,
4395 const XML_Char *UNUSED_P(base),
4396 const XML_Char *UNUSED_P(systemId),
4397 const XML_Char *UNUSED_P(publicId))
4398 {
4399 const char text[] =
4400 /* <![IGNORE[<!ELEMENT e (#PCDATA)*>]]> */
4401 "<\0!\0[\0I\0G\0N\0O\0R\0E\0[\0"
4402 "<\0!\0E\0L\0E\0M\0E\0N\0T\0 \0e\0 \0"
4403 "(\0#\0P\0C\0D\0A\0T\0A\0)\0*\0>\0]\0]\0>\0";
4404 XML_Parser ext_parser;
4405
4406 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
4407 if (ext_parser == NULL)
4408 fail("Could not create external entity parser");
4409 if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)sizeof(text)-1,
4410 XML_TRUE) == XML_STATUS_ERROR)
4411 xml_failure(parser);
4412
4413 XML_ParserFree(ext_parser);
4414 return XML_STATUS_OK;
4415 }
4416
START_TEST(test_ignore_section_utf16)4417 START_TEST(test_ignore_section_utf16)
4418 {
4419 const char text[] =
4420 /* <!DOCTYPE d SYSTEM 's'> */
4421 "<\0!\0D\0O\0C\0T\0Y\0P\0E\0 \0d\0 "
4422 "\0S\0Y\0S\0T\0E\0M\0 \0'\0s\0'\0>\0\n\0"
4423 /* <d><e>&en;</e></d> */
4424 "<\0d\0>\0<\0e\0>\0&\0e\0n\0;\0<\0/\0e\0>\0<\0/\0d\0>\0";
4425 const XML_Char *expected =
4426 XCS("<![IGNORE[<!ELEMENT e (#PCDATA)*>]]>\n&en;");
4427 CharData storage;
4428
4429 CharData_Init(&storage);
4430 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
4431 XML_SetUserData(parser, &storage);
4432 XML_SetExternalEntityRefHandler(parser,
4433 external_entity_load_ignore_utf16);
4434 XML_SetDefaultHandler(parser, accumulate_characters);
4435 XML_SetStartDoctypeDeclHandler(parser, dummy_start_doctype_handler);
4436 XML_SetEndDoctypeDeclHandler(parser, dummy_end_doctype_handler);
4437 XML_SetElementDeclHandler(parser, dummy_element_decl_handler);
4438 XML_SetStartElementHandler(parser, dummy_start_element);
4439 XML_SetEndElementHandler(parser, dummy_end_element);
4440 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text)-1,
4441 XML_TRUE) == XML_STATUS_ERROR)
4442 xml_failure(parser);
4443 CharData_CheckXMLChars(&storage, expected);
4444 }
4445 END_TEST
4446
4447 static int XMLCALL
external_entity_load_ignore_utf16_be(XML_Parser parser,const XML_Char * context,const XML_Char * UNUSED_P (base),const XML_Char * UNUSED_P (systemId),const XML_Char * UNUSED_P (publicId))4448 external_entity_load_ignore_utf16_be(XML_Parser parser,
4449 const XML_Char *context,
4450 const XML_Char *UNUSED_P(base),
4451 const XML_Char *UNUSED_P(systemId),
4452 const XML_Char *UNUSED_P(publicId))
4453 {
4454 const char text[] =
4455 /* <![IGNORE[<!ELEMENT e (#PCDATA)*>]]> */
4456 "\0<\0!\0[\0I\0G\0N\0O\0R\0E\0["
4457 "\0<\0!\0E\0L\0E\0M\0E\0N\0T\0 \0e\0 "
4458 "\0(\0#\0P\0C\0D\0A\0T\0A\0)\0*\0>\0]\0]\0>";
4459 XML_Parser ext_parser;
4460
4461 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
4462 if (ext_parser == NULL)
4463 fail("Could not create external entity parser");
4464 if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)sizeof(text)-1,
4465 XML_TRUE) == XML_STATUS_ERROR)
4466 xml_failure(parser);
4467
4468 XML_ParserFree(ext_parser);
4469 return XML_STATUS_OK;
4470 }
4471
START_TEST(test_ignore_section_utf16_be)4472 START_TEST(test_ignore_section_utf16_be)
4473 {
4474 const char text[] =
4475 /* <!DOCTYPE d SYSTEM 's'> */
4476 "\0<\0!\0D\0O\0C\0T\0Y\0P\0E\0 \0d\0 "
4477 "\0S\0Y\0S\0T\0E\0M\0 \0'\0s\0'\0>\0\n"
4478 /* <d><e>&en;</e></d> */
4479 "\0<\0d\0>\0<\0e\0>\0&\0e\0n\0;\0<\0/\0e\0>\0<\0/\0d\0>";
4480 const XML_Char *expected =
4481 XCS("<![IGNORE[<!ELEMENT e (#PCDATA)*>]]>\n&en;");
4482 CharData storage;
4483
4484 CharData_Init(&storage);
4485 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
4486 XML_SetUserData(parser, &storage);
4487 XML_SetExternalEntityRefHandler(parser,
4488 external_entity_load_ignore_utf16_be);
4489 XML_SetDefaultHandler(parser, accumulate_characters);
4490 XML_SetStartDoctypeDeclHandler(parser, dummy_start_doctype_handler);
4491 XML_SetEndDoctypeDeclHandler(parser, dummy_end_doctype_handler);
4492 XML_SetElementDeclHandler(parser, dummy_element_decl_handler);
4493 XML_SetStartElementHandler(parser, dummy_start_element);
4494 XML_SetEndElementHandler(parser, dummy_end_element);
4495 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text)-1,
4496 XML_TRUE) == XML_STATUS_ERROR)
4497 xml_failure(parser);
4498 CharData_CheckXMLChars(&storage, expected);
4499 }
4500 END_TEST
4501
4502 /* Test mis-formatted conditional exclusion */
START_TEST(test_bad_ignore_section)4503 START_TEST(test_bad_ignore_section)
4504 {
4505 const char *text =
4506 "<!DOCTYPE doc SYSTEM 'foo'>\n"
4507 "<doc><e>&entity;</e></doc>";
4508 ExtFaults faults[] = {
4509 {
4510 "<![IGNORE[<!ELEM",
4511 "Broken-off declaration not faulted",
4512 NULL,
4513 XML_ERROR_SYNTAX
4514 },
4515 {
4516 "<![IGNORE[\x01]]>",
4517 "Invalid XML character not faulted",
4518 NULL,
4519 XML_ERROR_INVALID_TOKEN
4520 },
4521 {
4522 /* FIrst two bytes of a three-byte char */
4523 "<![IGNORE[\xe2\x82",
4524 "Partial XML character not faulted",
4525 NULL,
4526 XML_ERROR_PARTIAL_CHAR
4527 },
4528 { NULL, NULL, NULL, XML_ERROR_NONE }
4529 };
4530 ExtFaults *fault;
4531
4532 for (fault = &faults[0]; fault->parse_text != NULL; fault++) {
4533 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
4534 XML_SetExternalEntityRefHandler(parser, external_entity_faulter);
4535 XML_SetUserData(parser, fault);
4536 expect_failure(text, XML_ERROR_EXTERNAL_ENTITY_HANDLING,
4537 "Incomplete IGNORE section not failed");
4538 XML_ParserReset(parser, NULL);
4539 }
4540 }
4541 END_TEST
4542
4543 /* Test recursive parsing */
4544 static int XMLCALL
external_entity_valuer(XML_Parser parser,const XML_Char * context,const XML_Char * UNUSED_P (base),const XML_Char * systemId,const XML_Char * UNUSED_P (publicId))4545 external_entity_valuer(XML_Parser parser,
4546 const XML_Char *context,
4547 const XML_Char *UNUSED_P(base),
4548 const XML_Char *systemId,
4549 const XML_Char *UNUSED_P(publicId))
4550 {
4551 const char *text1 =
4552 "<!ELEMENT doc EMPTY>\n"
4553 "<!ENTITY % e1 SYSTEM '004-2.ent'>\n"
4554 "<!ENTITY % e2 '%e1;'>\n"
4555 "%e1;\n";
4556 XML_Parser ext_parser;
4557
4558 if (systemId == NULL)
4559 return XML_STATUS_OK;
4560 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
4561 if (ext_parser == NULL)
4562 fail("Could not create external entity parser");
4563 if (!xcstrcmp(systemId, XCS("004-1.ent"))) {
4564 if (_XML_Parse_SINGLE_BYTES(ext_parser, text1, (int)strlen(text1),
4565 XML_TRUE) == XML_STATUS_ERROR)
4566 xml_failure(ext_parser);
4567 }
4568 else if (!xcstrcmp(systemId, XCS("004-2.ent"))) {
4569 ExtFaults *fault = (ExtFaults *)XML_GetUserData(parser);
4570 enum XML_Status status;
4571 enum XML_Error error;
4572
4573 status = _XML_Parse_SINGLE_BYTES(ext_parser,
4574 fault->parse_text,
4575 (int)strlen(fault->parse_text),
4576 XML_TRUE);
4577 if (fault->error == XML_ERROR_NONE) {
4578 if (status == XML_STATUS_ERROR)
4579 xml_failure(ext_parser);
4580 } else {
4581 if (status != XML_STATUS_ERROR)
4582 fail(fault->fail_text);
4583 error = XML_GetErrorCode(ext_parser);
4584 if (error != fault->error &&
4585 (fault->error != XML_ERROR_XML_DECL ||
4586 error != XML_ERROR_TEXT_DECL))
4587 xml_failure(ext_parser);
4588 }
4589 }
4590
4591 XML_ParserFree(ext_parser);
4592 return XML_STATUS_OK;
4593 }
4594
START_TEST(test_external_entity_values)4595 START_TEST(test_external_entity_values)
4596 {
4597 const char *text =
4598 "<!DOCTYPE doc SYSTEM '004-1.ent'>\n"
4599 "<doc></doc>\n";
4600 ExtFaults data_004_2[] = {
4601 {
4602 "<!ATTLIST doc a1 CDATA 'value'>",
4603 NULL,
4604 NULL,
4605 XML_ERROR_NONE
4606 },
4607 {
4608 "<!ATTLIST $doc a1 CDATA 'value'>",
4609 "Invalid token not faulted",
4610 NULL,
4611 XML_ERROR_INVALID_TOKEN
4612 },
4613 {
4614 "'wombat",
4615 "Unterminated string not faulted",
4616 NULL,
4617 XML_ERROR_UNCLOSED_TOKEN
4618 },
4619 {
4620 "\xe2\x82",
4621 "Partial UTF-8 character not faulted",
4622 NULL,
4623 XML_ERROR_PARTIAL_CHAR
4624 },
4625 {
4626 "<?xml version='1.0' encoding='utf-8'?>\n",
4627 NULL,
4628 NULL,
4629 XML_ERROR_NONE
4630 },
4631 {
4632 "<?xml?>",
4633 "Malformed XML declaration not faulted",
4634 NULL,
4635 XML_ERROR_XML_DECL
4636 },
4637 {
4638 /* UTF-8 BOM */
4639 "\xEF\xBB\xBF<!ATTLIST doc a1 CDATA 'value'>",
4640 NULL,
4641 NULL,
4642 XML_ERROR_NONE
4643 },
4644 {
4645 "<?xml version='1.0' encoding='utf-8'?>\n$",
4646 "Invalid token after text declaration not faulted",
4647 NULL,
4648 XML_ERROR_INVALID_TOKEN
4649 },
4650 {
4651 "<?xml version='1.0' encoding='utf-8'?>\n'wombat",
4652 "Unterminated string after text decl not faulted",
4653 NULL,
4654 XML_ERROR_UNCLOSED_TOKEN
4655 },
4656 {
4657 "<?xml version='1.0' encoding='utf-8'?>\n\xe2\x82",
4658 "Partial UTF-8 character after text decl not faulted",
4659 NULL,
4660 XML_ERROR_PARTIAL_CHAR
4661 },
4662 {
4663 "%e1;",
4664 "Recursive parameter entity not faulted",
4665 NULL,
4666 XML_ERROR_RECURSIVE_ENTITY_REF
4667 },
4668 { NULL, NULL, NULL, XML_ERROR_NONE }
4669 };
4670 int i;
4671
4672 for (i = 0; data_004_2[i].parse_text != NULL; i++) {
4673 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
4674 XML_SetExternalEntityRefHandler(parser, external_entity_valuer);
4675 XML_SetUserData(parser, &data_004_2[i]);
4676 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
4677 XML_TRUE) == XML_STATUS_ERROR)
4678 xml_failure(parser);
4679 XML_ParserReset(parser, NULL);
4680 }
4681 }
4682 END_TEST
4683
4684 /* Test the recursive parse interacts with a not standalone handler */
4685 static int XMLCALL
external_entity_not_standalone(XML_Parser parser,const XML_Char * context,const XML_Char * UNUSED_P (base),const XML_Char * systemId,const XML_Char * UNUSED_P (publicId))4686 external_entity_not_standalone(XML_Parser parser,
4687 const XML_Char *context,
4688 const XML_Char *UNUSED_P(base),
4689 const XML_Char *systemId,
4690 const XML_Char *UNUSED_P(publicId))
4691 {
4692 const char *text1 =
4693 "<!ELEMENT doc EMPTY>\n"
4694 "<!ENTITY % e1 SYSTEM 'bar'>\n"
4695 "%e1;\n";
4696 const char *text2 = "<!ATTLIST doc a1 CDATA 'value'>";
4697 XML_Parser ext_parser;
4698
4699 if (systemId == NULL)
4700 return XML_STATUS_OK;
4701 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
4702 if (ext_parser == NULL)
4703 fail("Could not create external entity parser");
4704 if (!xcstrcmp(systemId, XCS("foo"))) {
4705 XML_SetNotStandaloneHandler(ext_parser,
4706 reject_not_standalone_handler);
4707 if (_XML_Parse_SINGLE_BYTES(ext_parser, text1, (int)strlen(text1),
4708 XML_TRUE) != XML_STATUS_ERROR)
4709 fail("Expected not standalone rejection");
4710 if (XML_GetErrorCode(ext_parser) != XML_ERROR_NOT_STANDALONE)
4711 xml_failure(ext_parser);
4712 XML_SetNotStandaloneHandler(ext_parser, NULL);
4713 XML_ParserFree(ext_parser);
4714 return XML_STATUS_ERROR;
4715 }
4716 else if (!xcstrcmp(systemId, XCS("bar"))) {
4717 if (_XML_Parse_SINGLE_BYTES(ext_parser, text2, (int)strlen(text2),
4718 XML_TRUE) == XML_STATUS_ERROR)
4719 xml_failure(ext_parser);
4720 }
4721
4722 XML_ParserFree(ext_parser);
4723 return XML_STATUS_OK;
4724 }
4725
START_TEST(test_ext_entity_not_standalone)4726 START_TEST(test_ext_entity_not_standalone)
4727 {
4728 const char *text =
4729 "<!DOCTYPE doc SYSTEM 'foo'>\n"
4730 "<doc></doc>";
4731
4732 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
4733 XML_SetExternalEntityRefHandler(parser, external_entity_not_standalone);
4734 expect_failure(text, XML_ERROR_EXTERNAL_ENTITY_HANDLING,
4735 "Standalone rejection not caught");
4736 }
4737 END_TEST
4738
4739 static int XMLCALL
external_entity_value_aborter(XML_Parser parser,const XML_Char * context,const XML_Char * UNUSED_P (base),const XML_Char * systemId,const XML_Char * UNUSED_P (publicId))4740 external_entity_value_aborter(XML_Parser parser,
4741 const XML_Char *context,
4742 const XML_Char *UNUSED_P(base),
4743 const XML_Char *systemId,
4744 const XML_Char *UNUSED_P(publicId))
4745 {
4746 const char *text1 =
4747 "<!ELEMENT doc EMPTY>\n"
4748 "<!ENTITY % e1 SYSTEM '004-2.ent'>\n"
4749 "<!ENTITY % e2 '%e1;'>\n"
4750 "%e1;\n";
4751 const char *text2 =
4752 "<?xml version='1.0' encoding='utf-8'?>";
4753 XML_Parser ext_parser;
4754
4755 if (systemId == NULL)
4756 return XML_STATUS_OK;
4757 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
4758 if (ext_parser == NULL)
4759 fail("Could not create external entity parser");
4760 if (!xcstrcmp(systemId, XCS("004-1.ent"))) {
4761 if (_XML_Parse_SINGLE_BYTES(ext_parser, text1, (int)strlen(text1),
4762 XML_TRUE) == XML_STATUS_ERROR)
4763 xml_failure(ext_parser);
4764 }
4765 if (!xcstrcmp(systemId, XCS("004-2.ent"))) {
4766 XML_SetXmlDeclHandler(ext_parser, entity_suspending_xdecl_handler);
4767 XML_SetUserData(ext_parser, ext_parser);
4768 if (_XML_Parse_SINGLE_BYTES(ext_parser, text2, (int)strlen(text2),
4769 XML_TRUE) != XML_STATUS_ERROR)
4770 fail("Aborted parse not faulted");
4771 if (XML_GetErrorCode(ext_parser) != XML_ERROR_ABORTED)
4772 xml_failure(ext_parser);
4773 }
4774
4775 XML_ParserFree(ext_parser);
4776 return XML_STATUS_OK;
4777 }
4778
START_TEST(test_ext_entity_value_abort)4779 START_TEST(test_ext_entity_value_abort)
4780 {
4781 const char *text =
4782 "<!DOCTYPE doc SYSTEM '004-1.ent'>\n"
4783 "<doc></doc>\n";
4784
4785 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
4786 XML_SetExternalEntityRefHandler(parser,
4787 external_entity_value_aborter);
4788 resumable = XML_FALSE;
4789 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
4790 XML_TRUE) == XML_STATUS_ERROR)
4791 xml_failure(parser);
4792 }
4793 END_TEST
4794
START_TEST(test_bad_public_doctype)4795 START_TEST(test_bad_public_doctype)
4796 {
4797 const char *text =
4798 "<?xml version='1.0' encoding='utf-8'?>\n"
4799 "<!DOCTYPE doc PUBLIC '{BadName}' 'test'>\n"
4800 "<doc></doc>";
4801
4802 /* Setting a handler provokes a particular code path */
4803 XML_SetDoctypeDeclHandler(parser,
4804 dummy_start_doctype_handler,
4805 dummy_end_doctype_handler);
4806 expect_failure(text, XML_ERROR_PUBLICID, "Bad Public ID not failed");
4807 }
4808 END_TEST
4809
4810 /* Test based on ibm/valid/P32/ibm32v04.xml */
START_TEST(test_attribute_enum_value)4811 START_TEST(test_attribute_enum_value)
4812 {
4813 const char *text =
4814 "<?xml version='1.0' standalone='no'?>\n"
4815 "<!DOCTYPE animal SYSTEM 'test.dtd'>\n"
4816 "<animal>This is a \n <a/> \n\nyellow tiger</animal>";
4817 ExtTest dtd_data = {
4818 "<!ELEMENT animal (#PCDATA|a)*>\n"
4819 "<!ELEMENT a EMPTY>\n"
4820 "<!ATTLIST animal xml:space (default|preserve) 'preserve'>",
4821 NULL,
4822 NULL
4823 };
4824 const XML_Char *expected = XCS("This is a \n \n\nyellow tiger");
4825
4826 XML_SetExternalEntityRefHandler(parser, external_entity_loader);
4827 XML_SetUserData(parser, &dtd_data);
4828 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
4829 /* An attribute list handler provokes a different code path */
4830 XML_SetAttlistDeclHandler(parser, dummy_attlist_decl_handler);
4831 run_ext_character_check(text, &dtd_data, expected);
4832 }
4833 END_TEST
4834
4835 /* Slightly bizarrely, the library seems to silently ignore entity
4836 * definitions for predefined entities, even when they are wrong. The
4837 * language of the XML 1.0 spec is somewhat unhelpful as to what ought
4838 * to happen, so this is currently treated as acceptable.
4839 */
START_TEST(test_predefined_entity_redefinition)4840 START_TEST(test_predefined_entity_redefinition)
4841 {
4842 const char *text =
4843 "<!DOCTYPE doc [\n"
4844 "<!ENTITY apos 'foo'>\n"
4845 "]>\n"
4846 "<doc>'</doc>";
4847 run_character_check(text, XCS("'"));
4848 }
4849 END_TEST
4850
4851 /* Test that the parser stops processing the DTD after an unresolved
4852 * parameter entity is encountered.
4853 */
START_TEST(test_dtd_stop_processing)4854 START_TEST(test_dtd_stop_processing)
4855 {
4856 const char *text =
4857 "<!DOCTYPE doc [\n"
4858 "%foo;\n"
4859 "<!ENTITY bar 'bas'>\n"
4860 "]><doc/>";
4861
4862 XML_SetEntityDeclHandler(parser, dummy_entity_decl_handler);
4863 dummy_handler_flags = 0;
4864 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
4865 XML_TRUE) == XML_STATUS_ERROR)
4866 xml_failure(parser);
4867 if (dummy_handler_flags != 0)
4868 fail("DTD processing still going after undefined PE");
4869 }
4870 END_TEST
4871
4872 /* Test public notations with no system ID */
START_TEST(test_public_notation_no_sysid)4873 START_TEST(test_public_notation_no_sysid)
4874 {
4875 const char *text =
4876 "<!DOCTYPE doc [\n"
4877 "<!NOTATION note PUBLIC 'foo'>\n"
4878 "<!ELEMENT doc EMPTY>\n"
4879 "]>\n<doc/>";
4880
4881 dummy_handler_flags = 0;
4882 XML_SetNotationDeclHandler(parser, dummy_notation_decl_handler);
4883 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
4884 XML_TRUE) == XML_STATUS_ERROR)
4885 xml_failure(parser);
4886 if (dummy_handler_flags != DUMMY_NOTATION_DECL_HANDLER_FLAG)
4887 fail("Notation declaration handler not called");
4888 }
4889 END_TEST
4890
4891 static void XMLCALL
record_element_start_handler(void * userData,const XML_Char * name,const XML_Char ** UNUSED_P (atts))4892 record_element_start_handler(void *userData,
4893 const XML_Char *name,
4894 const XML_Char **UNUSED_P(atts))
4895 {
4896 CharData_AppendXMLChars((CharData *)userData, name, (int)xcstrlen(name));
4897 }
4898
START_TEST(test_nested_groups)4899 START_TEST(test_nested_groups)
4900 {
4901 const char *text =
4902 "<!DOCTYPE doc [\n"
4903 "<!ELEMENT doc "
4904 /* Sixteen elements per line */
4905 "(e,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,"
4906 "(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?"
4907 "))))))))))))))))))))))))))))))))>\n"
4908 "<!ELEMENT e EMPTY>"
4909 "]>\n"
4910 "<doc><e/></doc>";
4911 CharData storage;
4912
4913 CharData_Init(&storage);
4914 XML_SetElementDeclHandler(parser, dummy_element_decl_handler);
4915 XML_SetStartElementHandler(parser, record_element_start_handler);
4916 XML_SetUserData(parser, &storage);
4917 dummy_handler_flags = 0;
4918 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
4919 XML_TRUE) == XML_STATUS_ERROR)
4920 xml_failure(parser);
4921 CharData_CheckXMLChars(&storage, XCS("doce"));
4922 if (dummy_handler_flags != DUMMY_ELEMENT_DECL_HANDLER_FLAG)
4923 fail("Element handler not fired");
4924 }
4925 END_TEST
4926
START_TEST(test_group_choice)4927 START_TEST(test_group_choice)
4928 {
4929 const char *text =
4930 "<!DOCTYPE doc [\n"
4931 "<!ELEMENT doc (a|b|c)+>\n"
4932 "<!ELEMENT a EMPTY>\n"
4933 "<!ELEMENT b (#PCDATA)>\n"
4934 "<!ELEMENT c ANY>\n"
4935 "]>\n"
4936 "<doc>\n"
4937 "<a/>\n"
4938 "<b attr='foo'>This is a foo</b>\n"
4939 "<c></c>\n"
4940 "</doc>\n";
4941
4942 XML_SetElementDeclHandler(parser, dummy_element_decl_handler);
4943 dummy_handler_flags = 0;
4944 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
4945 XML_TRUE) == XML_STATUS_ERROR)
4946 xml_failure(parser);
4947 if (dummy_handler_flags != DUMMY_ELEMENT_DECL_HANDLER_FLAG)
4948 fail("Element handler flag not raised");
4949 }
4950 END_TEST
4951
4952 static int XMLCALL
external_entity_public(XML_Parser parser,const XML_Char * context,const XML_Char * UNUSED_P (base),const XML_Char * systemId,const XML_Char * publicId)4953 external_entity_public(XML_Parser parser,
4954 const XML_Char *context,
4955 const XML_Char *UNUSED_P(base),
4956 const XML_Char *systemId,
4957 const XML_Char *publicId)
4958 {
4959 const char *text1 = (const char *)XML_GetUserData(parser);
4960 const char *text2 = "<!ATTLIST doc a CDATA 'value'>";
4961 const char *text = NULL;
4962 XML_Parser ext_parser;
4963 int parse_res;
4964
4965 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
4966 if (ext_parser == NULL)
4967 return XML_STATUS_ERROR;
4968 if (systemId != NULL && !xcstrcmp(systemId, XCS("http://example.org/"))) {
4969 text = text1;
4970 }
4971 else if (publicId != NULL && !xcstrcmp(publicId, XCS("foo"))) {
4972 text = text2;
4973 }
4974 else
4975 fail("Unexpected parameters to external entity parser");
4976 parse_res = _XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text),
4977 XML_TRUE);
4978 XML_ParserFree(ext_parser);
4979 return parse_res;
4980 }
4981
START_TEST(test_standalone_parameter_entity)4982 START_TEST(test_standalone_parameter_entity)
4983 {
4984 const char *text =
4985 "<?xml version='1.0' standalone='yes'?>\n"
4986 "<!DOCTYPE doc SYSTEM 'http://example.org/' [\n"
4987 "<!ENTITY % entity '<!ELEMENT doc (#PCDATA)>'>\n"
4988 "%entity;\n"
4989 "]>\n"
4990 "<doc></doc>";
4991 char dtd_data[] =
4992 "<!ENTITY % e1 'foo'>\n";
4993
4994 XML_SetUserData(parser, dtd_data);
4995 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
4996 XML_SetExternalEntityRefHandler(parser, external_entity_public);
4997 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
4998 XML_TRUE) == XML_STATUS_ERROR)
4999 xml_failure(parser);
5000 }
5001 END_TEST
5002
5003 /* Test skipping of parameter entity in an external DTD */
5004 /* Derived from ibm/invalid/P69/ibm69i01.xml */
START_TEST(test_skipped_parameter_entity)5005 START_TEST(test_skipped_parameter_entity)
5006 {
5007 const char *text =
5008 "<?xml version='1.0'?>\n"
5009 "<!DOCTYPE root SYSTEM 'http://example.org/dtd.ent' [\n"
5010 "<!ELEMENT root (#PCDATA|a)* >\n"
5011 "]>\n"
5012 "<root></root>";
5013 ExtTest dtd_data = { "%pe2;", NULL, NULL };
5014
5015 XML_SetExternalEntityRefHandler(parser, external_entity_loader);
5016 XML_SetUserData(parser, &dtd_data);
5017 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
5018 XML_SetSkippedEntityHandler(parser, dummy_skip_handler);
5019 dummy_handler_flags = 0;
5020 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
5021 XML_TRUE) == XML_STATUS_ERROR)
5022 xml_failure(parser);
5023 if (dummy_handler_flags != DUMMY_SKIP_HANDLER_FLAG)
5024 fail("Skip handler not executed");
5025 }
5026 END_TEST
5027
5028 /* Test recursive parameter entity definition rejected in external DTD */
START_TEST(test_recursive_external_parameter_entity)5029 START_TEST(test_recursive_external_parameter_entity)
5030 {
5031 const char *text =
5032 "<?xml version='1.0'?>\n"
5033 "<!DOCTYPE root SYSTEM 'http://example.org/dtd.ent' [\n"
5034 "<!ELEMENT root (#PCDATA|a)* >\n"
5035 "]>\n"
5036 "<root></root>";
5037 ExtFaults dtd_data = {
5038 "<!ENTITY % pe2 '%pe2;'>\n%pe2;",
5039 "Recursive external parameter entity not faulted",
5040 NULL,
5041 XML_ERROR_RECURSIVE_ENTITY_REF
5042 };
5043
5044 XML_SetExternalEntityRefHandler(parser, external_entity_faulter);
5045 XML_SetUserData(parser, &dtd_data);
5046 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
5047 expect_failure(text,
5048 XML_ERROR_EXTERNAL_ENTITY_HANDLING,
5049 "Recursive external parameter not spotted");
5050 }
5051 END_TEST
5052
5053 /* Test undefined parameter entity in external entity handler */
5054 static int XMLCALL
external_entity_devaluer(XML_Parser parser,const XML_Char * context,const XML_Char * UNUSED_P (base),const XML_Char * systemId,const XML_Char * UNUSED_P (publicId))5055 external_entity_devaluer(XML_Parser parser,
5056 const XML_Char *context,
5057 const XML_Char *UNUSED_P(base),
5058 const XML_Char *systemId,
5059 const XML_Char *UNUSED_P(publicId))
5060 {
5061 const char *text =
5062 "<!ELEMENT doc EMPTY>\n"
5063 "<!ENTITY % e1 SYSTEM 'bar'>\n"
5064 "%e1;\n";
5065 XML_Parser ext_parser;
5066 intptr_t clear_handler = (intptr_t)XML_GetUserData(parser);
5067
5068 if (systemId == NULL || !xcstrcmp(systemId, XCS("bar")))
5069 return XML_STATUS_OK;
5070 if (xcstrcmp(systemId, XCS("foo")))
5071 fail("Unexpected system ID");
5072 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
5073 if (ext_parser == NULL)
5074 fail("Could note create external entity parser");
5075 if (clear_handler)
5076 XML_SetExternalEntityRefHandler(ext_parser, NULL);
5077 if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text),
5078 XML_TRUE) == XML_STATUS_ERROR)
5079 xml_failure(ext_parser);
5080
5081 XML_ParserFree(ext_parser);
5082 return XML_STATUS_OK;
5083 }
5084
START_TEST(test_undefined_ext_entity_in_external_dtd)5085 START_TEST(test_undefined_ext_entity_in_external_dtd)
5086 {
5087 const char *text =
5088 "<!DOCTYPE doc SYSTEM 'foo'>\n"
5089 "<doc></doc>\n";
5090
5091 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
5092 XML_SetExternalEntityRefHandler(parser, external_entity_devaluer);
5093 XML_SetUserData(parser, (void *)(intptr_t)XML_FALSE);
5094 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
5095 XML_TRUE) == XML_STATUS_ERROR)
5096 xml_failure(parser);
5097
5098 /* Now repeat without the external entity ref handler invoking
5099 * another copy of itself.
5100 */
5101 XML_ParserReset(parser, NULL);
5102 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
5103 XML_SetExternalEntityRefHandler(parser, external_entity_devaluer);
5104 XML_SetUserData(parser, (void *)(intptr_t)XML_TRUE);
5105 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
5106 XML_TRUE) == XML_STATUS_ERROR)
5107 xml_failure(parser);
5108 }
5109 END_TEST
5110
5111
5112 static void XMLCALL
aborting_xdecl_handler(void * UNUSED_P (userData),const XML_Char * UNUSED_P (version),const XML_Char * UNUSED_P (encoding),int UNUSED_P (standalone))5113 aborting_xdecl_handler(void *UNUSED_P(userData),
5114 const XML_Char *UNUSED_P(version),
5115 const XML_Char *UNUSED_P(encoding),
5116 int UNUSED_P(standalone))
5117 {
5118 XML_StopParser(parser, resumable);
5119 XML_SetXmlDeclHandler(parser, NULL);
5120 }
5121
5122 /* Test suspending the parse on receiving an XML declaration works */
START_TEST(test_suspend_xdecl)5123 START_TEST(test_suspend_xdecl)
5124 {
5125 const char *text = long_character_data_text;
5126
5127 XML_SetXmlDeclHandler(parser, aborting_xdecl_handler);
5128 resumable = XML_TRUE;
5129 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
5130 XML_TRUE) != XML_STATUS_SUSPENDED)
5131 xml_failure(parser);
5132 if (XML_GetErrorCode(parser) != XML_ERROR_NONE)
5133 xml_failure(parser);
5134 /* Attempt to start a new parse while suspended */
5135 if (XML_Parse(parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR)
5136 fail("Attempt to parse while suspended not faulted");
5137 if (XML_GetErrorCode(parser) != XML_ERROR_SUSPENDED)
5138 fail("Suspended parse not faulted with correct error");
5139 }
5140 END_TEST
5141
5142 /* Test aborting the parse in an epilog works */
5143 static void XMLCALL
selective_aborting_default_handler(void * userData,const XML_Char * s,int len)5144 selective_aborting_default_handler(void *userData,
5145 const XML_Char *s,
5146 int len)
5147 {
5148 const XML_Char *match = (const XML_Char *)userData;
5149
5150 if (match == NULL ||
5151 (xcstrlen(match) == (unsigned)len &&
5152 !xcstrncmp(match, s, len))) {
5153 XML_StopParser(parser, resumable);
5154 XML_SetDefaultHandler(parser, NULL);
5155 }
5156 }
5157
START_TEST(test_abort_epilog)5158 START_TEST(test_abort_epilog)
5159 {
5160 const char *text = "<doc></doc>\n\r\n";
5161 XML_Char match[] = XCS("\r");
5162
5163 XML_SetDefaultHandler(parser, selective_aborting_default_handler);
5164 XML_SetUserData(parser, match);
5165 resumable = XML_FALSE;
5166 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
5167 XML_TRUE) != XML_STATUS_ERROR)
5168 fail("Abort not triggered");
5169 if (XML_GetErrorCode(parser) != XML_ERROR_ABORTED)
5170 xml_failure(parser);
5171 }
5172 END_TEST
5173
5174 /* Test a different code path for abort in the epilog */
START_TEST(test_abort_epilog_2)5175 START_TEST(test_abort_epilog_2)
5176 {
5177 const char *text = "<doc></doc>\n";
5178 XML_Char match[] = XCS("\n");
5179
5180 XML_SetDefaultHandler(parser, selective_aborting_default_handler);
5181 XML_SetUserData(parser, match);
5182 resumable = XML_FALSE;
5183 expect_failure(text, XML_ERROR_ABORTED, "Abort not triggered");
5184 }
5185 END_TEST
5186
5187 /* Test suspension from the epilog */
START_TEST(test_suspend_epilog)5188 START_TEST(test_suspend_epilog)
5189 {
5190 const char *text = "<doc></doc>\n";
5191 XML_Char match[] = XCS("\n");
5192
5193 XML_SetDefaultHandler(parser, selective_aborting_default_handler);
5194 XML_SetUserData(parser, match);
5195 resumable = XML_TRUE;
5196 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
5197 XML_TRUE) != XML_STATUS_SUSPENDED)
5198 xml_failure(parser);
5199 }
5200 END_TEST
5201
5202 static void XMLCALL
suspending_end_handler(void * userData,const XML_Char * UNUSED_P (s))5203 suspending_end_handler(void *userData,
5204 const XML_Char *UNUSED_P(s))
5205 {
5206 XML_StopParser((XML_Parser)userData, 1);
5207 }
5208
START_TEST(test_suspend_in_sole_empty_tag)5209 START_TEST(test_suspend_in_sole_empty_tag)
5210 {
5211 const char *text = "<doc/>";
5212 enum XML_Status rc;
5213
5214 XML_SetEndElementHandler(parser, suspending_end_handler);
5215 XML_SetUserData(parser, parser);
5216 rc = _XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
5217 XML_TRUE);
5218 if (rc == XML_STATUS_ERROR)
5219 xml_failure(parser);
5220 else if (rc != XML_STATUS_SUSPENDED)
5221 fail("Suspend not triggered");
5222 rc = XML_ResumeParser(parser);
5223 if (rc == XML_STATUS_ERROR)
5224 xml_failure(parser);
5225 else if (rc != XML_STATUS_OK)
5226 fail("Resume failed");
5227 }
5228 END_TEST
5229
START_TEST(test_unfinished_epilog)5230 START_TEST(test_unfinished_epilog)
5231 {
5232 const char *text = "<doc></doc><";
5233
5234 expect_failure(text, XML_ERROR_UNCLOSED_TOKEN,
5235 "Incomplete epilog entry not faulted");
5236 }
5237 END_TEST
5238
START_TEST(test_partial_char_in_epilog)5239 START_TEST(test_partial_char_in_epilog)
5240 {
5241 const char *text = "<doc></doc>\xe2\x82";
5242
5243 /* First check that no fault is raised if the parse is not finished */
5244 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
5245 XML_FALSE) == XML_STATUS_ERROR)
5246 xml_failure(parser);
5247 /* Now check that it is faulted once we finish */
5248 if (XML_ParseBuffer(parser, 0, XML_TRUE) != XML_STATUS_ERROR)
5249 fail("Partial character in epilog not faulted");
5250 if (XML_GetErrorCode(parser) != XML_ERROR_PARTIAL_CHAR)
5251 xml_failure(parser);
5252 }
5253 END_TEST
5254
START_TEST(test_hash_collision)5255 START_TEST(test_hash_collision)
5256 {
5257 /* For full coverage of the lookup routine, we need to ensure a
5258 * hash collision even though we can only tell that we have one
5259 * through breakpoint debugging or coverage statistics. The
5260 * following will cause a hash collision on machines with a 64-bit
5261 * long type; others will have to experiment. The full coverage
5262 * tests invoked from qa.sh usually provide a hash collision, but
5263 * not always. This is an attempt to provide insurance.
5264 */
5265 #define COLLIDING_HASH_SALT (unsigned long)_SIP_ULL(0xffffffffU, 0xff99fc90U)
5266 const char * text =
5267 "<doc>\n"
5268 "<a1/><a2/><a3/><a4/><a5/><a6/><a7/><a8/>\n"
5269 "<b1></b1><b2 attr='foo'>This is a foo</b2><b3></b3><b4></b4>\n"
5270 "<b5></b5><b6></b6><b7></b7><b8></b8>\n"
5271 "<c1/><c2/><c3/><c4/><c5/><c6/><c7/><c8/>\n"
5272 "<d1/><d2/><d3/><d4/><d5/><d6/><d7/>\n"
5273 "<d8>This triggers the table growth and collides with b2</d8>\n"
5274 "</doc>\n";
5275
5276 XML_SetHashSalt(parser, COLLIDING_HASH_SALT);
5277 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
5278 XML_TRUE) == XML_STATUS_ERROR)
5279 xml_failure(parser);
5280 }
5281 END_TEST
5282 #undef COLLIDING_HASH_SALT
5283
5284 /* Test resuming a parse suspended in entity substitution */
5285 static void XMLCALL
start_element_suspender(void * UNUSED_P (userData),const XML_Char * name,const XML_Char ** UNUSED_P (atts))5286 start_element_suspender(void *UNUSED_P(userData),
5287 const XML_Char *name,
5288 const XML_Char **UNUSED_P(atts))
5289 {
5290 if (!xcstrcmp(name, XCS("suspend")))
5291 XML_StopParser(parser, XML_TRUE);
5292 if (!xcstrcmp(name, XCS("abort")))
5293 XML_StopParser(parser, XML_FALSE);
5294 }
5295
START_TEST(test_suspend_resume_internal_entity)5296 START_TEST(test_suspend_resume_internal_entity)
5297 {
5298 const char *text =
5299 "<!DOCTYPE doc [\n"
5300 "<!ENTITY foo '<suspend>Hi<suspend>Ho</suspend></suspend>'>\n"
5301 "]>\n"
5302 "<doc>&foo;</doc>\n";
5303 const XML_Char *expected1 = XCS("Hi");
5304 const XML_Char *expected2 = XCS("HiHo");
5305 CharData storage;
5306
5307 CharData_Init(&storage);
5308 XML_SetStartElementHandler(parser, start_element_suspender);
5309 XML_SetCharacterDataHandler(parser, accumulate_characters);
5310 XML_SetUserData(parser, &storage);
5311 if (XML_Parse(parser, text, (int)strlen(text),
5312 XML_TRUE) != XML_STATUS_SUSPENDED)
5313 xml_failure(parser);
5314 CharData_CheckXMLChars(&storage, XCS(""));
5315 if (XML_ResumeParser(parser) != XML_STATUS_SUSPENDED)
5316 xml_failure(parser);
5317 CharData_CheckXMLChars(&storage, expected1);
5318 if (XML_ResumeParser(parser) != XML_STATUS_OK)
5319 xml_failure(parser);
5320 CharData_CheckXMLChars(&storage, expected2);
5321 }
5322 END_TEST
5323
5324 /* Test syntax error is caught at parse resumption */
START_TEST(test_resume_entity_with_syntax_error)5325 START_TEST(test_resume_entity_with_syntax_error)
5326 {
5327 const char *text =
5328 "<!DOCTYPE doc [\n"
5329 "<!ENTITY foo '<suspend>Hi</wombat>'>\n"
5330 "]>\n"
5331 "<doc>&foo;</doc>\n";
5332
5333 XML_SetStartElementHandler(parser, start_element_suspender);
5334 if (XML_Parse(parser, text, (int)strlen(text),
5335 XML_TRUE) != XML_STATUS_SUSPENDED)
5336 xml_failure(parser);
5337 if (XML_ResumeParser(parser) != XML_STATUS_ERROR)
5338 fail("Syntax error in entity not faulted");
5339 if (XML_GetErrorCode(parser) != XML_ERROR_TAG_MISMATCH)
5340 xml_failure(parser);
5341 }
5342 END_TEST
5343
5344 /* Test suspending and resuming in a parameter entity substitution */
5345 static void XMLCALL
element_decl_suspender(void * UNUSED_P (userData),const XML_Char * UNUSED_P (name),XML_Content * model)5346 element_decl_suspender(void *UNUSED_P(userData),
5347 const XML_Char *UNUSED_P(name),
5348 XML_Content *model)
5349 {
5350 XML_StopParser(parser, XML_TRUE);
5351 XML_FreeContentModel(parser, model);
5352 }
5353
START_TEST(test_suspend_resume_parameter_entity)5354 START_TEST(test_suspend_resume_parameter_entity)
5355 {
5356 const char *text =
5357 "<!DOCTYPE doc [\n"
5358 "<!ENTITY % foo '<!ELEMENT doc (#PCDATA)*>'>\n"
5359 "%foo;\n"
5360 "]>\n"
5361 "<doc>Hello, world</doc>";
5362 const XML_Char *expected = XCS("Hello, world");
5363 CharData storage;
5364
5365 CharData_Init(&storage);
5366 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
5367 XML_SetElementDeclHandler(parser, element_decl_suspender);
5368 XML_SetCharacterDataHandler(parser, accumulate_characters);
5369 XML_SetUserData(parser, &storage);
5370 if (XML_Parse(parser, text, (int)strlen(text),
5371 XML_TRUE) != XML_STATUS_SUSPENDED)
5372 xml_failure(parser);
5373 CharData_CheckXMLChars(&storage, XCS(""));
5374 if (XML_ResumeParser(parser) != XML_STATUS_OK)
5375 xml_failure(parser);
5376 CharData_CheckXMLChars(&storage, expected);
5377 }
5378 END_TEST
5379
5380 /* Test attempting to use parser after an error is faulted */
START_TEST(test_restart_on_error)5381 START_TEST(test_restart_on_error)
5382 {
5383 const char *text = "<$doc><doc></doc>";
5384
5385 if (XML_Parse(parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR)
5386 fail("Invalid tag name not faulted");
5387 if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_TOKEN)
5388 xml_failure(parser);
5389 if (XML_Parse(parser, NULL, 0, XML_TRUE) != XML_STATUS_ERROR)
5390 fail("Restarting invalid parse not faulted");
5391 if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_TOKEN)
5392 xml_failure(parser);
5393 }
5394 END_TEST
5395
5396 /* Test that angle brackets in an attribute default value are faulted */
START_TEST(test_reject_lt_in_attribute_value)5397 START_TEST(test_reject_lt_in_attribute_value)
5398 {
5399 const char *text =
5400 "<!DOCTYPE doc [<!ATTLIST doc a CDATA '<bar>'>]>\n"
5401 "<doc></doc>";
5402
5403 expect_failure(text, XML_ERROR_INVALID_TOKEN,
5404 "Bad attribute default not faulted");
5405 }
5406 END_TEST
5407
START_TEST(test_reject_unfinished_param_in_att_value)5408 START_TEST(test_reject_unfinished_param_in_att_value)
5409 {
5410 const char *text =
5411 "<!DOCTYPE doc [<!ATTLIST doc a CDATA '&foo'>]>\n"
5412 "<doc></doc>";
5413
5414 expect_failure(text, XML_ERROR_INVALID_TOKEN,
5415 "Bad attribute default not faulted");
5416 }
5417 END_TEST
5418
START_TEST(test_trailing_cr_in_att_value)5419 START_TEST(test_trailing_cr_in_att_value)
5420 {
5421 const char *text = "<doc a='value\r'/>";
5422
5423 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
5424 XML_TRUE) == XML_STATUS_ERROR)
5425 xml_failure(parser);
5426 }
5427 END_TEST
5428
5429 /* Try parsing a general entity within a parameter entity in a
5430 * standalone internal DTD. Covers a corner case in the parser.
5431 */
START_TEST(test_standalone_internal_entity)5432 START_TEST(test_standalone_internal_entity)
5433 {
5434 const char *text =
5435 "<?xml version='1.0' standalone='yes' ?>\n"
5436 "<!DOCTYPE doc [\n"
5437 " <!ELEMENT doc (#PCDATA)>\n"
5438 " <!ENTITY % pe '<!ATTLIST doc att2 CDATA \"≥\">'>\n"
5439 " <!ENTITY ge 'AttDefaultValue'>\n"
5440 " %pe;\n"
5441 "]>\n"
5442 "<doc att2='any'/>";
5443
5444 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
5445 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
5446 XML_TRUE) == XML_STATUS_ERROR)
5447 xml_failure(parser);
5448 }
5449 END_TEST
5450
5451 /* Test that a reference to an unknown external entity is skipped */
START_TEST(test_skipped_external_entity)5452 START_TEST(test_skipped_external_entity)
5453 {
5454 const char *text =
5455 "<!DOCTYPE doc SYSTEM 'http://example.org/'>\n"
5456 "<doc></doc>\n";
5457 ExtTest test_data = {
5458 "<!ELEMENT doc EMPTY>\n"
5459 "<!ENTITY % e2 '%e1;'>\n",
5460 NULL,
5461 NULL
5462 };
5463
5464 XML_SetUserData(parser, &test_data);
5465 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
5466 XML_SetExternalEntityRefHandler(parser, external_entity_loader);
5467 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
5468 XML_TRUE) == XML_STATUS_ERROR)
5469 xml_failure(parser);
5470 }
5471 END_TEST
5472
5473 /* Test a different form of unknown external entity */
5474 typedef struct ext_hdlr_data {
5475 const char *parse_text;
5476 XML_ExternalEntityRefHandler handler;
5477 } ExtHdlrData;
5478
5479 static int XMLCALL
external_entity_oneshot_loader(XML_Parser parser,const XML_Char * context,const XML_Char * UNUSED_P (base),const XML_Char * UNUSED_P (systemId),const XML_Char * UNUSED_P (publicId))5480 external_entity_oneshot_loader(XML_Parser parser,
5481 const XML_Char *context,
5482 const XML_Char *UNUSED_P(base),
5483 const XML_Char *UNUSED_P(systemId),
5484 const XML_Char *UNUSED_P(publicId))
5485 {
5486 ExtHdlrData *test_data = (ExtHdlrData *)XML_GetUserData(parser);
5487 XML_Parser ext_parser;
5488
5489 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
5490 if (ext_parser == NULL)
5491 fail("Could not create external entity parser.");
5492 /* Use the requested entity parser for further externals */
5493 XML_SetExternalEntityRefHandler(ext_parser, test_data->handler);
5494 if ( _XML_Parse_SINGLE_BYTES(ext_parser,
5495 test_data->parse_text,
5496 (int)strlen(test_data->parse_text),
5497 XML_TRUE) == XML_STATUS_ERROR) {
5498 xml_failure(ext_parser);
5499 }
5500
5501 XML_ParserFree(ext_parser);
5502 return XML_STATUS_OK;
5503 }
5504
START_TEST(test_skipped_null_loaded_ext_entity)5505 START_TEST(test_skipped_null_loaded_ext_entity)
5506 {
5507 const char *text =
5508 "<!DOCTYPE doc SYSTEM 'http://example.org/one.ent'>\n"
5509 "<doc />";
5510 ExtHdlrData test_data = {
5511 "<!ENTITY % pe1 SYSTEM 'http://example.org/two.ent'>\n"
5512 "<!ENTITY % pe2 '%pe1;'>\n"
5513 "%pe2;\n",
5514 external_entity_null_loader
5515 };
5516
5517 XML_SetUserData(parser, &test_data);
5518 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
5519 XML_SetExternalEntityRefHandler(parser, external_entity_oneshot_loader);
5520 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
5521 XML_TRUE) == XML_STATUS_ERROR)
5522 xml_failure(parser);
5523 }
5524 END_TEST
5525
START_TEST(test_skipped_unloaded_ext_entity)5526 START_TEST(test_skipped_unloaded_ext_entity)
5527 {
5528 const char *text =
5529 "<!DOCTYPE doc SYSTEM 'http://example.org/one.ent'>\n"
5530 "<doc />";
5531 ExtHdlrData test_data = {
5532 "<!ENTITY % pe1 SYSTEM 'http://example.org/two.ent'>\n"
5533 "<!ENTITY % pe2 '%pe1;'>\n"
5534 "%pe2;\n",
5535 NULL
5536 };
5537
5538 XML_SetUserData(parser, &test_data);
5539 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
5540 XML_SetExternalEntityRefHandler(parser, external_entity_oneshot_loader);
5541 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
5542 XML_TRUE) == XML_STATUS_ERROR)
5543 xml_failure(parser);
5544 }
5545 END_TEST
5546
5547 /* Test that a parameter entity value ending with a carriage return
5548 * has it translated internally into a newline.
5549 */
START_TEST(test_param_entity_with_trailing_cr)5550 START_TEST(test_param_entity_with_trailing_cr)
5551 {
5552 #define PARAM_ENTITY_NAME "pe"
5553 #define PARAM_ENTITY_CORE_VALUE "<!ATTLIST doc att CDATA \"default\">"
5554 const char *text =
5555 "<!DOCTYPE doc SYSTEM 'http://example.org/'>\n"
5556 "<doc/>";
5557 ExtTest test_data = {
5558 "<!ENTITY % " PARAM_ENTITY_NAME
5559 " '" PARAM_ENTITY_CORE_VALUE "\r'>\n"
5560 "%" PARAM_ENTITY_NAME ";\n",
5561 NULL,
5562 NULL
5563 };
5564
5565 XML_SetUserData(parser, &test_data);
5566 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
5567 XML_SetExternalEntityRefHandler(parser, external_entity_loader);
5568 XML_SetEntityDeclHandler(parser, param_entity_match_handler);
5569 entity_name_to_match = XCS(PARAM_ENTITY_NAME);
5570 entity_value_to_match = XCS(PARAM_ENTITY_CORE_VALUE) XCS("\n");
5571 entity_match_flag = ENTITY_MATCH_NOT_FOUND;
5572 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
5573 XML_TRUE) == XML_STATUS_ERROR)
5574 xml_failure(parser);
5575 if (entity_match_flag == ENTITY_MATCH_FAIL)
5576 fail("Parameter entity CR->NEWLINE conversion failed");
5577 else if (entity_match_flag == ENTITY_MATCH_NOT_FOUND)
5578 fail("Parameter entity not parsed");
5579 }
5580 #undef PARAM_ENTITY_NAME
5581 #undef PARAM_ENTITY_CORE_VALUE
5582 END_TEST
5583
START_TEST(test_invalid_character_entity)5584 START_TEST(test_invalid_character_entity)
5585 {
5586 const char *text =
5587 "<!DOCTYPE doc [\n"
5588 " <!ENTITY entity '�'>\n"
5589 "]>\n"
5590 "<doc>&entity;</doc>";
5591
5592 expect_failure(text, XML_ERROR_BAD_CHAR_REF,
5593 "Out of range character reference not faulted");
5594 }
5595 END_TEST
5596
START_TEST(test_invalid_character_entity_2)5597 START_TEST(test_invalid_character_entity_2)
5598 {
5599 const char *text =
5600 "<!DOCTYPE doc [\n"
5601 " <!ENTITY entity '&#xg0;'>\n"
5602 "]>\n"
5603 "<doc>&entity;</doc>";
5604
5605 expect_failure(text, XML_ERROR_INVALID_TOKEN,
5606 "Out of range character reference not faulted");
5607 }
5608 END_TEST
5609
START_TEST(test_invalid_character_entity_3)5610 START_TEST(test_invalid_character_entity_3)
5611 {
5612 const char text[] =
5613 /* <!DOCTYPE doc [\n */
5614 "\0<\0!\0D\0O\0C\0T\0Y\0P\0E\0 \0d\0o\0c\0 \0[\0\n"
5615 /* U+0E04 = KHO KHWAI
5616 * U+0E08 = CHO CHAN */
5617 /* <!ENTITY entity '&\u0e04\u0e08;'>\n */
5618 "\0<\0!\0E\0N\0T\0I\0T\0Y\0 \0e\0n\0t\0i\0t\0y\0 "
5619 "\0'\0&\x0e\x04\x0e\x08\0;\0'\0>\0\n"
5620 /* ]>\n */
5621 "\0]\0>\0\n"
5622 /* <doc>&entity;</doc> */
5623 "\0<\0d\0o\0c\0>\0&\0e\0n\0t\0i\0t\0y\0;\0<\0/\0d\0o\0c\0>";
5624
5625 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text)-1,
5626 XML_TRUE) != XML_STATUS_ERROR)
5627 fail("Invalid start of entity name not faulted");
5628 if (XML_GetErrorCode(parser) != XML_ERROR_UNDEFINED_ENTITY)
5629 xml_failure(parser);
5630 }
5631 END_TEST
5632
START_TEST(test_invalid_character_entity_4)5633 START_TEST(test_invalid_character_entity_4)
5634 {
5635 const char *text =
5636 "<!DOCTYPE doc [\n"
5637 " <!ENTITY entity '�'>\n" /* = � */
5638 "]>\n"
5639 "<doc>&entity;</doc>";
5640
5641 expect_failure(text, XML_ERROR_BAD_CHAR_REF,
5642 "Out of range character reference not faulted");
5643 }
5644 END_TEST
5645
5646
5647 /* Test that processing instructions are picked up by a default handler */
START_TEST(test_pi_handled_in_default)5648 START_TEST(test_pi_handled_in_default)
5649 {
5650 const char *text = "<?test processing instruction?>\n<doc/>";
5651 const XML_Char *expected = XCS("<?test processing instruction?>\n<doc/>");
5652 CharData storage;
5653
5654 CharData_Init(&storage);
5655 XML_SetDefaultHandler(parser, accumulate_characters);
5656 XML_SetUserData(parser, &storage);
5657 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
5658 XML_TRUE)== XML_STATUS_ERROR)
5659 xml_failure(parser);
5660 CharData_CheckXMLChars(&storage, expected);
5661 }
5662 END_TEST
5663
5664
5665 /* Test that comments are picked up by a default handler */
START_TEST(test_comment_handled_in_default)5666 START_TEST(test_comment_handled_in_default)
5667 {
5668 const char *text = "<!-- This is a comment -->\n<doc/>";
5669 const XML_Char *expected = XCS("<!-- This is a comment -->\n<doc/>");
5670 CharData storage;
5671
5672 CharData_Init(&storage);
5673 XML_SetDefaultHandler(parser, accumulate_characters);
5674 XML_SetUserData(parser, &storage);
5675 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
5676 XML_TRUE) == XML_STATUS_ERROR)
5677 xml_failure(parser);
5678 CharData_CheckXMLChars(&storage, expected);
5679 }
5680 END_TEST
5681
5682 /* Test PIs that look almost but not quite like XML declarations */
5683 static void XMLCALL
accumulate_pi_characters(void * userData,const XML_Char * target,const XML_Char * data)5684 accumulate_pi_characters(void *userData,
5685 const XML_Char *target,
5686 const XML_Char *data)
5687 {
5688 CharData *storage = (CharData *)userData;
5689
5690 CharData_AppendXMLChars(storage, target, -1);
5691 CharData_AppendXMLChars(storage, XCS(": "), 2);
5692 CharData_AppendXMLChars(storage, data, -1);
5693 CharData_AppendXMLChars(storage, XCS("\n"), 1);
5694 }
5695
START_TEST(test_pi_yml)5696 START_TEST(test_pi_yml)
5697 {
5698 const char *text = "<?yml something like data?><doc/>";
5699 const XML_Char *expected = XCS("yml: something like data\n");
5700 CharData storage;
5701
5702 CharData_Init(&storage);
5703 XML_SetProcessingInstructionHandler(parser, accumulate_pi_characters);
5704 XML_SetUserData(parser, &storage);
5705 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
5706 XML_TRUE) == XML_STATUS_ERROR)
5707 xml_failure(parser);
5708 CharData_CheckXMLChars(&storage, expected);
5709 }
5710 END_TEST
5711
START_TEST(test_pi_xnl)5712 START_TEST(test_pi_xnl)
5713 {
5714 const char *text = "<?xnl nothing like data?><doc/>";
5715 const XML_Char *expected = XCS("xnl: nothing like data\n");
5716 CharData storage;
5717
5718 CharData_Init(&storage);
5719 XML_SetProcessingInstructionHandler(parser, accumulate_pi_characters);
5720 XML_SetUserData(parser, &storage);
5721 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
5722 XML_TRUE) == XML_STATUS_ERROR)
5723 xml_failure(parser);
5724 CharData_CheckXMLChars(&storage, expected);
5725 }
5726 END_TEST
5727
START_TEST(test_pi_xmm)5728 START_TEST(test_pi_xmm)
5729 {
5730 const char *text = "<?xmm everything like data?><doc/>";
5731 const XML_Char *expected = XCS("xmm: everything like data\n");
5732 CharData storage;
5733
5734 CharData_Init(&storage);
5735 XML_SetProcessingInstructionHandler(parser, accumulate_pi_characters);
5736 XML_SetUserData(parser, &storage);
5737 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
5738 XML_TRUE) == XML_STATUS_ERROR)
5739 xml_failure(parser);
5740 CharData_CheckXMLChars(&storage, expected);
5741 }
5742 END_TEST
5743
START_TEST(test_utf16_pi)5744 START_TEST(test_utf16_pi)
5745 {
5746 const char text[] =
5747 /* <?{KHO KHWAI}{CHO CHAN}?>
5748 * where {KHO KHWAI} = U+0E04
5749 * and {CHO CHAN} = U+0E08
5750 */
5751 "<\0?\0\x04\x0e\x08\x0e?\0>\0"
5752 /* <q/> */
5753 "<\0q\0/\0>\0";
5754 #ifdef XML_UNICODE
5755 const XML_Char *expected = XCS("\x0e04\x0e08: \n");
5756 #else
5757 const XML_Char *expected = XCS("\xe0\xb8\x84\xe0\xb8\x88: \n");
5758 #endif
5759 CharData storage;
5760
5761 CharData_Init(&storage);
5762 XML_SetProcessingInstructionHandler(parser, accumulate_pi_characters);
5763 XML_SetUserData(parser, &storage);
5764 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text)-1,
5765 XML_TRUE) == XML_STATUS_ERROR)
5766 xml_failure(parser);
5767 CharData_CheckXMLChars(&storage, expected);
5768 }
5769 END_TEST
5770
START_TEST(test_utf16_be_pi)5771 START_TEST(test_utf16_be_pi)
5772 {
5773 const char text[] =
5774 /* <?{KHO KHWAI}{CHO CHAN}?>
5775 * where {KHO KHWAI} = U+0E04
5776 * and {CHO CHAN} = U+0E08
5777 */
5778 "\0<\0?\x0e\x04\x0e\x08\0?\0>"
5779 /* <q/> */
5780 "\0<\0q\0/\0>";
5781 #ifdef XML_UNICODE
5782 const XML_Char *expected = XCS("\x0e04\x0e08: \n");
5783 #else
5784 const XML_Char *expected = XCS("\xe0\xb8\x84\xe0\xb8\x88: \n");
5785 #endif
5786 CharData storage;
5787
5788 CharData_Init(&storage);
5789 XML_SetProcessingInstructionHandler(parser, accumulate_pi_characters);
5790 XML_SetUserData(parser, &storage);
5791 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text)-1,
5792 XML_TRUE) == XML_STATUS_ERROR)
5793 xml_failure(parser);
5794 CharData_CheckXMLChars(&storage, expected);
5795 }
5796 END_TEST
5797
5798 /* Test that comments can be picked up and translated */
5799 static void XMLCALL
accumulate_comment(void * userData,const XML_Char * data)5800 accumulate_comment(void *userData,
5801 const XML_Char *data)
5802 {
5803 CharData *storage = (CharData *)userData;
5804
5805 CharData_AppendXMLChars(storage, data, -1);
5806 }
5807
START_TEST(test_utf16_be_comment)5808 START_TEST(test_utf16_be_comment)
5809 {
5810 const char text[] =
5811 /* <!-- Comment A --> */
5812 "\0<\0!\0-\0-\0 \0C\0o\0m\0m\0e\0n\0t\0 \0A\0 \0-\0-\0>\0\n"
5813 /* <doc/> */
5814 "\0<\0d\0o\0c\0/\0>";
5815 const XML_Char *expected = XCS(" Comment A ");
5816 CharData storage;
5817
5818 CharData_Init(&storage);
5819 XML_SetCommentHandler(parser, accumulate_comment);
5820 XML_SetUserData(parser, &storage);
5821 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text)-1,
5822 XML_TRUE) == XML_STATUS_ERROR)
5823 xml_failure(parser);
5824 CharData_CheckXMLChars(&storage, expected);
5825 }
5826 END_TEST
5827
START_TEST(test_utf16_le_comment)5828 START_TEST(test_utf16_le_comment)
5829 {
5830 const char text[] =
5831 /* <!-- Comment B --> */
5832 "<\0!\0-\0-\0 \0C\0o\0m\0m\0e\0n\0t\0 \0B\0 \0-\0-\0>\0\n\0"
5833 /* <doc/> */
5834 "<\0d\0o\0c\0/\0>\0";
5835 const XML_Char *expected = XCS(" Comment B ");
5836 CharData storage;
5837
5838 CharData_Init(&storage);
5839 XML_SetCommentHandler(parser, accumulate_comment);
5840 XML_SetUserData(parser, &storage);
5841 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text)-1,
5842 XML_TRUE) == XML_STATUS_ERROR)
5843 xml_failure(parser);
5844 CharData_CheckXMLChars(&storage, expected);
5845 }
5846 END_TEST
5847
5848 /* Test that the unknown encoding handler with map entries that expect
5849 * conversion but no conversion function is faulted
5850 */
5851 static int XMLCALL
failing_converter(void * UNUSED_P (data),const char * UNUSED_P (s))5852 failing_converter(void *UNUSED_P(data), const char *UNUSED_P(s))
5853 {
5854 /* Always claim to have failed */
5855 return -1;
5856 }
5857
5858 static int XMLCALL
prefix_converter(void * UNUSED_P (data),const char * s)5859 prefix_converter(void *UNUSED_P(data), const char *s)
5860 {
5861 /* If the first byte is 0xff, raise an error */
5862 if (s[0] == (char)-1)
5863 return -1;
5864 /* Just add the low bits of the first byte to the second */
5865 return (s[1] + (s[0] & 0x7f)) & 0x01ff;
5866 }
5867
5868 static int XMLCALL
MiscEncodingHandler(void * data,const XML_Char * encoding,XML_Encoding * info)5869 MiscEncodingHandler(void *data,
5870 const XML_Char *encoding,
5871 XML_Encoding *info)
5872 {
5873 int i;
5874 int high_map = -2; /* Assume a 2-byte sequence */
5875
5876 if (!xcstrcmp(encoding, XCS("invalid-9")) ||
5877 !xcstrcmp(encoding, XCS("ascii-like")) ||
5878 !xcstrcmp(encoding, XCS("invalid-len")) ||
5879 !xcstrcmp(encoding, XCS("invalid-a")) ||
5880 !xcstrcmp(encoding, XCS("invalid-surrogate")) ||
5881 !xcstrcmp(encoding, XCS("invalid-high")))
5882 high_map = -1;
5883
5884 for (i = 0; i < 128; ++i)
5885 info->map[i] = i;
5886 for (; i < 256; ++i)
5887 info->map[i] = high_map;
5888
5889 /* If required, put an invalid value in the ASCII entries */
5890 if (!xcstrcmp(encoding, XCS("invalid-9")))
5891 info->map[9] = 5;
5892 /* If required, have a top-bit set character starts a 5-byte sequence */
5893 if (!xcstrcmp(encoding, XCS("invalid-len")))
5894 info->map[0x81] = -5;
5895 /* If required, make a top-bit set character a valid ASCII character */
5896 if (!xcstrcmp(encoding, XCS("invalid-a")))
5897 info->map[0x82] = 'a';
5898 /* If required, give a top-bit set character a forbidden value,
5899 * what would otherwise be the first of a surrogate pair.
5900 */
5901 if (!xcstrcmp(encoding, XCS("invalid-surrogate")))
5902 info->map[0x83] = 0xd801;
5903 /* If required, give a top-bit set character too high a value */
5904 if (!xcstrcmp(encoding, XCS("invalid-high")))
5905 info->map[0x84] = 0x010101;
5906
5907 info->data = data;
5908 info->release = NULL;
5909 if (!xcstrcmp(encoding, XCS("failing-conv")))
5910 info->convert = failing_converter;
5911 else if (!xcstrcmp(encoding, XCS("prefix-conv")))
5912 info->convert = prefix_converter;
5913 else
5914 info->convert = NULL;
5915 return XML_STATUS_OK;
5916 }
5917
START_TEST(test_missing_encoding_conversion_fn)5918 START_TEST(test_missing_encoding_conversion_fn)
5919 {
5920 const char *text =
5921 "<?xml version='1.0' encoding='no-conv'?>\n"
5922 "<doc>\x81</doc>";
5923
5924 XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL);
5925 /* MiscEncodingHandler sets up an encoding with every top-bit-set
5926 * character introducing a two-byte sequence. For this, it
5927 * requires a convert function. The above function call doesn't
5928 * pass one through, so when BadEncodingHandler actually gets
5929 * called it should supply an invalid encoding.
5930 */
5931 expect_failure(text, XML_ERROR_UNKNOWN_ENCODING,
5932 "Encoding with missing convert() not faulted");
5933 }
5934 END_TEST
5935
START_TEST(test_failing_encoding_conversion_fn)5936 START_TEST(test_failing_encoding_conversion_fn)
5937 {
5938 const char *text =
5939 "<?xml version='1.0' encoding='failing-conv'?>\n"
5940 "<doc>\x81</doc>";
5941
5942 XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL);
5943 /* BadEncodingHandler sets up an encoding with every top-bit-set
5944 * character introducing a two-byte sequence. For this, it
5945 * requires a convert function. The above function call passes
5946 * one that insists all possible sequences are invalid anyway.
5947 */
5948 expect_failure(text, XML_ERROR_INVALID_TOKEN,
5949 "Encoding with failing convert() not faulted");
5950 }
5951 END_TEST
5952
5953 /* Test unknown encoding conversions */
START_TEST(test_unknown_encoding_success)5954 START_TEST(test_unknown_encoding_success)
5955 {
5956 const char *text =
5957 "<?xml version='1.0' encoding='prefix-conv'?>\n"
5958 /* Equivalent to <eoc>Hello, world</eoc> */
5959 "<\x81\x64\x80oc>Hello, world</\x81\x64\x80oc>";
5960
5961 XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL);
5962 run_character_check(text, XCS("Hello, world"));
5963 }
5964 END_TEST
5965
5966 /* Test bad name character in unknown encoding */
START_TEST(test_unknown_encoding_bad_name)5967 START_TEST(test_unknown_encoding_bad_name)
5968 {
5969 const char *text =
5970 "<?xml version='1.0' encoding='prefix-conv'?>\n"
5971 "<\xff\x64oc>Hello, world</\xff\x64oc>";
5972
5973 XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL);
5974 expect_failure(text, XML_ERROR_INVALID_TOKEN,
5975 "Bad name start in unknown encoding not faulted");
5976 }
5977 END_TEST
5978
5979 /* Test bad mid-name character in unknown encoding */
START_TEST(test_unknown_encoding_bad_name_2)5980 START_TEST(test_unknown_encoding_bad_name_2)
5981 {
5982 const char *text =
5983 "<?xml version='1.0' encoding='prefix-conv'?>\n"
5984 "<d\xffoc>Hello, world</d\xffoc>";
5985
5986 XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL);
5987 expect_failure(text, XML_ERROR_INVALID_TOKEN,
5988 "Bad name in unknown encoding not faulted");
5989 }
5990 END_TEST
5991
5992 /* Test element name that is long enough to fill the conversion buffer
5993 * in an unknown encoding, finishing with an encoded character.
5994 */
START_TEST(test_unknown_encoding_long_name_1)5995 START_TEST(test_unknown_encoding_long_name_1)
5996 {
5997 const char *text =
5998 "<?xml version='1.0' encoding='prefix-conv'?>\n"
5999 "<abcdefghabcdefghabcdefghijkl\x80m\x80n\x80o\x80p>"
6000 "Hi"
6001 "</abcdefghabcdefghabcdefghijkl\x80m\x80n\x80o\x80p>";
6002 const XML_Char *expected = XCS("abcdefghabcdefghabcdefghijklmnop");
6003 CharData storage;
6004
6005 CharData_Init(&storage);
6006 XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL);
6007 XML_SetStartElementHandler(parser, record_element_start_handler);
6008 XML_SetUserData(parser, &storage);
6009 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
6010 XML_TRUE) == XML_STATUS_ERROR)
6011 xml_failure(parser);
6012 CharData_CheckXMLChars(&storage, expected);
6013 }
6014 END_TEST
6015
6016 /* Test element name that is long enough to fill the conversion buffer
6017 * in an unknown encoding, finishing with an simple character.
6018 */
START_TEST(test_unknown_encoding_long_name_2)6019 START_TEST(test_unknown_encoding_long_name_2)
6020 {
6021 const char *text =
6022 "<?xml version='1.0' encoding='prefix-conv'?>\n"
6023 "<abcdefghabcdefghabcdefghijklmnop>"
6024 "Hi"
6025 "</abcdefghabcdefghabcdefghijklmnop>";
6026 const XML_Char *expected = XCS("abcdefghabcdefghabcdefghijklmnop");
6027 CharData storage;
6028
6029 CharData_Init(&storage);
6030 XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL);
6031 XML_SetStartElementHandler(parser, record_element_start_handler);
6032 XML_SetUserData(parser, &storage);
6033 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
6034 XML_TRUE) == XML_STATUS_ERROR)
6035 xml_failure(parser);
6036 CharData_CheckXMLChars(&storage, expected);
6037 }
6038 END_TEST
6039
START_TEST(test_invalid_unknown_encoding)6040 START_TEST(test_invalid_unknown_encoding)
6041 {
6042 const char *text =
6043 "<?xml version='1.0' encoding='invalid-9'?>\n"
6044 "<doc>Hello world</doc>";
6045
6046 XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL);
6047 expect_failure(text, XML_ERROR_UNKNOWN_ENCODING,
6048 "Invalid unknown encoding not faulted");
6049 }
6050 END_TEST
6051
START_TEST(test_unknown_ascii_encoding_ok)6052 START_TEST(test_unknown_ascii_encoding_ok)
6053 {
6054 const char *text =
6055 "<?xml version='1.0' encoding='ascii-like'?>\n"
6056 "<doc>Hello, world</doc>";
6057
6058 XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL);
6059 run_character_check(text, XCS("Hello, world"));
6060 }
6061 END_TEST
6062
START_TEST(test_unknown_ascii_encoding_fail)6063 START_TEST(test_unknown_ascii_encoding_fail)
6064 {
6065 const char *text =
6066 "<?xml version='1.0' encoding='ascii-like'?>\n"
6067 "<doc>Hello, \x80 world</doc>";
6068
6069 XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL);
6070 expect_failure(text, XML_ERROR_INVALID_TOKEN,
6071 "Invalid character not faulted");
6072 }
6073 END_TEST
6074
START_TEST(test_unknown_encoding_invalid_length)6075 START_TEST(test_unknown_encoding_invalid_length)
6076 {
6077 const char *text =
6078 "<?xml version='1.0' encoding='invalid-len'?>\n"
6079 "<doc>Hello, world</doc>";
6080
6081 XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL);
6082 expect_failure(text, XML_ERROR_UNKNOWN_ENCODING,
6083 "Invalid unknown encoding not faulted");
6084 }
6085 END_TEST
6086
START_TEST(test_unknown_encoding_invalid_topbit)6087 START_TEST(test_unknown_encoding_invalid_topbit)
6088 {
6089 const char *text =
6090 "<?xml version='1.0' encoding='invalid-a'?>\n"
6091 "<doc>Hello, world</doc>";
6092
6093 XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL);
6094 expect_failure(text, XML_ERROR_UNKNOWN_ENCODING,
6095 "Invalid unknown encoding not faulted");
6096 }
6097 END_TEST
6098
START_TEST(test_unknown_encoding_invalid_surrogate)6099 START_TEST(test_unknown_encoding_invalid_surrogate)
6100 {
6101 const char *text =
6102 "<?xml version='1.0' encoding='invalid-surrogate'?>\n"
6103 "<doc>Hello, \x82 world</doc>";
6104
6105 XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL);
6106 expect_failure(text, XML_ERROR_INVALID_TOKEN,
6107 "Invalid unknown encoding not faulted");
6108 }
6109 END_TEST
6110
START_TEST(test_unknown_encoding_invalid_high)6111 START_TEST(test_unknown_encoding_invalid_high)
6112 {
6113 const char *text =
6114 "<?xml version='1.0' encoding='invalid-high'?>\n"
6115 "<doc>Hello, world</doc>";
6116
6117 XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL);
6118 expect_failure(text, XML_ERROR_UNKNOWN_ENCODING,
6119 "Invalid unknown encoding not faulted");
6120 }
6121 END_TEST
6122
START_TEST(test_unknown_encoding_invalid_attr_value)6123 START_TEST(test_unknown_encoding_invalid_attr_value)
6124 {
6125 const char *text =
6126 "<?xml version='1.0' encoding='prefix-conv'?>\n"
6127 "<doc attr='\xff\x30'/>";
6128
6129 XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL);
6130 expect_failure(text, XML_ERROR_INVALID_TOKEN,
6131 "Invalid attribute valid not faulted");
6132 }
6133 END_TEST
6134
6135 /* Test an external entity parser set to use latin-1 detects UTF-16
6136 * BOMs correctly.
6137 */
6138 enum ee_parse_flags {
6139 EE_PARSE_NONE = 0x00,
6140 EE_PARSE_FULL_BUFFER = 0x01
6141 };
6142
6143 typedef struct ExtTest2 {
6144 const char *parse_text;
6145 int parse_len;
6146 const XML_Char *encoding;
6147 CharData *storage;
6148 enum ee_parse_flags flags;
6149 } ExtTest2;
6150
6151 static int XMLCALL
external_entity_loader2(XML_Parser parser,const XML_Char * context,const XML_Char * UNUSED_P (base),const XML_Char * UNUSED_P (systemId),const XML_Char * UNUSED_P (publicId))6152 external_entity_loader2(XML_Parser parser,
6153 const XML_Char *context,
6154 const XML_Char *UNUSED_P(base),
6155 const XML_Char *UNUSED_P(systemId),
6156 const XML_Char *UNUSED_P(publicId))
6157 {
6158 ExtTest2 *test_data = (ExtTest2 *)XML_GetUserData(parser);
6159 XML_Parser extparser;
6160
6161 extparser = XML_ExternalEntityParserCreate(parser, context, NULL);
6162 if (extparser == NULL)
6163 fail("Coulr not create external entity parser");
6164 if (test_data->encoding != NULL) {
6165 if (!XML_SetEncoding(extparser, test_data->encoding))
6166 fail("XML_SetEncoding() ignored for external entity");
6167 }
6168 if (test_data->flags & EE_PARSE_FULL_BUFFER) {
6169 if (XML_Parse(extparser,
6170 test_data->parse_text,
6171 test_data->parse_len,
6172 XML_TRUE) == XML_STATUS_ERROR) {
6173 xml_failure(extparser);
6174 }
6175 }
6176 else if (_XML_Parse_SINGLE_BYTES(extparser,
6177 test_data->parse_text,
6178 test_data->parse_len,
6179 XML_TRUE) == XML_STATUS_ERROR) {
6180 xml_failure(extparser);
6181 }
6182
6183 XML_ParserFree(extparser);
6184 return XML_STATUS_OK;
6185 }
6186
6187 /* Test that UTF-16 BOM does not select UTF-16 given explicit encoding */
6188 static void XMLCALL
ext2_accumulate_characters(void * userData,const XML_Char * s,int len)6189 ext2_accumulate_characters(void *userData, const XML_Char *s, int len)
6190 {
6191 ExtTest2 *test_data = (ExtTest2 *)userData;
6192 accumulate_characters(test_data->storage, s, len);
6193 }
6194
START_TEST(test_ext_entity_latin1_utf16le_bom)6195 START_TEST(test_ext_entity_latin1_utf16le_bom)
6196 {
6197 const char *text =
6198 "<!DOCTYPE doc [\n"
6199 " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n"
6200 "]>\n"
6201 "<doc>&en;</doc>";
6202 ExtTest2 test_data = {
6203 /* If UTF-16, 0xfeff is the BOM and 0x204c is black left bullet */
6204 /* If Latin-1, 0xff = Y-diaeresis, 0xfe = lowercase thorn,
6205 * 0x4c = L and 0x20 is a space
6206 */
6207 "\xff\xfe\x4c\x20",
6208 4,
6209 XCS("iso-8859-1"),
6210 NULL,
6211 EE_PARSE_NONE
6212 };
6213 #ifdef XML_UNICODE
6214 const XML_Char *expected = XCS("\x00ff\x00feL ");
6215 #else
6216 /* In UTF-8, y-diaeresis is 0xc3 0xbf, lowercase thorn is 0xc3 0xbe */
6217 const XML_Char *expected = XCS("\xc3\xbf\xc3\xbeL ");
6218 #endif
6219 CharData storage;
6220
6221
6222 CharData_Init(&storage);
6223 test_data.storage = &storage;
6224 XML_SetExternalEntityRefHandler(parser, external_entity_loader2);
6225 XML_SetUserData(parser, &test_data);
6226 XML_SetCharacterDataHandler(parser, ext2_accumulate_characters);
6227 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
6228 XML_TRUE) == XML_STATUS_ERROR)
6229 xml_failure(parser);
6230 CharData_CheckXMLChars(&storage, expected);
6231 }
6232 END_TEST
6233
START_TEST(test_ext_entity_latin1_utf16be_bom)6234 START_TEST(test_ext_entity_latin1_utf16be_bom)
6235 {
6236 const char *text =
6237 "<!DOCTYPE doc [\n"
6238 " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n"
6239 "]>\n"
6240 "<doc>&en;</doc>";
6241 ExtTest2 test_data = {
6242 /* If UTF-16, 0xfeff is the BOM and 0x204c is black left bullet */
6243 /* If Latin-1, 0xff = Y-diaeresis, 0xfe = lowercase thorn,
6244 * 0x4c = L and 0x20 is a space
6245 */
6246 "\xfe\xff\x20\x4c",
6247 4,
6248 XCS("iso-8859-1"),
6249 NULL,
6250 EE_PARSE_NONE
6251 };
6252 #ifdef XML_UNICODE
6253 const XML_Char *expected = XCS("\x00fe\x00ff L");
6254 #else
6255 /* In UTF-8, y-diaeresis is 0xc3 0xbf, lowercase thorn is 0xc3 0xbe */
6256 const XML_Char *expected = XCS("\xc3\xbe\xc3\xbf L");
6257 #endif
6258 CharData storage;
6259
6260
6261 CharData_Init(&storage);
6262 test_data.storage = &storage;
6263 XML_SetExternalEntityRefHandler(parser, external_entity_loader2);
6264 XML_SetUserData(parser, &test_data);
6265 XML_SetCharacterDataHandler(parser, ext2_accumulate_characters);
6266 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
6267 XML_TRUE) == XML_STATUS_ERROR)
6268 xml_failure(parser);
6269 CharData_CheckXMLChars(&storage, expected);
6270 }
6271 END_TEST
6272
6273
6274 /* Parsing the full buffer rather than a byte at a time makes a
6275 * difference to the encoding scanning code, so repeat the above tests
6276 * without breaking them down by byte.
6277 */
START_TEST(test_ext_entity_latin1_utf16le_bom2)6278 START_TEST(test_ext_entity_latin1_utf16le_bom2)
6279 {
6280 const char *text =
6281 "<!DOCTYPE doc [\n"
6282 " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n"
6283 "]>\n"
6284 "<doc>&en;</doc>";
6285 ExtTest2 test_data = {
6286 /* If UTF-16, 0xfeff is the BOM and 0x204c is black left bullet */
6287 /* If Latin-1, 0xff = Y-diaeresis, 0xfe = lowercase thorn,
6288 * 0x4c = L and 0x20 is a space
6289 */
6290 "\xff\xfe\x4c\x20",
6291 4,
6292 XCS("iso-8859-1"),
6293 NULL,
6294 EE_PARSE_FULL_BUFFER
6295 };
6296 #ifdef XML_UNICODE
6297 const XML_Char *expected = XCS("\x00ff\x00feL ");
6298 #else
6299 /* In UTF-8, y-diaeresis is 0xc3 0xbf, lowercase thorn is 0xc3 0xbe */
6300 const XML_Char *expected = XCS("\xc3\xbf\xc3\xbeL ");
6301 #endif
6302 CharData storage;
6303
6304
6305 CharData_Init(&storage);
6306 test_data.storage = &storage;
6307 XML_SetExternalEntityRefHandler(parser, external_entity_loader2);
6308 XML_SetUserData(parser, &test_data);
6309 XML_SetCharacterDataHandler(parser, ext2_accumulate_characters);
6310 if (XML_Parse(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR)
6311 xml_failure(parser);
6312 CharData_CheckXMLChars(&storage, expected);
6313 }
6314 END_TEST
6315
START_TEST(test_ext_entity_latin1_utf16be_bom2)6316 START_TEST(test_ext_entity_latin1_utf16be_bom2)
6317 {
6318 const char *text =
6319 "<!DOCTYPE doc [\n"
6320 " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n"
6321 "]>\n"
6322 "<doc>&en;</doc>";
6323 ExtTest2 test_data = {
6324 /* If UTF-16, 0xfeff is the BOM and 0x204c is black left bullet */
6325 /* If Latin-1, 0xff = Y-diaeresis, 0xfe = lowercase thorn,
6326 * 0x4c = L and 0x20 is a space
6327 */
6328 "\xfe\xff\x20\x4c",
6329 4,
6330 XCS("iso-8859-1"),
6331 NULL,
6332 EE_PARSE_FULL_BUFFER
6333 };
6334 #ifdef XML_UNICODE
6335 const XML_Char *expected = XCS("\x00fe\x00ff L");
6336 #else
6337 /* In UTF-8, y-diaeresis is 0xc3 0xbf, lowercase thorn is 0xc3 0xbe */
6338 const XML_Char *expected = "\xc3\xbe\xc3\xbf L";
6339 #endif
6340 CharData storage;
6341
6342
6343 CharData_Init(&storage);
6344 test_data.storage = &storage;
6345 XML_SetExternalEntityRefHandler(parser, external_entity_loader2);
6346 XML_SetUserData(parser, &test_data);
6347 XML_SetCharacterDataHandler(parser, ext2_accumulate_characters);
6348 if (XML_Parse(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR)
6349 xml_failure(parser);
6350 CharData_CheckXMLChars(&storage, expected);
6351 }
6352 END_TEST
6353
6354 /* Test little-endian UTF-16 given an explicit big-endian encoding */
START_TEST(test_ext_entity_utf16_be)6355 START_TEST(test_ext_entity_utf16_be)
6356 {
6357 const char *text =
6358 "<!DOCTYPE doc [\n"
6359 " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n"
6360 "]>\n"
6361 "<doc>&en;</doc>";
6362 ExtTest2 test_data = {
6363 "<\0e\0/\0>\0",
6364 8,
6365 XCS("utf-16be"),
6366 NULL,
6367 EE_PARSE_NONE
6368 };
6369 #ifdef XML_UNICODE
6370 const XML_Char *expected = XCS("\x3c00\x6500\x2f00\x3e00");
6371 #else
6372 const XML_Char *expected =
6373 XCS("\xe3\xb0\x80" /* U+3C00 */
6374 "\xe6\x94\x80" /* U+6500 */
6375 "\xe2\xbc\x80" /* U+2F00 */
6376 "\xe3\xb8\x80"); /* U+3E00 */
6377 #endif
6378 CharData storage;
6379
6380 CharData_Init(&storage);
6381 test_data.storage = &storage;
6382 XML_SetExternalEntityRefHandler(parser, external_entity_loader2);
6383 XML_SetUserData(parser, &test_data);
6384 XML_SetCharacterDataHandler(parser, ext2_accumulate_characters);
6385 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
6386 XML_TRUE) == XML_STATUS_ERROR)
6387 xml_failure(parser);
6388 CharData_CheckXMLChars(&storage, expected);
6389 }
6390 END_TEST
6391
6392 /* Test big-endian UTF-16 given an explicit little-endian encoding */
START_TEST(test_ext_entity_utf16_le)6393 START_TEST(test_ext_entity_utf16_le)
6394 {
6395 const char *text =
6396 "<!DOCTYPE doc [\n"
6397 " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n"
6398 "]>\n"
6399 "<doc>&en;</doc>";
6400 ExtTest2 test_data = {
6401 "\0<\0e\0/\0>",
6402 8,
6403 XCS("utf-16le"),
6404 NULL,
6405 EE_PARSE_NONE
6406 };
6407 #ifdef XML_UNICODE
6408 const XML_Char *expected = XCS("\x3c00\x6500\x2f00\x3e00");
6409 #else
6410 const XML_Char *expected =
6411 XCS("\xe3\xb0\x80" /* U+3C00 */
6412 "\xe6\x94\x80" /* U+6500 */
6413 "\xe2\xbc\x80" /* U+2F00 */
6414 "\xe3\xb8\x80"); /* U+3E00 */
6415 #endif
6416 CharData storage;
6417
6418 CharData_Init(&storage);
6419 test_data.storage = &storage;
6420 XML_SetExternalEntityRefHandler(parser, external_entity_loader2);
6421 XML_SetUserData(parser, &test_data);
6422 XML_SetCharacterDataHandler(parser, ext2_accumulate_characters);
6423 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
6424 XML_TRUE) == XML_STATUS_ERROR)
6425 xml_failure(parser);
6426 CharData_CheckXMLChars(&storage, expected);
6427 }
6428 END_TEST
6429
6430 /* Test little-endian UTF-16 given no explicit encoding.
6431 * The existing default encoding (UTF-8) is assumed to hold without a
6432 * BOM to contradict it, so the entity value will in fact provoke an
6433 * error because 0x00 is not a valid XML character. We parse the
6434 * whole buffer in one go rather than feeding it in byte by byte to
6435 * exercise different code paths in the initial scanning routines.
6436 */
6437 typedef struct ExtFaults2 {
6438 const char *parse_text;
6439 int parse_len;
6440 const char *fail_text;
6441 const XML_Char *encoding;
6442 enum XML_Error error;
6443 } ExtFaults2;
6444
6445 static int XMLCALL
external_entity_faulter2(XML_Parser parser,const XML_Char * context,const XML_Char * UNUSED_P (base),const XML_Char * UNUSED_P (systemId),const XML_Char * UNUSED_P (publicId))6446 external_entity_faulter2(XML_Parser parser,
6447 const XML_Char *context,
6448 const XML_Char *UNUSED_P(base),
6449 const XML_Char *UNUSED_P(systemId),
6450 const XML_Char *UNUSED_P(publicId))
6451 {
6452 ExtFaults2 *test_data = (ExtFaults2 *)XML_GetUserData(parser);
6453 XML_Parser extparser;
6454
6455 extparser = XML_ExternalEntityParserCreate(parser, context, NULL);
6456 if (extparser == NULL)
6457 fail("Could not create external entity parser");
6458 if (test_data->encoding != NULL) {
6459 if (!XML_SetEncoding(extparser, test_data->encoding))
6460 fail("XML_SetEncoding() ignored for external entity");
6461 }
6462 if (XML_Parse(extparser,
6463 test_data->parse_text,
6464 test_data->parse_len,
6465 XML_TRUE) != XML_STATUS_ERROR)
6466 fail(test_data->fail_text);
6467 if (XML_GetErrorCode(extparser) != test_data->error)
6468 xml_failure(extparser);
6469
6470 XML_ParserFree(extparser);
6471 return XML_STATUS_ERROR;
6472 }
6473
START_TEST(test_ext_entity_utf16_unknown)6474 START_TEST(test_ext_entity_utf16_unknown)
6475 {
6476 const char *text =
6477 "<!DOCTYPE doc [\n"
6478 " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n"
6479 "]>\n"
6480 "<doc>&en;</doc>";
6481 ExtFaults2 test_data = {
6482 "a\0b\0c\0",
6483 6,
6484 "Invalid character in entity not faulted",
6485 NULL,
6486 XML_ERROR_INVALID_TOKEN
6487 };
6488
6489 XML_SetExternalEntityRefHandler(parser, external_entity_faulter2);
6490 XML_SetUserData(parser, &test_data);
6491 expect_failure(text, XML_ERROR_EXTERNAL_ENTITY_HANDLING,
6492 "Invalid character should not have been accepted");
6493 }
6494 END_TEST
6495
6496 /* Test not-quite-UTF-8 BOM (0xEF 0xBB 0xBF) */
START_TEST(test_ext_entity_utf8_non_bom)6497 START_TEST(test_ext_entity_utf8_non_bom)
6498 {
6499 const char *text =
6500 "<!DOCTYPE doc [\n"
6501 " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n"
6502 "]>\n"
6503 "<doc>&en;</doc>";
6504 ExtTest2 test_data = {
6505 "\xef\xbb\x80", /* Arabic letter DAD medial form, U+FEC0 */
6506 3,
6507 NULL,
6508 NULL,
6509 EE_PARSE_NONE
6510 };
6511 #ifdef XML_UNICODE
6512 const XML_Char *expected = XCS("\xfec0");
6513 #else
6514 const XML_Char *expected = XCS("\xef\xbb\x80");
6515 #endif
6516 CharData storage;
6517
6518 CharData_Init(&storage);
6519 test_data.storage = &storage;
6520 XML_SetExternalEntityRefHandler(parser, external_entity_loader2);
6521 XML_SetUserData(parser, &test_data);
6522 XML_SetCharacterDataHandler(parser, ext2_accumulate_characters);
6523 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
6524 XML_TRUE) == XML_STATUS_ERROR)
6525 xml_failure(parser);
6526 CharData_CheckXMLChars(&storage, expected);
6527 }
6528 END_TEST
6529
6530 /* Test that UTF-8 in a CDATA section is correctly passed through */
START_TEST(test_utf8_in_cdata_section)6531 START_TEST(test_utf8_in_cdata_section)
6532 {
6533 const char *text = "<doc><![CDATA[one \xc3\xa9 two]]></doc>";
6534 #ifdef XML_UNICODE
6535 const XML_Char *expected = XCS("one \x00e9 two");
6536 #else
6537 const XML_Char *expected = XCS("one \xc3\xa9 two");
6538 #endif
6539
6540 run_character_check(text, expected);
6541 }
6542 END_TEST
6543
6544 /* Test that little-endian UTF-16 in a CDATA section is handled */
START_TEST(test_utf8_in_cdata_section_2)6545 START_TEST(test_utf8_in_cdata_section_2)
6546 {
6547 const char *text = "<doc><![CDATA[\xc3\xa9]\xc3\xa9two]]></doc>";
6548 #ifdef XML_UNICODE
6549 const XML_Char *expected = XCS("\x00e9]\x00e9two");
6550 #else
6551 const XML_Char *expected = XCS("\xc3\xa9]\xc3\xa9two");
6552 #endif
6553
6554 run_character_check(text, expected);
6555 }
6556 END_TEST
6557
6558 /* Test trailing spaces in elements are accepted */
6559 static void XMLCALL
record_element_end_handler(void * userData,const XML_Char * name)6560 record_element_end_handler(void *userData,
6561 const XML_Char *name)
6562 {
6563 CharData *storage = (CharData *)userData;
6564
6565 CharData_AppendXMLChars(storage, XCS("/"), 1);
6566 CharData_AppendXMLChars(storage, name, -1);
6567 }
6568
START_TEST(test_trailing_spaces_in_elements)6569 START_TEST(test_trailing_spaces_in_elements)
6570 {
6571 const char *text = "<doc >Hi</doc >";
6572 const XML_Char *expected = XCS("doc/doc");
6573 CharData storage;
6574
6575 CharData_Init(&storage);
6576 XML_SetElementHandler(parser, record_element_start_handler,
6577 record_element_end_handler);
6578 XML_SetUserData(parser, &storage);
6579 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
6580 XML_TRUE) == XML_STATUS_ERROR)
6581 xml_failure(parser);
6582 CharData_CheckXMLChars(&storage, expected);
6583 }
6584 END_TEST
6585
START_TEST(test_utf16_attribute)6586 START_TEST(test_utf16_attribute)
6587 {
6588 const char text[] =
6589 /* <d {KHO KHWAI}{CHO CHAN}='a'/>
6590 * where {KHO KHWAI} = U+0E04 = 0xe0 0xb8 0x84 in UTF-8
6591 * and {CHO CHAN} = U+0E08 = 0xe0 0xb8 0x88 in UTF-8
6592 */
6593 "<\0d\0 \0\x04\x0e\x08\x0e=\0'\0a\0'\0/\0>\0";
6594 const XML_Char *expected = XCS("a");
6595 CharData storage;
6596
6597 CharData_Init(&storage);
6598 XML_SetStartElementHandler(parser, accumulate_attribute);
6599 XML_SetUserData(parser, &storage);
6600 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text)-1,
6601 XML_TRUE) == XML_STATUS_ERROR)
6602 xml_failure(parser);
6603 CharData_CheckXMLChars(&storage, expected);
6604 }
6605 END_TEST
6606
START_TEST(test_utf16_second_attr)6607 START_TEST(test_utf16_second_attr)
6608 {
6609 /* <d a='1' {KHO KHWAI}{CHO CHAN}='2'/>
6610 * where {KHO KHWAI} = U+0E04 = 0xe0 0xb8 0x84 in UTF-8
6611 * and {CHO CHAN} = U+0E08 = 0xe0 0xb8 0x88 in UTF-8
6612 */
6613 const char text[] =
6614 "<\0d\0 \0a\0=\0'\0\x31\0'\0 \0"
6615 "\x04\x0e\x08\x0e=\0'\0\x32\0'\0/\0>\0";
6616 const XML_Char *expected = XCS("1");
6617 CharData storage;
6618
6619 CharData_Init(&storage);
6620 XML_SetStartElementHandler(parser, accumulate_attribute);
6621 XML_SetUserData(parser, &storage);
6622 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text)-1,
6623 XML_TRUE) == XML_STATUS_ERROR)
6624 xml_failure(parser);
6625 CharData_CheckXMLChars(&storage, expected);
6626 }
6627 END_TEST
6628
START_TEST(test_attr_after_solidus)6629 START_TEST(test_attr_after_solidus)
6630 {
6631 const char *text = "<doc attr1='a' / attr2='b'>";
6632
6633 expect_failure(text, XML_ERROR_INVALID_TOKEN,
6634 "Misplaced / not faulted");
6635 }
6636 END_TEST
6637
6638 static void XMLCALL
accumulate_entity_decl(void * userData,const XML_Char * entityName,int UNUSED_P (is_parameter_entity),const XML_Char * value,int value_length,const XML_Char * UNUSED_P (base),const XML_Char * UNUSED_P (systemId),const XML_Char * UNUSED_P (publicId),const XML_Char * UNUSED_P (notationName))6639 accumulate_entity_decl(void *userData,
6640 const XML_Char *entityName,
6641 int UNUSED_P(is_parameter_entity),
6642 const XML_Char *value,
6643 int value_length,
6644 const XML_Char *UNUSED_P(base),
6645 const XML_Char *UNUSED_P(systemId),
6646 const XML_Char *UNUSED_P(publicId),
6647 const XML_Char *UNUSED_P(notationName))
6648 {
6649 CharData *storage = (CharData *)userData;
6650
6651 CharData_AppendXMLChars(storage, entityName, -1);
6652 CharData_AppendXMLChars(storage, XCS("="), 1);
6653 CharData_AppendXMLChars(storage, value, value_length);
6654 CharData_AppendXMLChars(storage, XCS("\n"), 1);
6655 }
6656
6657
START_TEST(test_utf16_pe)6658 START_TEST(test_utf16_pe)
6659 {
6660 /* <!DOCTYPE doc [
6661 * <!ENTITY % {KHO KHWAI}{CHO CHAN} '<!ELEMENT doc (#PCDATA)>'>
6662 * %{KHO KHWAI}{CHO CHAN};
6663 * ]>
6664 * <doc></doc>
6665 *
6666 * where {KHO KHWAI} = U+0E04 = 0xe0 0xb8 0x84 in UTF-8
6667 * and {CHO CHAN} = U+0E08 = 0xe0 0xb8 0x88 in UTF-8
6668 */
6669 const char text[] =
6670 "\0<\0!\0D\0O\0C\0T\0Y\0P\0E\0 \0d\0o\0c\0 \0[\0\n"
6671 "\0<\0!\0E\0N\0T\0I\0T\0Y\0 \0%\0 \x0e\x04\x0e\x08\0 "
6672 "\0'\0<\0!\0E\0L\0E\0M\0E\0N\0T\0 "
6673 "\0d\0o\0c\0 \0(\0#\0P\0C\0D\0A\0T\0A\0)\0>\0'\0>\0\n"
6674 "\0%\x0e\x04\x0e\x08\0;\0\n"
6675 "\0]\0>\0\n"
6676 "\0<\0d\0o\0c\0>\0<\0/\0d\0o\0c\0>";
6677 #ifdef XML_UNICODE
6678 const XML_Char *expected =
6679 XCS("\x0e04\x0e08=<!ELEMENT doc (#PCDATA)>\n");
6680 #else
6681 const XML_Char *expected =
6682 XCS("\xe0\xb8\x84\xe0\xb8\x88=<!ELEMENT doc (#PCDATA)>\n");
6683 #endif
6684 CharData storage;
6685
6686 CharData_Init(&storage);
6687 XML_SetUserData(parser, &storage);
6688 XML_SetEntityDeclHandler(parser, accumulate_entity_decl);
6689 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text)-1,
6690 XML_TRUE) == XML_STATUS_ERROR)
6691 xml_failure(parser);
6692 CharData_CheckXMLChars(&storage, expected);
6693 }
6694 END_TEST
6695
6696 /* Test that duff attribute description keywords are rejected */
START_TEST(test_bad_attr_desc_keyword)6697 START_TEST(test_bad_attr_desc_keyword)
6698 {
6699 const char *text =
6700 "<!DOCTYPE doc [\n"
6701 " <!ATTLIST doc attr CDATA #!IMPLIED>\n"
6702 "]>\n"
6703 "<doc />";
6704
6705 expect_failure(text, XML_ERROR_INVALID_TOKEN,
6706 "Bad keyword !IMPLIED not faulted");
6707 }
6708 END_TEST
6709
6710 /* Test that an invalid attribute description keyword consisting of
6711 * UTF-16 characters with their top bytes non-zero are correctly
6712 * faulted
6713 */
START_TEST(test_bad_attr_desc_keyword_utf16)6714 START_TEST(test_bad_attr_desc_keyword_utf16)
6715 {
6716 /* <!DOCTYPE d [
6717 * <!ATTLIST d a CDATA #{KHO KHWAI}{CHO CHAN}>
6718 * ]><d/>
6719 *
6720 * where {KHO KHWAI} = U+0E04 = 0xe0 0xb8 0x84 in UTF-8
6721 * and {CHO CHAN} = U+0E08 = 0xe0 0xb8 0x88 in UTF-8
6722 */
6723 const char text[] =
6724 "\0<\0!\0D\0O\0C\0T\0Y\0P\0E\0 \0d\0 \0[\0\n"
6725 "\0<\0!\0A\0T\0T\0L\0I\0S\0T\0 \0d\0 \0a\0 \0C\0D\0A\0T\0A\0 "
6726 "\0#\x0e\x04\x0e\x08\0>\0\n"
6727 "\0]\0>\0<\0d\0/\0>";
6728
6729 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text)-1,
6730 XML_TRUE) != XML_STATUS_ERROR)
6731 fail("Invalid UTF16 attribute keyword not faulted");
6732 if (XML_GetErrorCode(parser) != XML_ERROR_SYNTAX)
6733 xml_failure(parser);
6734 }
6735 END_TEST
6736
6737 /* Test that invalid syntax in a <!DOCTYPE> is rejected. Do this
6738 * using prefix-encoding (see above) to trigger specific code paths
6739 */
START_TEST(test_bad_doctype)6740 START_TEST(test_bad_doctype)
6741 {
6742 const char *text =
6743 "<?xml version='1.0' encoding='prefix-conv'?>\n"
6744 "<!DOCTYPE doc [ \x80\x44 ]><doc/>";
6745
6746 XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL);
6747 expect_failure(text, XML_ERROR_SYNTAX,
6748 "Invalid bytes in DOCTYPE not faulted");
6749 }
6750 END_TEST
6751
START_TEST(test_bad_doctype_utf16)6752 START_TEST(test_bad_doctype_utf16)
6753 {
6754 const char text[] =
6755 /* <!DOCTYPE doc [ \x06f2 ]><doc/>
6756 *
6757 * U+06F2 = EXTENDED ARABIC-INDIC DIGIT TWO, a valid number
6758 * (name character) but not a valid letter (name start character)
6759 */
6760 "\0<\0!\0D\0O\0C\0T\0Y\0P\0E\0 \0d\0o\0c\0 \0[\0 "
6761 "\x06\xf2"
6762 "\0 \0]\0>\0<\0d\0o\0c\0/\0>";
6763
6764 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text)-1,
6765 XML_TRUE) != XML_STATUS_ERROR)
6766 fail("Invalid bytes in DOCTYPE not faulted");
6767 if (XML_GetErrorCode(parser) != XML_ERROR_SYNTAX)
6768 xml_failure(parser);
6769 }
6770 END_TEST
6771
START_TEST(test_bad_doctype_plus)6772 START_TEST(test_bad_doctype_plus)
6773 {
6774 const char *text =
6775 "<!DOCTYPE 1+ [ <!ENTITY foo 'bar'> ]>\n"
6776 "<1+>&foo;</1+>";
6777
6778 expect_failure(text, XML_ERROR_INVALID_TOKEN,
6779 "'+' in document name not faulted");
6780 }
6781 END_TEST
6782
START_TEST(test_bad_doctype_star)6783 START_TEST(test_bad_doctype_star)
6784 {
6785 const char *text =
6786 "<!DOCTYPE 1* [ <!ENTITY foo 'bar'> ]>\n"
6787 "<1*>&foo;</1*>";
6788
6789 expect_failure(text, XML_ERROR_INVALID_TOKEN,
6790 "'*' in document name not faulted");
6791 }
6792 END_TEST
6793
START_TEST(test_bad_doctype_query)6794 START_TEST(test_bad_doctype_query)
6795 {
6796 const char *text =
6797 "<!DOCTYPE 1? [ <!ENTITY foo 'bar'> ]>\n"
6798 "<1?>&foo;</1?>";
6799
6800 expect_failure(text, XML_ERROR_INVALID_TOKEN,
6801 "'?' in document name not faulted");
6802 }
6803 END_TEST
6804
START_TEST(test_unknown_encoding_bad_ignore)6805 START_TEST(test_unknown_encoding_bad_ignore)
6806 {
6807 const char *text =
6808 "<?xml version='1.0' encoding='prefix-conv'?>"
6809 "<!DOCTYPE doc SYSTEM 'foo'>"
6810 "<doc><e>&entity;</e></doc>";
6811 ExtFaults fault = {
6812 "<![IGNORE[<!ELEMENT \xffG (#PCDATA)*>]]>",
6813 "Invalid character not faulted",
6814 XCS("prefix-conv"),
6815 XML_ERROR_INVALID_TOKEN
6816 };
6817
6818 XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL);
6819 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
6820 XML_SetExternalEntityRefHandler(parser, external_entity_faulter);
6821 XML_SetUserData(parser, &fault);
6822 expect_failure(text, XML_ERROR_EXTERNAL_ENTITY_HANDLING,
6823 "Bad IGNORE section with unknown encoding not failed");
6824 }
6825 END_TEST
6826
START_TEST(test_entity_in_utf16_be_attr)6827 START_TEST(test_entity_in_utf16_be_attr)
6828 {
6829 const char text[] =
6830 /* <e a='ä ä'></e> */
6831 "\0<\0e\0 \0a\0=\0'\0&\0#\0\x32\0\x32\0\x38\0;\0 "
6832 "\0&\0#\0x\0\x30\0\x30\0E\0\x34\0;\0'\0>\0<\0/\0e\0>";
6833 #ifdef XML_UNICODE
6834 const XML_Char *expected = XCS("\x00e4 \x00e4");
6835 #else
6836 const XML_Char *expected = XCS("\xc3\xa4 \xc3\xa4");
6837 #endif
6838 CharData storage;
6839
6840 CharData_Init(&storage);
6841 XML_SetUserData(parser, &storage);
6842 XML_SetStartElementHandler(parser, accumulate_attribute);
6843 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text)-1,
6844 XML_TRUE) == XML_STATUS_ERROR)
6845 xml_failure(parser);
6846 CharData_CheckXMLChars(&storage, expected);
6847 }
6848 END_TEST
6849
START_TEST(test_entity_in_utf16_le_attr)6850 START_TEST(test_entity_in_utf16_le_attr)
6851 {
6852 const char text[] =
6853 /* <e a='ä ä'></e> */
6854 "<\0e\0 \0a\0=\0'\0&\0#\0\x32\0\x32\0\x38\0;\0 \0"
6855 "&\0#\0x\0\x30\0\x30\0E\0\x34\0;\0'\0>\0<\0/\0e\0>\0";
6856 #ifdef XML_UNICODE
6857 const XML_Char *expected = XCS("\x00e4 \x00e4");
6858 #else
6859 const XML_Char *expected = XCS("\xc3\xa4 \xc3\xa4");
6860 #endif
6861 CharData storage;
6862
6863 CharData_Init(&storage);
6864 XML_SetUserData(parser, &storage);
6865 XML_SetStartElementHandler(parser, accumulate_attribute);
6866 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text)-1,
6867 XML_TRUE) == XML_STATUS_ERROR)
6868 xml_failure(parser);
6869 CharData_CheckXMLChars(&storage, expected);
6870 }
6871 END_TEST
6872
START_TEST(test_entity_public_utf16_be)6873 START_TEST(test_entity_public_utf16_be)
6874 {
6875 const char text[] =
6876 /* <!DOCTYPE d [ */
6877 "\0<\0!\0D\0O\0C\0T\0Y\0P\0E\0 \0d\0 \0[\0\n"
6878 /* <!ENTITY % e PUBLIC 'foo' 'bar.ent'> */
6879 "\0<\0!\0E\0N\0T\0I\0T\0Y\0 \0%\0 \0e\0 \0P\0U\0B\0L\0I\0C\0 "
6880 "\0'\0f\0o\0o\0'\0 \0'\0b\0a\0r\0.\0e\0n\0t\0'\0>\0\n"
6881 /* %e; */
6882 "\0%\0e\0;\0\n"
6883 /* ]> */
6884 "\0]\0>\0\n"
6885 /* <d>&j;</d> */
6886 "\0<\0d\0>\0&\0j\0;\0<\0/\0d\0>";
6887 ExtTest2 test_data = {
6888 /* <!ENTITY j 'baz'> */
6889 "\0<\0!\0E\0N\0T\0I\0T\0Y\0 \0j\0 \0'\0b\0a\0z\0'\0>",
6890 34,
6891 NULL,
6892 NULL,
6893 EE_PARSE_NONE
6894 };
6895 const XML_Char *expected = XCS("baz");
6896 CharData storage;
6897
6898 CharData_Init(&storage);
6899 test_data.storage = &storage;
6900 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
6901 XML_SetExternalEntityRefHandler(parser, external_entity_loader2);
6902 XML_SetUserData(parser, &test_data);
6903 XML_SetCharacterDataHandler(parser, ext2_accumulate_characters);
6904 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text)-1,
6905 XML_TRUE) == XML_STATUS_ERROR)
6906 xml_failure(parser);
6907 CharData_CheckXMLChars(&storage, expected);
6908 }
6909 END_TEST
6910
START_TEST(test_entity_public_utf16_le)6911 START_TEST(test_entity_public_utf16_le)
6912 {
6913 const char text[] =
6914 /* <!DOCTYPE d [ */
6915 "<\0!\0D\0O\0C\0T\0Y\0P\0E\0 \0d\0 \0[\0\n\0"
6916 /* <!ENTITY % e PUBLIC 'foo' 'bar.ent'> */
6917 "<\0!\0E\0N\0T\0I\0T\0Y\0 \0%\0 \0e\0 \0P\0U\0B\0L\0I\0C\0 \0"
6918 "'\0f\0o\0o\0'\0 \0'\0b\0a\0r\0.\0e\0n\0t\0'\0>\0\n\0"
6919 /* %e; */
6920 "%\0e\0;\0\n\0"
6921 /* ]> */
6922 "]\0>\0\n\0"
6923 /* <d>&j;</d> */
6924 "<\0d\0>\0&\0j\0;\0<\0/\0d\0>\0";
6925 ExtTest2 test_data = {
6926 /* <!ENTITY j 'baz'> */
6927 "<\0!\0E\0N\0T\0I\0T\0Y\0 \0j\0 \0'\0b\0a\0z\0'\0>\0",
6928 34,
6929 NULL,
6930 NULL,
6931 EE_PARSE_NONE
6932 };
6933 const XML_Char *expected = XCS("baz");
6934 CharData storage;
6935
6936 CharData_Init(&storage);
6937 test_data.storage = &storage;
6938 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
6939 XML_SetExternalEntityRefHandler(parser, external_entity_loader2);
6940 XML_SetUserData(parser, &test_data);
6941 XML_SetCharacterDataHandler(parser, ext2_accumulate_characters);
6942 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text)-1,
6943 XML_TRUE) == XML_STATUS_ERROR)
6944 xml_failure(parser);
6945 CharData_CheckXMLChars(&storage, expected);
6946 }
6947 END_TEST
6948
6949 /* Test that a doctype with neither an internal nor external subset is
6950 * faulted
6951 */
START_TEST(test_short_doctype)6952 START_TEST(test_short_doctype)
6953 {
6954 const char *text = "<!DOCTYPE doc></doc>";
6955 expect_failure(text, XML_ERROR_INVALID_TOKEN,
6956 "DOCTYPE without subset not rejected");
6957 }
6958 END_TEST
6959
START_TEST(test_short_doctype_2)6960 START_TEST(test_short_doctype_2)
6961 {
6962 const char *text = "<!DOCTYPE doc PUBLIC></doc>";
6963 expect_failure(text, XML_ERROR_SYNTAX,
6964 "DOCTYPE without Public ID not rejected");
6965 }
6966 END_TEST
6967
START_TEST(test_short_doctype_3)6968 START_TEST(test_short_doctype_3)
6969 {
6970 const char *text = "<!DOCTYPE doc SYSTEM></doc>";
6971 expect_failure(text, XML_ERROR_SYNTAX,
6972 "DOCTYPE without System ID not rejected");
6973 }
6974 END_TEST
6975
START_TEST(test_long_doctype)6976 START_TEST(test_long_doctype)
6977 {
6978 const char *text = "<!DOCTYPE doc PUBLIC 'foo' 'bar' 'baz'></doc>";
6979 expect_failure(text, XML_ERROR_SYNTAX,
6980 "DOCTYPE with extra ID not rejected");
6981 }
6982 END_TEST
6983
START_TEST(test_bad_entity)6984 START_TEST(test_bad_entity)
6985 {
6986 const char *text =
6987 "<!DOCTYPE doc [\n"
6988 " <!ENTITY foo PUBLIC>\n"
6989 "]>\n"
6990 "<doc/>";
6991 expect_failure(text, XML_ERROR_SYNTAX,
6992 "ENTITY without Public ID is not rejected");
6993 }
6994 END_TEST
6995
6996 /* Test unquoted value is faulted */
START_TEST(test_bad_entity_2)6997 START_TEST(test_bad_entity_2)
6998 {
6999 const char *text =
7000 "<!DOCTYPE doc [\n"
7001 " <!ENTITY % foo bar>\n"
7002 "]>\n"
7003 "<doc/>";
7004 expect_failure(text, XML_ERROR_SYNTAX,
7005 "ENTITY without Public ID is not rejected");
7006 }
7007 END_TEST
7008
START_TEST(test_bad_entity_3)7009 START_TEST(test_bad_entity_3)
7010 {
7011 const char *text =
7012 "<!DOCTYPE doc [\n"
7013 " <!ENTITY % foo PUBLIC>\n"
7014 "]>\n"
7015 "<doc/>";
7016 expect_failure(text, XML_ERROR_SYNTAX,
7017 "Parameter ENTITY without Public ID is not rejected");
7018 }
7019 END_TEST
7020
START_TEST(test_bad_entity_4)7021 START_TEST(test_bad_entity_4)
7022 {
7023 const char *text =
7024 "<!DOCTYPE doc [\n"
7025 " <!ENTITY % foo SYSTEM>\n"
7026 "]>\n"
7027 "<doc/>";
7028 expect_failure(text, XML_ERROR_SYNTAX,
7029 "Parameter ENTITY without Public ID is not rejected");
7030 }
7031 END_TEST
7032
START_TEST(test_bad_notation)7033 START_TEST(test_bad_notation)
7034 {
7035 const char *text =
7036 "<!DOCTYPE doc [\n"
7037 " <!NOTATION n SYSTEM>\n"
7038 "]>\n"
7039 "<doc/>";
7040 expect_failure(text, XML_ERROR_SYNTAX,
7041 "Notation without System ID is not rejected");
7042 }
7043 END_TEST
7044
7045 /* Test for issue #11, wrongly suppressed default handler */
7046 typedef struct default_check {
7047 const XML_Char *expected;
7048 const int expectedLen;
7049 XML_Bool seen;
7050 } DefaultCheck;
7051
7052 static void XMLCALL
checking_default_handler(void * userData,const XML_Char * s,int len)7053 checking_default_handler(void *userData,
7054 const XML_Char *s,
7055 int len)
7056 {
7057 DefaultCheck *data = (DefaultCheck *)userData;
7058 int i;
7059
7060 for (i = 0; data[i].expected != NULL; i++) {
7061 if (data[i].expectedLen == len &&
7062 !memcmp(data[i].expected, s, len * sizeof(XML_Char))) {
7063 data[i].seen = XML_TRUE;
7064 break;
7065 }
7066 }
7067 }
7068
START_TEST(test_default_doctype_handler)7069 START_TEST(test_default_doctype_handler)
7070 {
7071 const char *text =
7072 "<!DOCTYPE doc PUBLIC 'pubname' 'test.dtd' [\n"
7073 " <!ENTITY foo 'bar'>\n"
7074 "]>\n"
7075 "<doc>&foo;</doc>";
7076 DefaultCheck test_data[] = {
7077 {
7078 XCS("'pubname'"),
7079 9,
7080 XML_FALSE
7081 },
7082 {
7083 XCS("'test.dtd'"),
7084 10,
7085 XML_FALSE
7086 },
7087 { NULL, 0, XML_FALSE }
7088 };
7089 int i;
7090
7091 XML_SetUserData(parser, &test_data);
7092 XML_SetDefaultHandler(parser, checking_default_handler);
7093 XML_SetEntityDeclHandler(parser, dummy_entity_decl_handler);
7094 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
7095 XML_TRUE) == XML_STATUS_ERROR)
7096 xml_failure(parser);
7097 for (i = 0; test_data[i].expected != NULL; i++)
7098 if (!test_data[i].seen)
7099 fail("Default handler not run for public !DOCTYPE");
7100 }
7101 END_TEST
7102
START_TEST(test_empty_element_abort)7103 START_TEST(test_empty_element_abort)
7104 {
7105 const char *text = "<abort/>";
7106
7107 XML_SetStartElementHandler(parser, start_element_suspender);
7108 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
7109 XML_TRUE) != XML_STATUS_ERROR)
7110 fail("Expected to error on abort");
7111 }
7112 END_TEST
7113
7114 /*
7115 * Namespaces tests.
7116 */
7117
7118 static void
namespace_setup(void)7119 namespace_setup(void)
7120 {
7121 parser = XML_ParserCreateNS(NULL, XCS(' '));
7122 if (parser == NULL)
7123 fail("Parser not created.");
7124 }
7125
7126 static void
namespace_teardown(void)7127 namespace_teardown(void)
7128 {
7129 basic_teardown();
7130 }
7131
7132 /* Check that an element name and attribute name match the expected values.
7133 The expected values are passed as an array reference of string pointers
7134 provided as the userData argument; the first is the expected
7135 element name, and the second is the expected attribute name.
7136 */
7137 static int triplet_start_flag = XML_FALSE;
7138 static int triplet_end_flag = XML_FALSE;
7139
7140 static void XMLCALL
triplet_start_checker(void * userData,const XML_Char * name,const XML_Char ** atts)7141 triplet_start_checker(void *userData, const XML_Char *name,
7142 const XML_Char **atts)
7143 {
7144 XML_Char **elemstr = (XML_Char **)userData;
7145 char buffer[1024];
7146 if (xcstrcmp(elemstr[0], name) != 0) {
7147 sprintf(buffer, "unexpected start string: '%" XML_FMT_STR "'", name);
7148 fail(buffer);
7149 }
7150 if (xcstrcmp(elemstr[1], atts[0]) != 0) {
7151 sprintf(buffer, "unexpected attribute string: '%" XML_FMT_STR "'",
7152 atts[0]);
7153 fail(buffer);
7154 }
7155 triplet_start_flag = XML_TRUE;
7156 }
7157
7158 /* Check that the element name passed to the end-element handler matches
7159 the expected value. The expected value is passed as the first element
7160 in an array of strings passed as the userData argument.
7161 */
7162 static void XMLCALL
triplet_end_checker(void * userData,const XML_Char * name)7163 triplet_end_checker(void *userData, const XML_Char *name)
7164 {
7165 XML_Char **elemstr = (XML_Char **)userData;
7166 if (xcstrcmp(elemstr[0], name) != 0) {
7167 char buffer[1024];
7168 sprintf(buffer, "unexpected end string: '%" XML_FMT_STR "'", name);
7169 fail(buffer);
7170 }
7171 triplet_end_flag = XML_TRUE;
7172 }
7173
START_TEST(test_return_ns_triplet)7174 START_TEST(test_return_ns_triplet)
7175 {
7176 const char *text =
7177 "<foo:e xmlns:foo='http://example.org/' bar:a='12'\n"
7178 " xmlns:bar='http://example.org/'>";
7179 const char *epilog = "</foo:e>";
7180 const XML_Char *elemstr[] = {
7181 XCS("http://example.org/ e foo"),
7182 XCS("http://example.org/ a bar")
7183 };
7184 XML_SetReturnNSTriplet(parser, XML_TRUE);
7185 XML_SetUserData(parser, (void *)elemstr);
7186 XML_SetElementHandler(parser, triplet_start_checker,
7187 triplet_end_checker);
7188 XML_SetNamespaceDeclHandler(parser,
7189 dummy_start_namespace_decl_handler,
7190 dummy_end_namespace_decl_handler);
7191 triplet_start_flag = XML_FALSE;
7192 triplet_end_flag = XML_FALSE;
7193 dummy_handler_flags = 0;
7194 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
7195 XML_FALSE) == XML_STATUS_ERROR)
7196 xml_failure(parser);
7197 if (!triplet_start_flag)
7198 fail("triplet_start_checker not invoked");
7199 /* Check that unsetting "return triplets" fails while still parsing */
7200 XML_SetReturnNSTriplet(parser, XML_FALSE);
7201 if (_XML_Parse_SINGLE_BYTES(parser, epilog, (int)strlen(epilog),
7202 XML_TRUE) == XML_STATUS_ERROR)
7203 xml_failure(parser);
7204 if (!triplet_end_flag)
7205 fail("triplet_end_checker not invoked");
7206 if (dummy_handler_flags != (DUMMY_START_NS_DECL_HANDLER_FLAG |
7207 DUMMY_END_NS_DECL_HANDLER_FLAG))
7208 fail("Namespace handlers not called");
7209 }
7210 END_TEST
7211
7212 static void XMLCALL
overwrite_start_checker(void * userData,const XML_Char * name,const XML_Char ** atts)7213 overwrite_start_checker(void *userData, const XML_Char *name,
7214 const XML_Char **atts)
7215 {
7216 CharData *storage = (CharData *) userData;
7217 CharData_AppendXMLChars(storage, XCS("start "), 6);
7218 CharData_AppendXMLChars(storage, name, -1);
7219 while (*atts != NULL) {
7220 CharData_AppendXMLChars(storage, XCS("\nattribute "), 11);
7221 CharData_AppendXMLChars(storage, *atts, -1);
7222 atts += 2;
7223 }
7224 CharData_AppendXMLChars(storage, XCS("\n"), 1);
7225 }
7226
7227 static void XMLCALL
overwrite_end_checker(void * userData,const XML_Char * name)7228 overwrite_end_checker(void *userData, const XML_Char *name)
7229 {
7230 CharData *storage = (CharData *) userData;
7231 CharData_AppendXMLChars(storage, XCS("end "), 4);
7232 CharData_AppendXMLChars(storage, name, -1);
7233 CharData_AppendXMLChars(storage, XCS("\n"), 1);
7234 }
7235
7236 static void
run_ns_tagname_overwrite_test(const char * text,const XML_Char * result)7237 run_ns_tagname_overwrite_test(const char *text, const XML_Char *result)
7238 {
7239 CharData storage;
7240 CharData_Init(&storage);
7241 XML_SetUserData(parser, &storage);
7242 XML_SetElementHandler(parser,
7243 overwrite_start_checker, overwrite_end_checker);
7244 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR)
7245 xml_failure(parser);
7246 CharData_CheckXMLChars(&storage, result);
7247 }
7248
7249 /* Regression test for SF bug #566334. */
START_TEST(test_ns_tagname_overwrite)7250 START_TEST(test_ns_tagname_overwrite)
7251 {
7252 const char *text =
7253 "<n:e xmlns:n='http://example.org/'>\n"
7254 " <n:f n:attr='foo'/>\n"
7255 " <n:g n:attr2='bar'/>\n"
7256 "</n:e>";
7257 const XML_Char *result =
7258 XCS("start http://example.org/ e\n")
7259 XCS("start http://example.org/ f\n")
7260 XCS("attribute http://example.org/ attr\n")
7261 XCS("end http://example.org/ f\n")
7262 XCS("start http://example.org/ g\n")
7263 XCS("attribute http://example.org/ attr2\n")
7264 XCS("end http://example.org/ g\n")
7265 XCS("end http://example.org/ e\n");
7266 run_ns_tagname_overwrite_test(text, result);
7267 }
7268 END_TEST
7269
7270 /* Regression test for SF bug #566334. */
START_TEST(test_ns_tagname_overwrite_triplet)7271 START_TEST(test_ns_tagname_overwrite_triplet)
7272 {
7273 const char *text =
7274 "<n:e xmlns:n='http://example.org/'>\n"
7275 " <n:f n:attr='foo'/>\n"
7276 " <n:g n:attr2='bar'/>\n"
7277 "</n:e>";
7278 const XML_Char *result =
7279 XCS("start http://example.org/ e n\n")
7280 XCS("start http://example.org/ f n\n")
7281 XCS("attribute http://example.org/ attr n\n")
7282 XCS("end http://example.org/ f n\n")
7283 XCS("start http://example.org/ g n\n")
7284 XCS("attribute http://example.org/ attr2 n\n")
7285 XCS("end http://example.org/ g n\n")
7286 XCS("end http://example.org/ e n\n");
7287 XML_SetReturnNSTriplet(parser, XML_TRUE);
7288 run_ns_tagname_overwrite_test(text, result);
7289 }
7290 END_TEST
7291
7292
7293 /* Regression test for SF bug #620343. */
7294 static void XMLCALL
start_element_fail(void * UNUSED_P (userData),const XML_Char * UNUSED_P (name),const XML_Char ** UNUSED_P (atts))7295 start_element_fail(void *UNUSED_P(userData),
7296 const XML_Char *UNUSED_P(name), const XML_Char **UNUSED_P(atts))
7297 {
7298 /* We should never get here. */
7299 fail("should never reach start_element_fail()");
7300 }
7301
7302 static void XMLCALL
start_ns_clearing_start_element(void * userData,const XML_Char * UNUSED_P (prefix),const XML_Char * UNUSED_P (uri))7303 start_ns_clearing_start_element(void *userData,
7304 const XML_Char *UNUSED_P(prefix),
7305 const XML_Char *UNUSED_P(uri))
7306 {
7307 XML_SetStartElementHandler((XML_Parser) userData, NULL);
7308 }
7309
START_TEST(test_start_ns_clears_start_element)7310 START_TEST(test_start_ns_clears_start_element)
7311 {
7312 /* This needs to use separate start/end tags; using the empty tag
7313 syntax doesn't cause the problematic path through Expat to be
7314 taken.
7315 */
7316 const char *text = "<e xmlns='http://example.org/'></e>";
7317
7318 XML_SetStartElementHandler(parser, start_element_fail);
7319 XML_SetStartNamespaceDeclHandler(parser, start_ns_clearing_start_element);
7320 XML_SetEndNamespaceDeclHandler(parser, dummy_end_namespace_decl_handler);
7321 XML_UseParserAsHandlerArg(parser);
7322 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR)
7323 xml_failure(parser);
7324 }
7325 END_TEST
7326
7327 /* Regression test for SF bug #616863. */
7328 static int XMLCALL
external_entity_handler(XML_Parser parser,const XML_Char * context,const XML_Char * UNUSED_P (base),const XML_Char * UNUSED_P (systemId),const XML_Char * UNUSED_P (publicId))7329 external_entity_handler(XML_Parser parser,
7330 const XML_Char *context,
7331 const XML_Char *UNUSED_P(base),
7332 const XML_Char *UNUSED_P(systemId),
7333 const XML_Char *UNUSED_P(publicId))
7334 {
7335 intptr_t callno = 1 + (intptr_t)XML_GetUserData(parser);
7336 const char *text;
7337 XML_Parser p2;
7338
7339 if (callno == 1)
7340 text = ("<!ELEMENT doc (e+)>\n"
7341 "<!ATTLIST doc xmlns CDATA #IMPLIED>\n"
7342 "<!ELEMENT e EMPTY>\n");
7343 else
7344 text = ("<?xml version='1.0' encoding='us-ascii'?>"
7345 "<e/>");
7346
7347 XML_SetUserData(parser, (void *) callno);
7348 p2 = XML_ExternalEntityParserCreate(parser, context, NULL);
7349 if (_XML_Parse_SINGLE_BYTES(p2, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR) {
7350 xml_failure(p2);
7351 return XML_STATUS_ERROR;
7352 }
7353 XML_ParserFree(p2);
7354 return XML_STATUS_OK;
7355 }
7356
START_TEST(test_default_ns_from_ext_subset_and_ext_ge)7357 START_TEST(test_default_ns_from_ext_subset_and_ext_ge)
7358 {
7359 const char *text =
7360 "<?xml version='1.0'?>\n"
7361 "<!DOCTYPE doc SYSTEM 'http://example.org/doc.dtd' [\n"
7362 " <!ENTITY en SYSTEM 'http://example.org/entity.ent'>\n"
7363 "]>\n"
7364 "<doc xmlns='http://example.org/ns1'>\n"
7365 "&en;\n"
7366 "</doc>";
7367
7368 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
7369 XML_SetExternalEntityRefHandler(parser, external_entity_handler);
7370 /* We actually need to set this handler to tickle this bug. */
7371 XML_SetStartElementHandler(parser, dummy_start_element);
7372 XML_SetUserData(parser, NULL);
7373 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR)
7374 xml_failure(parser);
7375 }
7376 END_TEST
7377
7378 /* Regression test #1 for SF bug #673791. */
START_TEST(test_ns_prefix_with_empty_uri_1)7379 START_TEST(test_ns_prefix_with_empty_uri_1)
7380 {
7381 const char *text =
7382 "<doc xmlns:prefix='http://example.org/'>\n"
7383 " <e xmlns:prefix=''/>\n"
7384 "</doc>";
7385
7386 expect_failure(text,
7387 XML_ERROR_UNDECLARING_PREFIX,
7388 "Did not report re-setting namespace"
7389 " URI with prefix to ''.");
7390 }
7391 END_TEST
7392
7393 /* Regression test #2 for SF bug #673791. */
START_TEST(test_ns_prefix_with_empty_uri_2)7394 START_TEST(test_ns_prefix_with_empty_uri_2)
7395 {
7396 const char *text =
7397 "<?xml version='1.0'?>\n"
7398 "<docelem xmlns:pre=''/>";
7399
7400 expect_failure(text,
7401 XML_ERROR_UNDECLARING_PREFIX,
7402 "Did not report setting namespace URI with prefix to ''.");
7403 }
7404 END_TEST
7405
7406 /* Regression test #3 for SF bug #673791. */
START_TEST(test_ns_prefix_with_empty_uri_3)7407 START_TEST(test_ns_prefix_with_empty_uri_3)
7408 {
7409 const char *text =
7410 "<!DOCTYPE doc [\n"
7411 " <!ELEMENT doc EMPTY>\n"
7412 " <!ATTLIST doc\n"
7413 " xmlns:prefix CDATA ''>\n"
7414 "]>\n"
7415 "<doc/>";
7416
7417 expect_failure(text,
7418 XML_ERROR_UNDECLARING_PREFIX,
7419 "Didn't report attr default setting NS w/ prefix to ''.");
7420 }
7421 END_TEST
7422
7423 /* Regression test #4 for SF bug #673791. */
START_TEST(test_ns_prefix_with_empty_uri_4)7424 START_TEST(test_ns_prefix_with_empty_uri_4)
7425 {
7426 const char *text =
7427 "<!DOCTYPE doc [\n"
7428 " <!ELEMENT prefix:doc EMPTY>\n"
7429 " <!ATTLIST prefix:doc\n"
7430 " xmlns:prefix CDATA 'http://example.org/'>\n"
7431 "]>\n"
7432 "<prefix:doc/>";
7433 /* Packaged info expected by the end element handler;
7434 the weird structuring lets us re-use the triplet_end_checker()
7435 function also used for another test. */
7436 const XML_Char *elemstr[] = {
7437 XCS("http://example.org/ doc prefix")
7438 };
7439 XML_SetReturnNSTriplet(parser, XML_TRUE);
7440 XML_SetUserData(parser, (void *)elemstr);
7441 XML_SetEndElementHandler(parser, triplet_end_checker);
7442 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR)
7443 xml_failure(parser);
7444 }
7445 END_TEST
7446
7447 /* Test with non-xmlns prefix */
START_TEST(test_ns_unbound_prefix)7448 START_TEST(test_ns_unbound_prefix)
7449 {
7450 const char *text =
7451 "<!DOCTYPE doc [\n"
7452 " <!ELEMENT prefix:doc EMPTY>\n"
7453 " <!ATTLIST prefix:doc\n"
7454 " notxmlns:prefix CDATA 'http://example.org/'>\n"
7455 "]>\n"
7456 "<prefix:doc/>";
7457
7458 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
7459 XML_TRUE) != XML_STATUS_ERROR)
7460 fail("Unbound prefix incorrectly passed");
7461 if (XML_GetErrorCode(parser) != XML_ERROR_UNBOUND_PREFIX)
7462 xml_failure(parser);
7463 }
7464 END_TEST
7465
START_TEST(test_ns_default_with_empty_uri)7466 START_TEST(test_ns_default_with_empty_uri)
7467 {
7468 const char *text =
7469 "<doc xmlns='http://example.org/'>\n"
7470 " <e xmlns=''/>\n"
7471 "</doc>";
7472 /* Add some handlers to exercise extra code paths */
7473 XML_SetStartNamespaceDeclHandler(parser,
7474 dummy_start_namespace_decl_handler);
7475 XML_SetEndNamespaceDeclHandler(parser,
7476 dummy_end_namespace_decl_handler);
7477 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR)
7478 xml_failure(parser);
7479 }
7480 END_TEST
7481
7482 /* Regression test for SF bug #692964: two prefixes for one namespace. */
START_TEST(test_ns_duplicate_attrs_diff_prefixes)7483 START_TEST(test_ns_duplicate_attrs_diff_prefixes)
7484 {
7485 const char *text =
7486 "<doc xmlns:a='http://example.org/a'\n"
7487 " xmlns:b='http://example.org/a'\n"
7488 " a:a='v' b:a='v' />";
7489 expect_failure(text,
7490 XML_ERROR_DUPLICATE_ATTRIBUTE,
7491 "did not report multiple attributes with same URI+name");
7492 }
7493 END_TEST
7494
START_TEST(test_ns_duplicate_hashes)7495 START_TEST(test_ns_duplicate_hashes)
7496 {
7497 /* The hash of an attribute is calculated as the hash of its URI
7498 * concatenated with a space followed by its name (after the
7499 * colon). We wish to generate attributes with the same hash
7500 * value modulo the attribute table size so that we can check that
7501 * the attribute hash table works correctly. The attribute hash
7502 * table size will be the smallest power of two greater than the
7503 * number of attributes, but at least eight. There is
7504 * unfortunately no programmatic way of getting the hash or the
7505 * table size at user level, but the test code coverage percentage
7506 * will drop if the hashes cease to point to the same row.
7507 *
7508 * The cunning plan is to have few enough attributes to have a
7509 * reliable table size of 8, and have the single letter attribute
7510 * names be 8 characters apart, producing a hash which will be the
7511 * same modulo 8.
7512 */
7513 const char *text =
7514 "<doc xmlns:a='http://example.org/a'\n"
7515 " a:a='v' a:i='w' />";
7516 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
7517 XML_TRUE) == XML_STATUS_ERROR)
7518 xml_failure(parser);
7519 }
7520 END_TEST
7521
7522 /* Regression test for SF bug #695401: unbound prefix. */
START_TEST(test_ns_unbound_prefix_on_attribute)7523 START_TEST(test_ns_unbound_prefix_on_attribute)
7524 {
7525 const char *text = "<doc a:attr=''/>";
7526 expect_failure(text,
7527 XML_ERROR_UNBOUND_PREFIX,
7528 "did not report unbound prefix on attribute");
7529 }
7530 END_TEST
7531
7532 /* Regression test for SF bug #695401: unbound prefix. */
START_TEST(test_ns_unbound_prefix_on_element)7533 START_TEST(test_ns_unbound_prefix_on_element)
7534 {
7535 const char *text = "<a:doc/>";
7536 expect_failure(text,
7537 XML_ERROR_UNBOUND_PREFIX,
7538 "did not report unbound prefix on element");
7539 }
7540 END_TEST
7541
7542 /* Test that the parsing status is correctly reset by XML_ParserReset().
7543 * We usE test_return_ns_triplet() for our example parse to improve
7544 * coverage of tidying up code executed.
7545 */
START_TEST(test_ns_parser_reset)7546 START_TEST(test_ns_parser_reset)
7547 {
7548 XML_ParsingStatus status;
7549
7550 XML_GetParsingStatus(parser, &status);
7551 if (status.parsing != XML_INITIALIZED)
7552 fail("parsing status doesn't start INITIALIZED");
7553 test_return_ns_triplet();
7554 XML_GetParsingStatus(parser, &status);
7555 if (status.parsing != XML_FINISHED)
7556 fail("parsing status doesn't end FINISHED");
7557 XML_ParserReset(parser, NULL);
7558 XML_GetParsingStatus(parser, &status);
7559 if (status.parsing != XML_INITIALIZED)
7560 fail("parsing status doesn't reset to INITIALIZED");
7561 }
7562 END_TEST
7563
7564 /* Test that long element names with namespaces are handled correctly */
START_TEST(test_ns_long_element)7565 START_TEST(test_ns_long_element)
7566 {
7567 const char *text =
7568 "<foo:thisisalongenoughelementnametotriggerareallocation\n"
7569 " xmlns:foo='http://example.org/' bar:a='12'\n"
7570 " xmlns:bar='http://example.org/'>"
7571 "</foo:thisisalongenoughelementnametotriggerareallocation>";
7572 const XML_Char *elemstr[] = {
7573 XCS("http://example.org/")
7574 XCS(" thisisalongenoughelementnametotriggerareallocation foo"),
7575 XCS("http://example.org/ a bar")
7576 };
7577
7578 XML_SetReturnNSTriplet(parser, XML_TRUE);
7579 XML_SetUserData(parser, (void *)elemstr);
7580 XML_SetElementHandler(parser,
7581 triplet_start_checker,
7582 triplet_end_checker);
7583 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
7584 XML_TRUE) == XML_STATUS_ERROR)
7585 xml_failure(parser);
7586 }
7587 END_TEST
7588
7589 /* Test mixed population of prefixed and unprefixed attributes */
START_TEST(test_ns_mixed_prefix_atts)7590 START_TEST(test_ns_mixed_prefix_atts)
7591 {
7592 const char *text =
7593 "<e a='12' bar:b='13'\n"
7594 " xmlns:bar='http://example.org/'>"
7595 "</e>";
7596
7597 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
7598 XML_TRUE) == XML_STATUS_ERROR)
7599 xml_failure(parser);
7600 }
7601 END_TEST
7602
7603 /* Test having a long namespaced element name inside a short one.
7604 * This exercises some internal buffer reallocation that is shared
7605 * across elements with the same namespace URI.
7606 */
START_TEST(test_ns_extend_uri_buffer)7607 START_TEST(test_ns_extend_uri_buffer)
7608 {
7609 const char *text =
7610 "<foo:e xmlns:foo='http://example.org/'>"
7611 " <foo:thisisalongenoughnametotriggerallocationaction"
7612 " foo:a='12' />"
7613 "</foo:e>";
7614 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
7615 XML_TRUE) == XML_STATUS_ERROR)
7616 xml_failure(parser);
7617 }
7618 END_TEST
7619
7620 /* Test that xmlns is correctly rejected as an attribute in the xmlns
7621 * namespace, but not in other namespaces
7622 */
START_TEST(test_ns_reserved_attributes)7623 START_TEST(test_ns_reserved_attributes)
7624 {
7625 const char *text1 =
7626 "<foo:e xmlns:foo='http://example.org/' xmlns:xmlns='12' />";
7627 const char *text2 =
7628 "<foo:e xmlns:foo='http://example.org/' foo:xmlns='12' />";
7629 expect_failure(text1, XML_ERROR_RESERVED_PREFIX_XMLNS,
7630 "xmlns not rejected as an attribute");
7631 XML_ParserReset(parser, NULL);
7632 if (_XML_Parse_SINGLE_BYTES(parser, text2, (int)strlen(text2),
7633 XML_TRUE) == XML_STATUS_ERROR)
7634 xml_failure(parser);
7635 }
7636 END_TEST
7637
7638 /* Test more reserved attributes */
START_TEST(test_ns_reserved_attributes_2)7639 START_TEST(test_ns_reserved_attributes_2)
7640 {
7641 const char *text1 =
7642 "<foo:e xmlns:foo='http://example.org/'"
7643 " xmlns:xml='http://example.org/' />";
7644 const char *text2 =
7645 "<foo:e xmlns:foo='http://www.w3.org/XML/1998/namespace' />";
7646 const char *text3 =
7647 "<foo:e xmlns:foo='http://www.w3.org/2000/xmlns/' />";
7648
7649 expect_failure(text1, XML_ERROR_RESERVED_PREFIX_XML,
7650 "xml not rejected as an attribute");
7651 XML_ParserReset(parser, NULL);
7652 expect_failure(text2, XML_ERROR_RESERVED_NAMESPACE_URI,
7653 "Use of w3.org URL not faulted");
7654 XML_ParserReset(parser, NULL);
7655 expect_failure(text3, XML_ERROR_RESERVED_NAMESPACE_URI,
7656 "Use of w3.org xmlns URL not faulted");
7657 }
7658 END_TEST
7659
7660 /* Test string pool handling of namespace names of 2048 characters */
7661 /* Exercises a particular string pool growth path */
START_TEST(test_ns_extremely_long_prefix)7662 START_TEST(test_ns_extremely_long_prefix)
7663 {
7664 /* C99 compilers are only required to support 4095-character
7665 * strings, so the following needs to be split in two to be safe
7666 * for all compilers.
7667 */
7668 const char *text1 =
7669 "<doc "
7670 /* 64 character on each line */
7671 /* ...gives a total length of 2048 */
7672 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7673 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7674 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7675 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7676 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7677 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7678 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7679 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7680 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7681 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7682 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7683 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7684 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7685 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7686 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7687 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7688 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7689 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7690 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7691 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7692 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7693 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7694 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7695 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7696 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7697 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7698 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7699 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7700 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7701 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7702 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7703 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7704 ":a='12'";
7705 const char *text2 =
7706 " xmlns:"
7707 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7708 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7709 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7710 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7711 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7712 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7713 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7714 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7715 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7716 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7717 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7718 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7719 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7720 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7721 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7722 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7723 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7724 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7725 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7726 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7727 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7728 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7729 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7730 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7731 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7732 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7733 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7734 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7735 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7736 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7737 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7738 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
7739 "='foo'\n>"
7740 "</doc>";
7741
7742 if (_XML_Parse_SINGLE_BYTES(parser, text1, (int)strlen(text1),
7743 XML_FALSE) == XML_STATUS_ERROR)
7744 xml_failure(parser);
7745 if (_XML_Parse_SINGLE_BYTES(parser, text2, (int)strlen(text2),
7746 XML_TRUE) == XML_STATUS_ERROR)
7747 xml_failure(parser);
7748 }
7749 END_TEST
7750
7751 /* Test unknown encoding handlers in namespace setup */
START_TEST(test_ns_unknown_encoding_success)7752 START_TEST(test_ns_unknown_encoding_success)
7753 {
7754 const char *text =
7755 "<?xml version='1.0' encoding='prefix-conv'?>\n"
7756 "<foo:e xmlns:foo='http://example.org/'>Hi</foo:e>";
7757
7758 XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL);
7759 run_character_check(text, XCS("Hi"));
7760 }
7761 END_TEST
7762
7763 /* Test that too many colons are rejected */
START_TEST(test_ns_double_colon)7764 START_TEST(test_ns_double_colon)
7765 {
7766 const char *text =
7767 "<foo:e xmlns:foo='http://example.org/' foo:a:b='bar' />";
7768
7769 expect_failure(text, XML_ERROR_INVALID_TOKEN,
7770 "Double colon in attribute name not faulted");
7771 }
7772 END_TEST
7773
START_TEST(test_ns_double_colon_element)7774 START_TEST(test_ns_double_colon_element)
7775 {
7776 const char *text =
7777 "<foo:bar:e xmlns:foo='http://example.org/' />";
7778
7779 expect_failure(text, XML_ERROR_INVALID_TOKEN,
7780 "Double colon in element name not faulted");
7781 }
7782 END_TEST
7783
7784 /* Test that non-name characters after a colon are rejected */
START_TEST(test_ns_bad_attr_leafname)7785 START_TEST(test_ns_bad_attr_leafname)
7786 {
7787 const char *text =
7788 "<foo:e xmlns:foo='http://example.org/' foo:?ar='baz' />";
7789
7790 expect_failure(text, XML_ERROR_INVALID_TOKEN,
7791 "Invalid character in leafname not faulted");
7792 }
7793 END_TEST
7794
START_TEST(test_ns_bad_element_leafname)7795 START_TEST(test_ns_bad_element_leafname)
7796 {
7797 const char *text =
7798 "<foo:?oc xmlns:foo='http://example.org/' />";
7799
7800 expect_failure(text, XML_ERROR_INVALID_TOKEN,
7801 "Invalid character in element leafname not faulted");
7802 }
7803 END_TEST
7804
7805 /* Test high-byte-set UTF-16 characters are valid in a leafname */
START_TEST(test_ns_utf16_leafname)7806 START_TEST(test_ns_utf16_leafname)
7807 {
7808 const char text[] =
7809 /* <n:e xmlns:n='URI' n:{KHO KHWAI}='a' />
7810 * where {KHO KHWAI} = U+0E04 = 0xe0 0xb8 0x84 in UTF-8
7811 */
7812 "<\0n\0:\0e\0 \0x\0m\0l\0n\0s\0:\0n\0=\0'\0U\0R\0I\0'\0 \0"
7813 "n\0:\0\x04\x0e=\0'\0a\0'\0 \0/\0>\0";
7814 const XML_Char *expected = XCS("a");
7815 CharData storage;
7816
7817 CharData_Init(&storage);
7818 XML_SetStartElementHandler(parser, accumulate_attribute);
7819 XML_SetUserData(parser, &storage);
7820 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text)-1,
7821 XML_TRUE) == XML_STATUS_ERROR)
7822 xml_failure(parser);
7823 CharData_CheckXMLChars(&storage, expected);
7824 }
7825 END_TEST
7826
START_TEST(test_ns_utf16_element_leafname)7827 START_TEST(test_ns_utf16_element_leafname)
7828 {
7829 const char text[] =
7830 /* <n:{KHO KHWAI} xmlns:n='URI'/>
7831 * where {KHO KHWAI} = U+0E04 = 0xe0 0xb8 0x84 in UTF-8
7832 */
7833 "\0<\0n\0:\x0e\x04\0 \0x\0m\0l\0n\0s\0:\0n\0=\0'\0U\0R\0I\0'\0/\0>";
7834 #ifdef XML_UNICODE
7835 const XML_Char *expected = XCS("URI \x0e04");
7836 #else
7837 const XML_Char *expected = XCS("URI \xe0\xb8\x84");
7838 #endif
7839 CharData storage;
7840
7841 CharData_Init(&storage);
7842 XML_SetStartElementHandler(parser, start_element_event_handler);
7843 XML_SetUserData(parser, &storage);
7844 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text)-1,
7845 XML_TRUE) == XML_STATUS_ERROR)
7846 xml_failure(parser);
7847 CharData_CheckXMLChars(&storage, expected);
7848 }
7849 END_TEST
7850
START_TEST(test_ns_utf16_doctype)7851 START_TEST(test_ns_utf16_doctype)
7852 {
7853 const char text[] =
7854 /* <!DOCTYPE foo:{KHO KHWAI} [ <!ENTITY bar 'baz'> ]>\n
7855 * where {KHO KHWAI} = U+0E04 = 0xe0 0xb8 0x84 in UTF-8
7856 */
7857 "\0<\0!\0D\0O\0C\0T\0Y\0P\0E\0 \0f\0o\0o\0:\x0e\x04\0 "
7858 "\0[\0 \0<\0!\0E\0N\0T\0I\0T\0Y\0 \0b\0a\0r\0 \0'\0b\0a\0z\0'\0>\0 "
7859 "\0]\0>\0\n"
7860 /* <foo:{KHO KHWAI} xmlns:foo='URI'>&bar;</foo:{KHO KHWAI}> */
7861 "\0<\0f\0o\0o\0:\x0e\x04\0 "
7862 "\0x\0m\0l\0n\0s\0:\0f\0o\0o\0=\0'\0U\0R\0I\0'\0>"
7863 "\0&\0b\0a\0r\0;"
7864 "\0<\0/\0f\0o\0o\0:\x0e\x04\0>";
7865 #ifdef XML_UNICODE
7866 const XML_Char *expected = XCS("URI \x0e04");
7867 #else
7868 const XML_Char *expected = XCS("URI \xe0\xb8\x84");
7869 #endif
7870 CharData storage;
7871
7872 CharData_Init(&storage);
7873 XML_SetUserData(parser, &storage);
7874 XML_SetStartElementHandler(parser, start_element_event_handler);
7875 XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL);
7876 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text)-1,
7877 XML_TRUE) == XML_STATUS_ERROR)
7878 xml_failure(parser);
7879 CharData_CheckXMLChars(&storage, expected);
7880 }
7881 END_TEST
7882
START_TEST(test_ns_invalid_doctype)7883 START_TEST(test_ns_invalid_doctype)
7884 {
7885 const char *text =
7886 "<!DOCTYPE foo:!bad [ <!ENTITY bar 'baz' ]>\n"
7887 "<foo:!bad>&bar;</foo:!bad>";
7888
7889 expect_failure(text, XML_ERROR_INVALID_TOKEN,
7890 "Invalid character in document local name not faulted");
7891 }
7892 END_TEST
7893
START_TEST(test_ns_double_colon_doctype)7894 START_TEST(test_ns_double_colon_doctype)
7895 {
7896 const char *text =
7897 "<!DOCTYPE foo:a:doc [ <!ENTITY bar 'baz' ]>\n"
7898 "<foo:a:doc>&bar;</foo:a:doc>";
7899
7900 expect_failure(text, XML_ERROR_SYNTAX,
7901 "Double colon in document name not faulted");
7902 }
7903 END_TEST
7904
7905 /* Control variable; the number of times duff_allocator() will successfully allocate */
7906 #define ALLOC_ALWAYS_SUCCEED (-1)
7907 #define REALLOC_ALWAYS_SUCCEED (-1)
7908
7909 static intptr_t allocation_count = ALLOC_ALWAYS_SUCCEED;
7910 static intptr_t reallocation_count = REALLOC_ALWAYS_SUCCEED;
7911
7912 /* Crocked allocator for allocation failure tests */
duff_allocator(size_t size)7913 static void *duff_allocator(size_t size)
7914 {
7915 if (allocation_count == 0)
7916 return NULL;
7917 if (allocation_count != ALLOC_ALWAYS_SUCCEED)
7918 allocation_count--;
7919 return malloc(size);
7920 }
7921
7922 /* Crocked reallocator for allocation failure tests */
duff_reallocator(void * ptr,size_t size)7923 static void *duff_reallocator(void *ptr, size_t size)
7924 {
7925 if (reallocation_count == 0)
7926 return NULL;
7927 if (reallocation_count != REALLOC_ALWAYS_SUCCEED)
7928 reallocation_count--;
7929 return realloc(ptr, size);
7930 }
7931
7932 /* Test that a failure to allocate the parser structure fails gracefully */
START_TEST(test_misc_alloc_create_parser)7933 START_TEST(test_misc_alloc_create_parser)
7934 {
7935 XML_Memory_Handling_Suite memsuite = { duff_allocator, realloc, free };
7936 unsigned int i;
7937 const unsigned int max_alloc_count = 10;
7938
7939 /* Something this simple shouldn't need more than 10 allocations */
7940 for (i = 0; i < max_alloc_count; i++)
7941 {
7942 allocation_count = i;
7943 parser = XML_ParserCreate_MM(NULL, &memsuite, NULL);
7944 if (parser != NULL)
7945 break;
7946 }
7947 if (i == 0)
7948 fail("Parser unexpectedly ignored failing allocator");
7949 else if (i == max_alloc_count)
7950 fail("Parser not created with max allocation count");
7951 }
7952 END_TEST
7953
7954 /* Test memory allocation failures for a parser with an encoding */
START_TEST(test_misc_alloc_create_parser_with_encoding)7955 START_TEST(test_misc_alloc_create_parser_with_encoding)
7956 {
7957 XML_Memory_Handling_Suite memsuite = { duff_allocator, realloc, free };
7958 unsigned int i;
7959 const unsigned int max_alloc_count = 10;
7960
7961 /* Try several levels of allocation */
7962 for (i = 0; i < max_alloc_count; i++) {
7963 allocation_count = i;
7964 parser = XML_ParserCreate_MM(XCS("us-ascii"), &memsuite, NULL);
7965 if (parser != NULL)
7966 break;
7967 }
7968 if (i == 0)
7969 fail("Parser ignored failing allocator");
7970 else if (i == max_alloc_count)
7971 fail("Parser not created with max allocation count");
7972 }
7973 END_TEST
7974
7975 /* Test that freeing a NULL parser doesn't cause an explosion.
7976 * (Not actually tested anywhere else)
7977 */
START_TEST(test_misc_null_parser)7978 START_TEST(test_misc_null_parser)
7979 {
7980 XML_ParserFree(NULL);
7981 }
7982 END_TEST
7983
7984 /* Test that XML_ErrorString rejects out-of-range codes */
START_TEST(test_misc_error_string)7985 START_TEST(test_misc_error_string)
7986 {
7987 if (XML_ErrorString((enum XML_Error)-1) != NULL)
7988 fail("Negative error code not rejected");
7989 if (XML_ErrorString((enum XML_Error)100) != NULL)
7990 fail("Large error code not rejected");
7991 }
7992 END_TEST
7993
7994 /* Test the version information is consistent */
7995
7996 /* Since we are working in XML_LChars (potentially 16-bits), we
7997 * can't use the standard C library functions for character
7998 * manipulation and have to roll our own.
7999 */
8000 static int
parse_version(const XML_LChar * version_text,XML_Expat_Version * version_struct)8001 parse_version(const XML_LChar *version_text,
8002 XML_Expat_Version *version_struct)
8003 {
8004 while (*version_text != 0x00) {
8005 if (*version_text >= ASCII_0 && *version_text <= ASCII_9)
8006 break;
8007 version_text++;
8008 }
8009 if (*version_text == 0x00)
8010 return XML_FALSE;
8011
8012 /* version_struct->major = strtoul(version_text, 10, &version_text) */
8013 version_struct->major = 0;
8014 while (*version_text >= ASCII_0 && *version_text <= ASCII_9) {
8015 version_struct->major =
8016 10 * version_struct->major + (*version_text++ - ASCII_0);
8017 }
8018 if (*version_text++ != ASCII_PERIOD)
8019 return XML_FALSE;
8020
8021 /* Now for the minor version number */
8022 version_struct->minor = 0;
8023 while (*version_text >= ASCII_0 && *version_text <= ASCII_9) {
8024 version_struct->minor =
8025 10 * version_struct->minor + (*version_text++ - ASCII_0);
8026 }
8027 if (*version_text++ != ASCII_PERIOD)
8028 return XML_FALSE;
8029
8030 /* Finally the micro version number */
8031 version_struct->micro = 0;
8032 while (*version_text >= ASCII_0 && *version_text <= ASCII_9) {
8033 version_struct->micro =
8034 10 * version_struct->micro + (*version_text++ - ASCII_0);
8035 }
8036 if (*version_text != 0x00)
8037 return XML_FALSE;
8038 return XML_TRUE;
8039 }
8040
8041 static int
versions_equal(const XML_Expat_Version * first,const XML_Expat_Version * second)8042 versions_equal(const XML_Expat_Version *first,
8043 const XML_Expat_Version *second)
8044 {
8045 return (first->major == second->major &&
8046 first->minor == second->minor &&
8047 first->micro == second->micro);
8048 }
8049
START_TEST(test_misc_version)8050 START_TEST(test_misc_version)
8051 {
8052 XML_Expat_Version read_version = XML_ExpatVersionInfo();
8053 /* Silence compiler warning with the following assignment */
8054 XML_Expat_Version parsed_version = { 0, 0, 0 };
8055 const XML_LChar *version_text = XML_ExpatVersion();
8056
8057 if (version_text == NULL)
8058 fail("Could not obtain version text");
8059 if (!parse_version(version_text, &parsed_version))
8060 fail("Unable to parse version text");
8061 if (!versions_equal(&read_version, &parsed_version))
8062 fail("Version mismatch");
8063
8064 #if ! defined(XML_UNICODE) || defined(XML_UNICODE_WCHAR_T)
8065 if (xcstrcmp(version_text, XCS("expat_2.2.6"))) /* needs bump on releases */
8066 fail("XML_*_VERSION in expat.h out of sync?\n");
8067 #else
8068 /* If we have XML_UNICODE defined but not XML_UNICODE_WCHAR_T
8069 * then XML_LChar is defined as char, for some reason.
8070 */
8071 if (strcmp(version_text, "expat_2.2.5")) /* needs bump on releases */
8072 fail("XML_*_VERSION in expat.h out of sync?\n");
8073 #endif /* ! defined(XML_UNICODE) || defined(XML_UNICODE_WCHAR_T) */
8074 }
8075 END_TEST
8076
8077 /* Test feature information */
START_TEST(test_misc_features)8078 START_TEST(test_misc_features)
8079 {
8080 const XML_Feature *features = XML_GetFeatureList();
8081
8082 /* Prevent problems with double-freeing parsers */
8083 parser = NULL;
8084 if (features == NULL)
8085 fail("Failed to get feature information");
8086 /* Loop through the features checking what we can */
8087 while (features->feature != XML_FEATURE_END) {
8088 switch(features->feature) {
8089 case XML_FEATURE_SIZEOF_XML_CHAR:
8090 if (features->value != sizeof(XML_Char))
8091 fail("Incorrect size of XML_Char");
8092 break;
8093 case XML_FEATURE_SIZEOF_XML_LCHAR:
8094 if (features->value != sizeof(XML_LChar))
8095 fail("Incorrect size of XML_LChar");
8096 break;
8097 default:
8098 break;
8099 }
8100 features++;
8101 }
8102 }
8103 END_TEST
8104
8105 /* Regression test for GitHub Issue #17: memory leak parsing attribute
8106 * values with mixed bound and unbound namespaces.
8107 */
START_TEST(test_misc_attribute_leak)8108 START_TEST(test_misc_attribute_leak)
8109 {
8110 const char *text = "<D xmlns:L=\"D\" l:a='' L:a=''/>";
8111 XML_Memory_Handling_Suite memsuite = {
8112 tracking_malloc,
8113 tracking_realloc,
8114 tracking_free
8115 };
8116
8117 parser = XML_ParserCreate_MM(XCS("UTF-8"), &memsuite, XCS("\n"));
8118 expect_failure(text, XML_ERROR_UNBOUND_PREFIX,
8119 "Unbound prefixes not found");
8120 XML_ParserFree(parser);
8121 /* Prevent the teardown trying to double free */
8122 parser = NULL;
8123
8124 if (!tracking_report())
8125 fail("Memory leak found");
8126 }
8127 END_TEST
8128
8129 /* Test parser created for UTF-16LE is successful */
START_TEST(test_misc_utf16le)8130 START_TEST(test_misc_utf16le)
8131 {
8132 const char text[] =
8133 /* <?xml version='1.0'?><q>Hi</q> */
8134 "<\0?\0x\0m\0l\0 \0"
8135 "v\0e\0r\0s\0i\0o\0n\0=\0'\0\x31\0.\0\x30\0'\0?\0>\0"
8136 "<\0q\0>\0H\0i\0<\0/\0q\0>\0";
8137 const XML_Char *expected = XCS("Hi");
8138 CharData storage;
8139
8140 parser = XML_ParserCreate(XCS("UTF-16LE"));
8141 if (parser == NULL)
8142 fail("Parser not created");
8143
8144 CharData_Init(&storage);
8145 XML_SetUserData(parser, &storage);
8146 XML_SetCharacterDataHandler(parser, accumulate_characters);
8147 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)sizeof(text)-1,
8148 XML_TRUE) == XML_STATUS_ERROR)
8149 xml_failure(parser);
8150 CharData_CheckXMLChars(&storage, expected);
8151 }
8152 END_TEST
8153
8154
8155 static void
alloc_setup(void)8156 alloc_setup(void)
8157 {
8158 XML_Memory_Handling_Suite memsuite = {
8159 duff_allocator,
8160 duff_reallocator,
8161 free
8162 };
8163
8164 /* Ensure the parser creation will go through */
8165 allocation_count = ALLOC_ALWAYS_SUCCEED;
8166 reallocation_count = REALLOC_ALWAYS_SUCCEED;
8167 parser = XML_ParserCreate_MM(NULL, &memsuite, NULL);
8168 if (parser == NULL)
8169 fail("Parser not created");
8170 }
8171
8172 static void
alloc_teardown(void)8173 alloc_teardown(void)
8174 {
8175 basic_teardown();
8176 }
8177
8178
8179 /* Test the effects of allocation failures on xml declaration processing */
START_TEST(test_alloc_parse_xdecl)8180 START_TEST(test_alloc_parse_xdecl)
8181 {
8182 const char *text =
8183 "<?xml version='1.0' encoding='utf-8'?>\n"
8184 "<doc>Hello, world</doc>";
8185 int i;
8186 const int max_alloc_count = 15;
8187
8188 for (i = 0; i < max_alloc_count; i++) {
8189 allocation_count = i;
8190 XML_SetXmlDeclHandler(parser, dummy_xdecl_handler);
8191 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
8192 XML_TRUE) != XML_STATUS_ERROR)
8193 break;
8194 /* Resetting the parser is insufficient, because some memory
8195 * allocations are cached within the parser. Instead we use
8196 * the teardown and setup routines to ensure that we have the
8197 * right sort of parser back in our hands.
8198 */
8199 alloc_teardown();
8200 alloc_setup();
8201 }
8202 if (i == 0)
8203 fail("Parse succeeded despite failing allocator");
8204 if (i == max_alloc_count)
8205 fail("Parse failed with max allocations");
8206 }
8207 END_TEST
8208
8209 /* As above, but with an encoding big enough to cause storing the
8210 * version information to expand the string pool being used.
8211 */
8212 static int XMLCALL
long_encoding_handler(void * UNUSED_P (userData),const XML_Char * UNUSED_P (encoding),XML_Encoding * info)8213 long_encoding_handler(void *UNUSED_P(userData),
8214 const XML_Char *UNUSED_P(encoding),
8215 XML_Encoding *info)
8216 {
8217 int i;
8218
8219 for (i = 0; i < 256; i++)
8220 info->map[i] = i;
8221 info->data = NULL;
8222 info->convert = NULL;
8223 info->release = NULL;
8224 return XML_STATUS_OK;
8225 }
8226
START_TEST(test_alloc_parse_xdecl_2)8227 START_TEST(test_alloc_parse_xdecl_2)
8228 {
8229 const char *text =
8230 "<?xml version='1.0' encoding='"
8231 /* Each line is 64 characters */
8232 "ThisIsAStupidlyLongEncodingNameIntendedToTriggerPoolGrowth123456"
8233 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
8234 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
8235 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
8236 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
8237 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
8238 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
8239 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
8240 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
8241 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
8242 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
8243 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
8244 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
8245 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
8246 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
8247 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMN"
8248 "'?>"
8249 "<doc>Hello, world</doc>";
8250 int i;
8251 const int max_alloc_count = 20;
8252
8253 for (i = 0; i < max_alloc_count; i++) {
8254 allocation_count = i;
8255 XML_SetXmlDeclHandler(parser, dummy_xdecl_handler);
8256 XML_SetUnknownEncodingHandler(parser, long_encoding_handler, NULL);
8257 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
8258 XML_TRUE) != XML_STATUS_ERROR)
8259 break;
8260 /* See comment in test_alloc_parse_xdecl() */
8261 alloc_teardown();
8262 alloc_setup();
8263 }
8264 if (i == 0)
8265 fail("Parse succeeded despite failing allocator");
8266 if (i == max_alloc_count)
8267 fail("Parse failed with max allocations");
8268 }
8269 END_TEST
8270
8271 /* Test the effects of allocation failures on a straightforward parse */
START_TEST(test_alloc_parse_pi)8272 START_TEST(test_alloc_parse_pi)
8273 {
8274 const char *text =
8275 "<?xml version='1.0' encoding='utf-8'?>\n"
8276 "<?pi unknown?>\n"
8277 "<doc>"
8278 "Hello, world"
8279 "</doc>";
8280 int i;
8281 const int max_alloc_count = 15;
8282
8283 for (i = 0; i < max_alloc_count; i++) {
8284 allocation_count = i;
8285 XML_SetProcessingInstructionHandler(parser, dummy_pi_handler);
8286 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
8287 XML_TRUE) != XML_STATUS_ERROR)
8288 break;
8289 /* See comment in test_alloc_parse_xdecl() */
8290 alloc_teardown();
8291 alloc_setup();
8292 }
8293 if (i == 0)
8294 fail("Parse succeeded despite failing allocator");
8295 if (i == max_alloc_count)
8296 fail("Parse failed with max allocations");
8297 }
8298 END_TEST
8299
START_TEST(test_alloc_parse_pi_2)8300 START_TEST(test_alloc_parse_pi_2)
8301 {
8302 const char *text =
8303 "<?xml version='1.0' encoding='utf-8'?>\n"
8304 "<doc>"
8305 "Hello, world"
8306 "<?pi unknown?>\n"
8307 "</doc>";
8308 int i;
8309 const int max_alloc_count = 15;
8310
8311 for (i = 0; i < max_alloc_count; i++) {
8312 allocation_count = i;
8313 XML_SetProcessingInstructionHandler(parser, dummy_pi_handler);
8314 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
8315 XML_TRUE) != XML_STATUS_ERROR)
8316 break;
8317 /* See comment in test_alloc_parse_xdecl() */
8318 alloc_teardown();
8319 alloc_setup();
8320 }
8321 if (i == 0)
8322 fail("Parse succeeded despite failing allocator");
8323 if (i == max_alloc_count)
8324 fail("Parse failed with max allocations");
8325 }
8326 END_TEST
8327
START_TEST(test_alloc_parse_pi_3)8328 START_TEST(test_alloc_parse_pi_3)
8329 {
8330 const char *text =
8331 "<?"
8332 /* 64 characters per line */
8333 "This processing instruction should be long enough to ensure that"
8334 "it triggers the growth of an internal string pool when the "
8335 "allocator fails at a cruicial moment FGHIJKLMNOPABCDEFGHIJKLMNOP"
8336 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
8337 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
8338 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
8339 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
8340 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
8341 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
8342 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
8343 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
8344 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
8345 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
8346 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
8347 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
8348 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
8349 "Q?><doc/>";
8350 int i;
8351 const int max_alloc_count = 20;
8352
8353 for (i = 0; i < max_alloc_count; i++) {
8354 allocation_count = i;
8355 XML_SetProcessingInstructionHandler(parser, dummy_pi_handler);
8356 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
8357 XML_TRUE) != XML_STATUS_ERROR)
8358 break;
8359 /* See comment in test_alloc_parse_xdecl() */
8360 alloc_teardown();
8361 alloc_setup();
8362 }
8363 if (i == 0)
8364 fail("Parse succeeded despite failing allocator");
8365 if (i == max_alloc_count)
8366 fail("Parse failed with max allocations");
8367 }
8368 END_TEST
8369
START_TEST(test_alloc_parse_comment)8370 START_TEST(test_alloc_parse_comment)
8371 {
8372 const char *text =
8373 "<?xml version='1.0' encoding='utf-8'?>\n"
8374 "<!-- Test parsing this comment -->"
8375 "<doc>Hi</doc>";
8376 int i;
8377 const int max_alloc_count = 15;
8378
8379 for (i = 0; i < max_alloc_count; i++) {
8380 allocation_count = i;
8381 XML_SetCommentHandler(parser, dummy_comment_handler);
8382 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
8383 XML_TRUE) != XML_STATUS_ERROR)
8384 break;
8385 /* See comment in test_alloc_parse_xdecl() */
8386 alloc_teardown();
8387 alloc_setup();
8388 }
8389 if (i == 0)
8390 fail("Parse succeeded despite failing allocator");
8391 if (i == max_alloc_count)
8392 fail("Parse failed with max allocations");
8393 }
8394 END_TEST
8395
START_TEST(test_alloc_parse_comment_2)8396 START_TEST(test_alloc_parse_comment_2)
8397 {
8398 const char *text =
8399 "<?xml version='1.0' encoding='utf-8'?>\n"
8400 "<doc>"
8401 "Hello, world"
8402 "<!-- Parse this comment too -->"
8403 "</doc>";
8404 int i;
8405 const int max_alloc_count = 15;
8406
8407 for (i = 0; i < max_alloc_count; i++) {
8408 allocation_count = i;
8409 XML_SetCommentHandler(parser, dummy_comment_handler);
8410 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
8411 XML_TRUE) != XML_STATUS_ERROR)
8412 break;
8413 /* See comment in test_alloc_parse_xdecl() */
8414 alloc_teardown();
8415 alloc_setup();
8416 }
8417 if (i == 0)
8418 fail("Parse succeeded despite failing allocator");
8419 if (i == max_alloc_count)
8420 fail("Parse failed with max allocations");
8421 }
8422 END_TEST
8423
8424 static int XMLCALL
external_entity_duff_loader(XML_Parser parser,const XML_Char * context,const XML_Char * UNUSED_P (base),const XML_Char * UNUSED_P (systemId),const XML_Char * UNUSED_P (publicId))8425 external_entity_duff_loader(XML_Parser parser,
8426 const XML_Char *context,
8427 const XML_Char *UNUSED_P(base),
8428 const XML_Char *UNUSED_P(systemId),
8429 const XML_Char *UNUSED_P(publicId))
8430 {
8431 XML_Parser new_parser;
8432 unsigned int i;
8433 const unsigned int max_alloc_count = 10;
8434
8435 /* Try a few different allocation levels */
8436 for (i = 0; i < max_alloc_count; i++)
8437 {
8438 allocation_count = i;
8439 new_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
8440 if (new_parser != NULL)
8441 {
8442 XML_ParserFree(new_parser);
8443 break;
8444 }
8445 }
8446 if (i == 0)
8447 fail("External parser creation ignored failing allocator");
8448 else if (i == max_alloc_count)
8449 fail("Extern parser not created with max allocation count");
8450
8451 /* Make sure other random allocation doesn't now fail */
8452 allocation_count = ALLOC_ALWAYS_SUCCEED;
8453
8454 /* Make sure the failure code path is executed too */
8455 return XML_STATUS_ERROR;
8456 }
8457
8458 /* Test that external parser creation running out of memory is
8459 * correctly reported. Based on the external entity test cases.
8460 */
START_TEST(test_alloc_create_external_parser)8461 START_TEST(test_alloc_create_external_parser)
8462 {
8463 const char *text =
8464 "<?xml version='1.0' encoding='us-ascii'?>\n"
8465 "<!DOCTYPE doc SYSTEM 'foo'>\n"
8466 "<doc>&entity;</doc>";
8467 char foo_text[] =
8468 "<!ELEMENT doc (#PCDATA)*>";
8469
8470 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
8471 XML_SetUserData(parser, foo_text);
8472 XML_SetExternalEntityRefHandler(parser,
8473 external_entity_duff_loader);
8474 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR) {
8475 fail("External parser allocator returned success incorrectly");
8476 }
8477 }
8478 END_TEST
8479
8480 /* More external parser memory allocation testing */
START_TEST(test_alloc_run_external_parser)8481 START_TEST(test_alloc_run_external_parser)
8482 {
8483 const char *text =
8484 "<?xml version='1.0' encoding='us-ascii'?>\n"
8485 "<!DOCTYPE doc SYSTEM 'foo'>\n"
8486 "<doc>&entity;</doc>";
8487 char foo_text[] =
8488 "<!ELEMENT doc (#PCDATA)*>";
8489 unsigned int i;
8490 const unsigned int max_alloc_count = 15;
8491
8492 for (i = 0; i < max_alloc_count; i++) {
8493 XML_SetParamEntityParsing(parser,
8494 XML_PARAM_ENTITY_PARSING_ALWAYS);
8495 XML_SetUserData(parser, foo_text);
8496 XML_SetExternalEntityRefHandler(parser,
8497 external_entity_null_loader);
8498 allocation_count = i;
8499 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR)
8500 break;
8501 /* See comment in test_alloc_parse_xdecl() */
8502 alloc_teardown();
8503 alloc_setup();
8504 }
8505 if (i == 0)
8506 fail("Parsing ignored failing allocator");
8507 else if (i == max_alloc_count)
8508 fail("Parsing failed with allocation count 10");
8509 }
8510 END_TEST
8511
8512
8513 static int XMLCALL
external_entity_dbl_handler(XML_Parser parser,const XML_Char * context,const XML_Char * UNUSED_P (base),const XML_Char * UNUSED_P (systemId),const XML_Char * UNUSED_P (publicId))8514 external_entity_dbl_handler(XML_Parser parser,
8515 const XML_Char *context,
8516 const XML_Char *UNUSED_P(base),
8517 const XML_Char *UNUSED_P(systemId),
8518 const XML_Char *UNUSED_P(publicId))
8519 {
8520 intptr_t callno = (intptr_t)XML_GetUserData(parser);
8521 const char *text;
8522 XML_Parser new_parser;
8523 int i;
8524 const int max_alloc_count = 20;
8525
8526 if (callno == 0) {
8527 /* First time through, check how many calls to malloc occur */
8528 text = ("<!ELEMENT doc (e+)>\n"
8529 "<!ATTLIST doc xmlns CDATA #IMPLIED>\n"
8530 "<!ELEMENT e EMPTY>\n");
8531 allocation_count = 10000;
8532 new_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
8533 if (new_parser == NULL) {
8534 fail("Unable to allocate first external parser");
8535 return XML_STATUS_ERROR;
8536 }
8537 /* Stash the number of calls in the user data */
8538 XML_SetUserData(parser, (void *)(intptr_t)(10000 - allocation_count));
8539 } else {
8540 text = ("<?xml version='1.0' encoding='us-ascii'?>"
8541 "<e/>");
8542 /* Try at varying levels to exercise more code paths */
8543 for (i = 0; i < max_alloc_count; i++) {
8544 allocation_count = callno + i;
8545 new_parser = XML_ExternalEntityParserCreate(parser,
8546 context,
8547 NULL);
8548 if (new_parser != NULL)
8549 break;
8550 }
8551 if (i == 0) {
8552 fail("Second external parser unexpectedly created");
8553 XML_ParserFree(new_parser);
8554 return XML_STATUS_ERROR;
8555 }
8556 else if (i == max_alloc_count) {
8557 fail("Second external parser not created");
8558 return XML_STATUS_ERROR;
8559 }
8560 }
8561
8562 allocation_count = ALLOC_ALWAYS_SUCCEED;
8563 if (_XML_Parse_SINGLE_BYTES(new_parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR) {
8564 xml_failure(new_parser);
8565 return XML_STATUS_ERROR;
8566 }
8567 XML_ParserFree(new_parser);
8568 return XML_STATUS_OK;
8569 }
8570
8571 /* Test that running out of memory in dtdCopy is correctly reported.
8572 * Based on test_default_ns_from_ext_subset_and_ext_ge()
8573 */
START_TEST(test_alloc_dtd_copy_default_atts)8574 START_TEST(test_alloc_dtd_copy_default_atts)
8575 {
8576 const char *text =
8577 "<?xml version='1.0'?>\n"
8578 "<!DOCTYPE doc SYSTEM 'http://example.org/doc.dtd' [\n"
8579 " <!ENTITY en SYSTEM 'http://example.org/entity.ent'>\n"
8580 "]>\n"
8581 "<doc xmlns='http://example.org/ns1'>\n"
8582 "&en;\n"
8583 "</doc>";
8584
8585 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
8586 XML_SetExternalEntityRefHandler(parser,
8587 external_entity_dbl_handler);
8588 XML_SetUserData(parser, NULL);
8589 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR)
8590 xml_failure(parser);
8591 }
8592 END_TEST
8593
8594
8595 static int XMLCALL
external_entity_dbl_handler_2(XML_Parser parser,const XML_Char * context,const XML_Char * UNUSED_P (base),const XML_Char * UNUSED_P (systemId),const XML_Char * UNUSED_P (publicId))8596 external_entity_dbl_handler_2(XML_Parser parser,
8597 const XML_Char *context,
8598 const XML_Char *UNUSED_P(base),
8599 const XML_Char *UNUSED_P(systemId),
8600 const XML_Char *UNUSED_P(publicId))
8601 {
8602 intptr_t callno = (intptr_t)XML_GetUserData(parser);
8603 const char *text;
8604 XML_Parser new_parser;
8605 enum XML_Status rv;
8606
8607 if (callno == 0) {
8608 /* Try different allocation levels for whole exercise */
8609 text = ("<!ELEMENT doc (e+)>\n"
8610 "<!ATTLIST doc xmlns CDATA #IMPLIED>\n"
8611 "<!ELEMENT e EMPTY>\n");
8612 XML_SetUserData(parser, (void *)(intptr_t)1);
8613 new_parser = XML_ExternalEntityParserCreate(parser,
8614 context,
8615 NULL);
8616 if (new_parser == NULL)
8617 return XML_STATUS_ERROR;
8618 rv = _XML_Parse_SINGLE_BYTES(new_parser, text, (int)strlen(text),
8619 XML_TRUE);
8620 } else {
8621 /* Just run through once */
8622 text = ("<?xml version='1.0' encoding='us-ascii'?>"
8623 "<e/>");
8624 new_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
8625 if (new_parser == NULL)
8626 return XML_STATUS_ERROR;
8627 rv =_XML_Parse_SINGLE_BYTES(new_parser, text, (int)strlen(text),
8628 XML_TRUE);
8629 }
8630 XML_ParserFree(new_parser);
8631 if (rv == XML_STATUS_ERROR)
8632 return XML_STATUS_ERROR;
8633 return XML_STATUS_OK;
8634 }
8635
8636 /* Test more external entity allocation failure paths */
START_TEST(test_alloc_external_entity)8637 START_TEST(test_alloc_external_entity)
8638 {
8639 const char *text =
8640 "<?xml version='1.0'?>\n"
8641 "<!DOCTYPE doc SYSTEM 'http://example.org/doc.dtd' [\n"
8642 " <!ENTITY en SYSTEM 'http://example.org/entity.ent'>\n"
8643 "]>\n"
8644 "<doc xmlns='http://example.org/ns1'>\n"
8645 "&en;\n"
8646 "</doc>";
8647 int i;
8648 const int alloc_test_max_repeats = 50;
8649
8650 for (i = 0; i < alloc_test_max_repeats; i++) {
8651 allocation_count = -1;
8652 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
8653 XML_SetExternalEntityRefHandler(parser,
8654 external_entity_dbl_handler_2);
8655 XML_SetUserData(parser, NULL);
8656 allocation_count = i;
8657 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
8658 XML_TRUE) == XML_STATUS_OK)
8659 break;
8660 /* See comment in test_alloc_parse_xdecl() */
8661 alloc_teardown();
8662 alloc_setup();
8663 }
8664 allocation_count = -1;
8665 if (i == 0)
8666 fail("External entity parsed despite duff allocator");
8667 if (i == alloc_test_max_repeats)
8668 fail("External entity not parsed at max allocation count");
8669 }
8670 END_TEST
8671
8672 /* Test more allocation failure paths */
8673 static int XMLCALL
external_entity_alloc_set_encoding(XML_Parser parser,const XML_Char * context,const XML_Char * UNUSED_P (base),const XML_Char * UNUSED_P (systemId),const XML_Char * UNUSED_P (publicId))8674 external_entity_alloc_set_encoding(XML_Parser parser,
8675 const XML_Char *context,
8676 const XML_Char *UNUSED_P(base),
8677 const XML_Char *UNUSED_P(systemId),
8678 const XML_Char *UNUSED_P(publicId))
8679 {
8680 /* As for external_entity_loader() */
8681 const char *text =
8682 "<?xml encoding='iso-8859-3'?>"
8683 "\xC3\xA9";
8684 XML_Parser ext_parser;
8685 enum XML_Status status;
8686
8687 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
8688 if (ext_parser == NULL)
8689 return XML_STATUS_ERROR;
8690 if (!XML_SetEncoding(ext_parser, XCS("utf-8"))) {
8691 XML_ParserFree(ext_parser);
8692 return XML_STATUS_ERROR;
8693 }
8694 status = _XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text),
8695 XML_TRUE);
8696 XML_ParserFree(ext_parser);
8697 if (status == XML_STATUS_ERROR)
8698 return XML_STATUS_ERROR;
8699 return XML_STATUS_OK;
8700 }
8701
START_TEST(test_alloc_ext_entity_set_encoding)8702 START_TEST(test_alloc_ext_entity_set_encoding)
8703 {
8704 const char *text =
8705 "<!DOCTYPE doc [\n"
8706 " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n"
8707 "]>\n"
8708 "<doc>&en;</doc>";
8709 int i;
8710 const int max_allocation_count = 30;
8711
8712 for (i = 0; i < max_allocation_count; i++) {
8713 XML_SetExternalEntityRefHandler(parser,
8714 external_entity_alloc_set_encoding);
8715 allocation_count = i;
8716 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
8717 XML_TRUE) == XML_STATUS_OK)
8718 break;
8719 allocation_count = -1;
8720 /* See comment in test_alloc_parse_xdecl() */
8721 alloc_teardown();
8722 alloc_setup();
8723 }
8724 if (i == 0)
8725 fail("Encoding check succeeded despite failing allocator");
8726 if (i == max_allocation_count)
8727 fail("Encoding failed at max allocation count");
8728 }
8729 END_TEST
8730
8731 static int XMLCALL
unknown_released_encoding_handler(void * UNUSED_P (data),const XML_Char * encoding,XML_Encoding * info)8732 unknown_released_encoding_handler(void *UNUSED_P(data),
8733 const XML_Char *encoding,
8734 XML_Encoding *info)
8735 {
8736 if (!xcstrcmp(encoding, XCS("unsupported-encoding"))) {
8737 int i;
8738
8739 for (i = 0; i < 256; i++)
8740 info->map[i] = i;
8741 info->data = NULL;
8742 info->convert = NULL;
8743 info->release = dummy_release;
8744 return XML_STATUS_OK;
8745 }
8746 return XML_STATUS_ERROR;
8747 }
8748
8749 /* Test the effects of allocation failure in internal entities.
8750 * Based on test_unknown_encoding_internal_entity
8751 */
START_TEST(test_alloc_internal_entity)8752 START_TEST(test_alloc_internal_entity)
8753 {
8754 const char *text =
8755 "<?xml version='1.0' encoding='unsupported-encoding'?>\n"
8756 "<!DOCTYPE test [<!ENTITY foo 'bar'>]>\n"
8757 "<test a='&foo;'/>";
8758 unsigned int i;
8759 const unsigned int max_alloc_count = 20;
8760
8761 for (i = 0; i < max_alloc_count; i++) {
8762 allocation_count = i;
8763 XML_SetUnknownEncodingHandler(parser,
8764 unknown_released_encoding_handler,
8765 NULL);
8766 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR)
8767 break;
8768 /* See comment in test_alloc_parse_xdecl() */
8769 alloc_teardown();
8770 alloc_setup();
8771 }
8772 if (i == 0)
8773 fail("Internal entity worked despite failing allocations");
8774 else if (i == max_alloc_count)
8775 fail("Internal entity failed at max allocation count");
8776 }
8777 END_TEST
8778
8779
8780 /* Test the robustness against allocation failure of element handling
8781 * Based on test_dtd_default_handling().
8782 */
START_TEST(test_alloc_dtd_default_handling)8783 START_TEST(test_alloc_dtd_default_handling)
8784 {
8785 const char *text =
8786 "<!DOCTYPE doc [\n"
8787 "<!ENTITY e SYSTEM 'http://example.org/e'>\n"
8788 "<!NOTATION n SYSTEM 'http://example.org/n'>\n"
8789 "<!ENTITY e1 SYSTEM 'http://example.org/e' NDATA n>\n"
8790 "<!ELEMENT doc (#PCDATA)>\n"
8791 "<!ATTLIST doc a CDATA #IMPLIED>\n"
8792 "<?pi in dtd?>\n"
8793 "<!--comment in dtd-->\n"
8794 "]>\n"
8795 "<doc><![CDATA[text in doc]]></doc>";
8796 const XML_Char *expected = XCS("\n\n\n\n\n\n\n\n\n<doc>text in doc</doc>");
8797 CharData storage;
8798 int i;
8799 const int max_alloc_count = 25;
8800
8801 for (i = 0; i < max_alloc_count; i++) {
8802 allocation_count = i;
8803 dummy_handler_flags = 0;
8804 XML_SetDefaultHandler(parser, accumulate_characters);
8805 XML_SetDoctypeDeclHandler(parser,
8806 dummy_start_doctype_handler,
8807 dummy_end_doctype_handler);
8808 XML_SetEntityDeclHandler(parser, dummy_entity_decl_handler);
8809 XML_SetNotationDeclHandler(parser, dummy_notation_decl_handler);
8810 XML_SetElementDeclHandler(parser, dummy_element_decl_handler);
8811 XML_SetAttlistDeclHandler(parser, dummy_attlist_decl_handler);
8812 XML_SetProcessingInstructionHandler(parser, dummy_pi_handler);
8813 XML_SetCommentHandler(parser, dummy_comment_handler);
8814 XML_SetCdataSectionHandler(parser,
8815 dummy_start_cdata_handler,
8816 dummy_end_cdata_handler);
8817 XML_SetUnparsedEntityDeclHandler(
8818 parser,
8819 dummy_unparsed_entity_decl_handler);
8820 CharData_Init(&storage);
8821 XML_SetUserData(parser, &storage);
8822 XML_SetCharacterDataHandler(parser, accumulate_characters);
8823 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
8824 XML_TRUE) != XML_STATUS_ERROR)
8825 break;
8826 /* See comment in test_alloc_parse_xdecl() */
8827 alloc_teardown();
8828 alloc_setup();
8829 }
8830 if (i == 0)
8831 fail("Default DTD parsed despite allocation failures");
8832 if (i == max_alloc_count)
8833 fail("Default DTD not parsed with maximum alloc count");
8834 CharData_CheckXMLChars(&storage, expected);
8835 if (dummy_handler_flags != (DUMMY_START_DOCTYPE_HANDLER_FLAG |
8836 DUMMY_END_DOCTYPE_HANDLER_FLAG |
8837 DUMMY_ENTITY_DECL_HANDLER_FLAG |
8838 DUMMY_NOTATION_DECL_HANDLER_FLAG |
8839 DUMMY_ELEMENT_DECL_HANDLER_FLAG |
8840 DUMMY_ATTLIST_DECL_HANDLER_FLAG |
8841 DUMMY_COMMENT_HANDLER_FLAG |
8842 DUMMY_PI_HANDLER_FLAG |
8843 DUMMY_START_CDATA_HANDLER_FLAG |
8844 DUMMY_END_CDATA_HANDLER_FLAG |
8845 DUMMY_UNPARSED_ENTITY_DECL_HANDLER_FLAG))
8846 fail("Not all handlers were called");
8847 }
8848 END_TEST
8849
8850 /* Test robustness of XML_SetEncoding() with a failing allocator */
START_TEST(test_alloc_explicit_encoding)8851 START_TEST(test_alloc_explicit_encoding)
8852 {
8853 int i;
8854 const int max_alloc_count = 5;
8855
8856 for (i = 0; i < max_alloc_count; i++) {
8857 allocation_count = i;
8858 if (XML_SetEncoding(parser, XCS("us-ascii")) == XML_STATUS_OK)
8859 break;
8860 }
8861 if (i == 0)
8862 fail("Encoding set despite failing allocator");
8863 else if (i == max_alloc_count)
8864 fail("Encoding not set at max allocation count");
8865 }
8866 END_TEST
8867
8868 /* Test robustness of XML_SetBase against a failing allocator */
START_TEST(test_alloc_set_base)8869 START_TEST(test_alloc_set_base)
8870 {
8871 const XML_Char *new_base = XCS("/local/file/name.xml");
8872 int i;
8873 const int max_alloc_count = 5;
8874
8875 for (i = 0; i < max_alloc_count; i++) {
8876 allocation_count = i;
8877 if (XML_SetBase(parser, new_base) == XML_STATUS_OK)
8878 break;
8879 }
8880 if (i == 0)
8881 fail("Base set despite failing allocator");
8882 else if (i == max_alloc_count)
8883 fail("Base not set with max allocation count");
8884 }
8885 END_TEST
8886
8887 /* Test buffer extension in the face of a duff reallocator */
START_TEST(test_alloc_realloc_buffer)8888 START_TEST(test_alloc_realloc_buffer)
8889 {
8890 const char *text = get_buffer_test_text;
8891 void *buffer;
8892 int i;
8893 const int max_realloc_count = 10;
8894
8895 /* Get a smallish buffer */
8896 for (i = 0; i < max_realloc_count; i++) {
8897 reallocation_count = i;
8898 buffer = XML_GetBuffer(parser, 1536);
8899 if (buffer == NULL)
8900 fail("1.5K buffer reallocation failed");
8901 memcpy(buffer, text, strlen(text));
8902 if (XML_ParseBuffer(parser, (int)strlen(text),
8903 XML_FALSE) == XML_STATUS_OK)
8904 break;
8905 /* See comment in test_alloc_parse_xdecl() */
8906 alloc_teardown();
8907 alloc_setup();
8908 }
8909 reallocation_count = -1;
8910 if (i == 0)
8911 fail("Parse succeeded with no reallocation");
8912 else if (i == max_realloc_count)
8913 fail("Parse failed with max reallocation count");
8914 }
8915 END_TEST
8916
8917 /* Same test for external entity parsers */
8918 static int XMLCALL
external_entity_reallocator(XML_Parser parser,const XML_Char * context,const XML_Char * UNUSED_P (base),const XML_Char * UNUSED_P (systemId),const XML_Char * UNUSED_P (publicId))8919 external_entity_reallocator(XML_Parser parser,
8920 const XML_Char *context,
8921 const XML_Char *UNUSED_P(base),
8922 const XML_Char *UNUSED_P(systemId),
8923 const XML_Char *UNUSED_P(publicId))
8924 {
8925 const char *text = get_buffer_test_text;
8926 XML_Parser ext_parser;
8927 void *buffer;
8928 enum XML_Status status;
8929
8930 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
8931 if (ext_parser == NULL)
8932 fail("Could not create external entity parser");
8933
8934 reallocation_count = (intptr_t)XML_GetUserData(parser);
8935 buffer = XML_GetBuffer(ext_parser, 1536);
8936 if (buffer == NULL)
8937 fail("Buffer allocation failed");
8938 memcpy(buffer, text, strlen(text));
8939 status = XML_ParseBuffer(ext_parser, (int)strlen(text), XML_FALSE);
8940 reallocation_count = -1;
8941 XML_ParserFree(ext_parser);
8942 return (status == XML_STATUS_OK) ? XML_STATUS_OK : XML_STATUS_ERROR;
8943 }
8944
START_TEST(test_alloc_ext_entity_realloc_buffer)8945 START_TEST(test_alloc_ext_entity_realloc_buffer)
8946 {
8947 const char *text =
8948 "<!DOCTYPE doc [\n"
8949 " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n"
8950 "]>\n"
8951 "<doc>&en;</doc>";
8952 int i;
8953 const int max_realloc_count = 10;
8954
8955 for (i = 0; i < max_realloc_count; i++) {
8956 XML_SetExternalEntityRefHandler(parser,
8957 external_entity_reallocator);
8958 XML_SetUserData(parser, (void *)(intptr_t)i);
8959 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
8960 XML_TRUE) == XML_STATUS_OK)
8961 break;
8962 /* See comment in test_alloc_parse_xdecl() */
8963 alloc_teardown();
8964 alloc_setup();
8965 }
8966 if (i == 0)
8967 fail("Succeeded with no reallocations");
8968 if (i == max_realloc_count)
8969 fail("Failed with max reallocations");
8970 }
8971 END_TEST
8972
8973 /* Test elements with many attributes are handled correctly */
START_TEST(test_alloc_realloc_many_attributes)8974 START_TEST(test_alloc_realloc_many_attributes)
8975 {
8976 const char *text =
8977 "<!DOCTYPE doc [\n"
8978 "<!ATTLIST doc za CDATA 'default'>\n"
8979 "<!ATTLIST doc zb CDATA 'def2'>\n"
8980 "<!ATTLIST doc zc CDATA 'def3'>\n"
8981 "]>\n"
8982 "<doc a='1'"
8983 " b='2'"
8984 " c='3'"
8985 " d='4'"
8986 " e='5'"
8987 " f='6'"
8988 " g='7'"
8989 " h='8'"
8990 " i='9'"
8991 " j='10'"
8992 " k='11'"
8993 " l='12'"
8994 " m='13'"
8995 " n='14'"
8996 " p='15'"
8997 " q='16'"
8998 " r='17'"
8999 " s='18'>"
9000 "</doc>";
9001 int i;
9002 const int max_realloc_count = 10;
9003
9004 for (i = 0; i < max_realloc_count; i++) {
9005 reallocation_count = i;
9006 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
9007 XML_TRUE) != XML_STATUS_ERROR)
9008 break;
9009 /* See comment in test_alloc_parse_xdecl() */
9010 alloc_teardown();
9011 alloc_setup();
9012 }
9013 if (i == 0)
9014 fail("Parse succeeded despite no reallocations");
9015 if (i == max_realloc_count)
9016 fail("Parse failed at max reallocations");
9017 }
9018 END_TEST
9019
9020 /* Test handling of a public entity with failing allocator */
START_TEST(test_alloc_public_entity_value)9021 START_TEST(test_alloc_public_entity_value)
9022 {
9023 const char *text =
9024 "<!DOCTYPE doc SYSTEM 'http://example.org/'>\n"
9025 "<doc></doc>\n";
9026 char dtd_text[] =
9027 "<!ELEMENT doc EMPTY>\n"
9028 "<!ENTITY % e1 PUBLIC 'foo' 'bar.ent'>\n"
9029 "<!ENTITY % "
9030 /* Each line is 64 characters */
9031 "ThisIsAStupidlyLongParameterNameIntendedToTriggerPoolGrowth12345"
9032 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9033 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9034 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9035 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9036 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9037 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9038 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9039 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9040 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9041 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9042 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9043 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9044 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9045 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9046 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9047 " '%e1;'>\n"
9048 "%e1;\n";
9049 int i;
9050 const int max_alloc_count = 50;
9051
9052 for (i = 0; i < max_alloc_count; i++) {
9053 allocation_count = i;
9054 dummy_handler_flags = 0;
9055 XML_SetUserData(parser, dtd_text);
9056 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
9057 XML_SetExternalEntityRefHandler(parser, external_entity_public);
9058 /* Provoke a particular code path */
9059 XML_SetEntityDeclHandler(parser, dummy_entity_decl_handler);
9060 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
9061 XML_TRUE) != XML_STATUS_ERROR)
9062 break;
9063 /* See comment in test_alloc_parse_xdecl() */
9064 alloc_teardown();
9065 alloc_setup();
9066 }
9067 if (i == 0)
9068 fail("Parsing worked despite failing allocation");
9069 if (i == max_alloc_count)
9070 fail("Parsing failed at max allocation count");
9071 if (dummy_handler_flags != DUMMY_ENTITY_DECL_HANDLER_FLAG)
9072 fail("Entity declaration handler not called");
9073 }
9074 END_TEST
9075
START_TEST(test_alloc_realloc_subst_public_entity_value)9076 START_TEST(test_alloc_realloc_subst_public_entity_value)
9077 {
9078 const char *text =
9079 "<!DOCTYPE doc SYSTEM 'http://example.org/'>\n"
9080 "<doc></doc>\n";
9081 char dtd_text[] =
9082 "<!ELEMENT doc EMPTY>\n"
9083 "<!ENTITY % "
9084 /* Each line is 64 characters */
9085 "ThisIsAStupidlyLongParameterNameIntendedToTriggerPoolGrowth12345"
9086 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9087 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9088 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9089 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9090 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9091 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9092 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9093 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9094 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9095 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9096 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9097 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9098 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9099 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9100 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9101 " PUBLIC 'foo' 'bar.ent'>\n"
9102 "%ThisIsAStupidlyLongParameterNameIntendedToTriggerPoolGrowth12345"
9103 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9104 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9105 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9106 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9107 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9108 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9109 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9110 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9111 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9112 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9113 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9114 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9115 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9116 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9117 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP;";
9118 int i;
9119 const int max_realloc_count = 10;
9120
9121 for (i = 0; i < max_realloc_count; i++) {
9122 reallocation_count = i;
9123 XML_SetUserData(parser, dtd_text);
9124 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
9125 XML_SetExternalEntityRefHandler(parser, external_entity_public);
9126 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
9127 XML_TRUE) != XML_STATUS_ERROR)
9128 break;
9129 /* See comment in test_alloc_parse_xdecl() */
9130 alloc_teardown();
9131 alloc_setup();
9132 }
9133 if (i == 0)
9134 fail("Parsing worked despite failing reallocation");
9135 if (i == max_realloc_count)
9136 fail("Parsing failed at max reallocation count");
9137 }
9138 END_TEST
9139
START_TEST(test_alloc_parse_public_doctype)9140 START_TEST(test_alloc_parse_public_doctype)
9141 {
9142 const char *text =
9143 "<?xml version='1.0' encoding='utf-8'?>\n"
9144 "<!DOCTYPE doc PUBLIC '"
9145 /* 64 characters per line */
9146 "http://example.com/a/long/enough/name/to/trigger/pool/growth/zz/"
9147 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9148 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9149 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9150 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9151 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9152 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9153 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9154 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9155 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9156 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9157 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9158 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9159 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9160 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9161 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9162 "' 'test'>\n"
9163 "<doc></doc>";
9164 int i;
9165 const int max_alloc_count = 25;
9166
9167 for (i = 0; i < max_alloc_count; i++) {
9168 allocation_count = i;
9169 dummy_handler_flags = 0;
9170 XML_SetDoctypeDeclHandler(parser,
9171 dummy_start_doctype_decl_handler,
9172 dummy_end_doctype_decl_handler);
9173 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
9174 XML_TRUE) != XML_STATUS_ERROR)
9175 break;
9176 /* See comment in test_alloc_parse_xdecl() */
9177 alloc_teardown();
9178 alloc_setup();
9179 }
9180 if (i == 0)
9181 fail("Parse succeeded despite failing allocator");
9182 if (i == max_alloc_count)
9183 fail("Parse failed at maximum allocation count");
9184 if (dummy_handler_flags != (DUMMY_START_DOCTYPE_DECL_HANDLER_FLAG |
9185 DUMMY_END_DOCTYPE_DECL_HANDLER_FLAG))
9186 fail("Doctype handler functions not called");
9187 }
9188 END_TEST
9189
START_TEST(test_alloc_parse_public_doctype_long_name)9190 START_TEST(test_alloc_parse_public_doctype_long_name)
9191 {
9192 const char *text =
9193 "<?xml version='1.0' encoding='utf-8'?>\n"
9194 "<!DOCTYPE doc PUBLIC 'http://example.com/foo' '"
9195 /* 64 characters per line */
9196 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
9197 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
9198 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
9199 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
9200 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
9201 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
9202 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
9203 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
9204 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
9205 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
9206 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
9207 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
9208 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
9209 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
9210 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
9211 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
9212 "'>\n"
9213 "<doc></doc>";
9214 int i;
9215 const int max_alloc_count = 25;
9216
9217 for (i = 0; i < max_alloc_count; i++) {
9218 allocation_count = i;
9219 XML_SetDoctypeDeclHandler(parser,
9220 dummy_start_doctype_decl_handler,
9221 dummy_end_doctype_decl_handler);
9222 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
9223 XML_TRUE) != XML_STATUS_ERROR)
9224 break;
9225 /* See comment in test_alloc_parse_xdecl() */
9226 alloc_teardown();
9227 alloc_setup();
9228 }
9229 if (i == 0)
9230 fail("Parse succeeded despite failing allocator");
9231 if (i == max_alloc_count)
9232 fail("Parse failed at maximum allocation count");
9233 }
9234 END_TEST
9235
9236 static int XMLCALL
external_entity_alloc(XML_Parser parser,const XML_Char * context,const XML_Char * UNUSED_P (base),const XML_Char * UNUSED_P (systemId),const XML_Char * UNUSED_P (publicId))9237 external_entity_alloc(XML_Parser parser,
9238 const XML_Char *context,
9239 const XML_Char *UNUSED_P(base),
9240 const XML_Char *UNUSED_P(systemId),
9241 const XML_Char *UNUSED_P(publicId))
9242 {
9243 const char *text = (const char *)XML_GetUserData(parser);
9244 XML_Parser ext_parser;
9245 int parse_res;
9246
9247 ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
9248 if (ext_parser == NULL)
9249 return XML_STATUS_ERROR;
9250 parse_res = _XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text),
9251 XML_TRUE);
9252 XML_ParserFree(ext_parser);
9253 return parse_res;
9254 }
9255
9256 /* Test foreign DTD handling */
START_TEST(test_alloc_set_foreign_dtd)9257 START_TEST(test_alloc_set_foreign_dtd)
9258 {
9259 const char *text1 =
9260 "<?xml version='1.0' encoding='us-ascii'?>\n"
9261 "<doc>&entity;</doc>";
9262 char text2[] = "<!ELEMENT doc (#PCDATA)*>";
9263 int i;
9264 const int max_alloc_count = 25;
9265
9266 for (i = 0; i < max_alloc_count; i++) {
9267 allocation_count = i;
9268 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
9269 XML_SetUserData(parser, &text2);
9270 XML_SetExternalEntityRefHandler(parser, external_entity_alloc);
9271 if (XML_UseForeignDTD(parser, XML_TRUE) != XML_ERROR_NONE)
9272 fail("Could not set foreign DTD");
9273 if (_XML_Parse_SINGLE_BYTES(parser, text1, (int)strlen(text1),
9274 XML_TRUE) != XML_STATUS_ERROR)
9275 break;
9276 /* See comment in test_alloc_parse_xdecl() */
9277 alloc_teardown();
9278 alloc_setup();
9279 }
9280 if (i == 0)
9281 fail("Parse succeeded despite failing allocator");
9282 if (i == max_alloc_count)
9283 fail("Parse failed at maximum allocation count");
9284 }
9285 END_TEST
9286
9287 /* Test based on ibm/valid/P32/ibm32v04.xml */
START_TEST(test_alloc_attribute_enum_value)9288 START_TEST(test_alloc_attribute_enum_value)
9289 {
9290 const char *text =
9291 "<?xml version='1.0' standalone='no'?>\n"
9292 "<!DOCTYPE animal SYSTEM 'test.dtd'>\n"
9293 "<animal>This is a \n <a/> \n\nyellow tiger</animal>";
9294 char dtd_text[] =
9295 "<!ELEMENT animal (#PCDATA|a)*>\n"
9296 "<!ELEMENT a EMPTY>\n"
9297 "<!ATTLIST animal xml:space (default|preserve) 'preserve'>";
9298 int i;
9299 const int max_alloc_count = 30;
9300
9301 for (i = 0; i < max_alloc_count; i++) {
9302 allocation_count = i;
9303 XML_SetExternalEntityRefHandler(parser, external_entity_alloc);
9304 XML_SetUserData(parser, dtd_text);
9305 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
9306 /* An attribute list handler provokes a different code path */
9307 XML_SetAttlistDeclHandler(parser, dummy_attlist_decl_handler);
9308 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
9309 XML_TRUE) != XML_STATUS_ERROR)
9310 break;
9311 /* See comment in test_alloc_parse_xdecl() */
9312 alloc_teardown();
9313 alloc_setup();
9314 }
9315 if (i == 0)
9316 fail("Parse succeeded despite failing allocator");
9317 if (i == max_alloc_count)
9318 fail("Parse failed at maximum allocation count");
9319 }
9320 END_TEST
9321
9322 /* Test attribute enums sufficient to overflow the string pool */
START_TEST(test_alloc_realloc_attribute_enum_value)9323 START_TEST(test_alloc_realloc_attribute_enum_value)
9324 {
9325 const char *text =
9326 "<?xml version='1.0' standalone='no'?>\n"
9327 "<!DOCTYPE animal SYSTEM 'test.dtd'>\n"
9328 "<animal>This is a yellow tiger</animal>";
9329 /* We wish to define a collection of attribute enums that will
9330 * cause the string pool storing them to have to expand. This
9331 * means more than 1024 bytes, including the parentheses and
9332 * separator bars.
9333 */
9334 char dtd_text[] =
9335 "<!ELEMENT animal (#PCDATA)*>\n"
9336 "<!ATTLIST animal thing "
9337 "(default"
9338 /* Each line is 64 characters */
9339 "|ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9340 "|BBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9341 "|CBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9342 "|DBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9343 "|EBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9344 "|FBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9345 "|GBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9346 "|HBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9347 "|IBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9348 "|JBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9349 "|KBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9350 "|LBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9351 "|MBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9352 "|NBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9353 "|OBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9354 "|PBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO)"
9355 " 'default'>";
9356 int i;
9357 const int max_realloc_count = 10;
9358
9359 for (i = 0; i < max_realloc_count; i++) {
9360 reallocation_count = i;
9361 XML_SetExternalEntityRefHandler(parser, external_entity_alloc);
9362 XML_SetUserData(parser, dtd_text);
9363 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
9364 /* An attribute list handler provokes a different code path */
9365 XML_SetAttlistDeclHandler(parser, dummy_attlist_decl_handler);
9366 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
9367 XML_TRUE) != XML_STATUS_ERROR)
9368 break;
9369 /* See comment in test_alloc_parse_xdecl() */
9370 alloc_teardown();
9371 alloc_setup();
9372 }
9373 if (i == 0)
9374 fail("Parse succeeded despite failing reallocator");
9375 if (i == max_realloc_count)
9376 fail("Parse failed at maximum reallocation count");
9377 }
9378 END_TEST
9379
9380 /* Test attribute enums in a #IMPLIED attribute forcing pool growth */
START_TEST(test_alloc_realloc_implied_attribute)9381 START_TEST(test_alloc_realloc_implied_attribute)
9382 {
9383 /* Forcing this particular code path is a balancing act. The
9384 * addition of the closing parenthesis and terminal NUL must be
9385 * what pushes the string of enums over the 1024-byte limit,
9386 * otherwise a different code path will pick up the realloc.
9387 */
9388 const char *text =
9389 "<!DOCTYPE doc [\n"
9390 "<!ELEMENT doc EMPTY>\n"
9391 "<!ATTLIST doc a "
9392 /* Each line is 64 characters */
9393 "(ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9394 "|BBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9395 "|CBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9396 "|DBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9397 "|EBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9398 "|FBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9399 "|GBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9400 "|HBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9401 "|IBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9402 "|JBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9403 "|KBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9404 "|LBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9405 "|MBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9406 "|NBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9407 "|OBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9408 "|PBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMN)"
9409 " #IMPLIED>\n"
9410 "]><doc/>";
9411 int i;
9412 const int max_realloc_count = 10;
9413
9414 for (i = 0; i < max_realloc_count; i++) {
9415 reallocation_count = i;
9416 XML_SetAttlistDeclHandler(parser, dummy_attlist_decl_handler);
9417 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
9418 XML_TRUE) != XML_STATUS_ERROR)
9419 break;
9420 /* See comment in test_alloc_parse_xdecl() */
9421 alloc_teardown();
9422 alloc_setup();
9423 }
9424 if (i == 0)
9425 fail("Parse succeeded despite failing reallocator");
9426 if (i == max_realloc_count)
9427 fail("Parse failed at maximum reallocation count");
9428 }
9429 END_TEST
9430
9431 /* Test attribute enums in a defaulted attribute forcing pool growth */
START_TEST(test_alloc_realloc_default_attribute)9432 START_TEST(test_alloc_realloc_default_attribute)
9433 {
9434 /* Forcing this particular code path is a balancing act. The
9435 * addition of the closing parenthesis and terminal NUL must be
9436 * what pushes the string of enums over the 1024-byte limit,
9437 * otherwise a different code path will pick up the realloc.
9438 */
9439 const char *text =
9440 "<!DOCTYPE doc [\n"
9441 "<!ELEMENT doc EMPTY>\n"
9442 "<!ATTLIST doc a "
9443 /* Each line is 64 characters */
9444 "(ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9445 "|BBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9446 "|CBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9447 "|DBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9448 "|EBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9449 "|FBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9450 "|GBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9451 "|HBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9452 "|IBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9453 "|JBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9454 "|KBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9455 "|LBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9456 "|MBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9457 "|NBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9458 "|OBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
9459 "|PBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMN)"
9460 " 'ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO'"
9461 ">\n]><doc/>";
9462 int i;
9463 const int max_realloc_count = 10;
9464
9465 for (i = 0; i < max_realloc_count; i++) {
9466 reallocation_count = i;
9467 XML_SetAttlistDeclHandler(parser, dummy_attlist_decl_handler);
9468 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
9469 XML_TRUE) != XML_STATUS_ERROR)
9470 break;
9471 /* See comment in test_alloc_parse_xdecl() */
9472 alloc_teardown();
9473 alloc_setup();
9474 }
9475 if (i == 0)
9476 fail("Parse succeeded despite failing reallocator");
9477 if (i == max_realloc_count)
9478 fail("Parse failed at maximum reallocation count");
9479 }
9480 END_TEST
9481
9482 /* Test long notation name with dodgy allocator */
START_TEST(test_alloc_notation)9483 START_TEST(test_alloc_notation)
9484 {
9485 const char *text =
9486 "<!DOCTYPE doc [\n"
9487 "<!NOTATION "
9488 /* Each line is 64 characters */
9489 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9490 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9491 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9492 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9493 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9494 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9495 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9496 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9497 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9498 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9499 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9500 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9501 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9502 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9503 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9504 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9505 " SYSTEM 'http://example.org/n'>\n"
9506 "<!ENTITY e SYSTEM 'http://example.org/e' NDATA "
9507 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9508 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9509 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9510 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9511 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9512 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9513 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9514 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9515 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9516 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9517 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9518 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9519 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9520 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9521 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9522 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9523 ">\n"
9524 "<!ELEMENT doc EMPTY>\n"
9525 "]>\n<doc/>";
9526 int i;
9527 const int max_alloc_count = 20;
9528
9529 for (i = 0; i < max_alloc_count; i++) {
9530 allocation_count = i;
9531 dummy_handler_flags = 0;
9532 XML_SetNotationDeclHandler(parser, dummy_notation_decl_handler);
9533 XML_SetEntityDeclHandler(parser, dummy_entity_decl_handler);
9534 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
9535 XML_TRUE) != XML_STATUS_ERROR)
9536 break;
9537 /* See comment in test_alloc_parse_xdecl() */
9538 alloc_teardown();
9539 alloc_setup();
9540 }
9541 if (i == 0)
9542 fail("Parse succeeded despite allocation failures");
9543 if (i == max_alloc_count)
9544 fail("Parse failed at maximum allocation count");
9545 if (dummy_handler_flags != (DUMMY_ENTITY_DECL_HANDLER_FLAG |
9546 DUMMY_NOTATION_DECL_HANDLER_FLAG))
9547 fail("Entity declaration handler not called");
9548 }
9549 END_TEST
9550
9551 /* Test public notation with dodgy allocator */
START_TEST(test_alloc_public_notation)9552 START_TEST(test_alloc_public_notation)
9553 {
9554 const char *text =
9555 "<!DOCTYPE doc [\n"
9556 "<!NOTATION note PUBLIC '"
9557 /* 64 characters per line */
9558 "http://example.com/a/long/enough/name/to/trigger/pool/growth/zz/"
9559 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9560 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9561 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9562 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9563 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9564 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9565 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9566 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9567 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9568 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9569 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9570 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9571 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9572 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9573 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9574 "' 'foo'>\n"
9575 "<!ENTITY e SYSTEM 'http://example.com/e' NDATA note>\n"
9576 "<!ELEMENT doc EMPTY>\n"
9577 "]>\n<doc/>";
9578 int i;
9579 const int max_alloc_count = 20;
9580
9581 for (i = 0; i < max_alloc_count; i++) {
9582 allocation_count = i;
9583 dummy_handler_flags = 0;
9584 XML_SetNotationDeclHandler(parser, dummy_notation_decl_handler);
9585 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
9586 XML_TRUE) != XML_STATUS_ERROR)
9587 break;
9588 /* See comment in test_alloc_parse_xdecl() */
9589 alloc_teardown();
9590 alloc_setup();
9591 }
9592 if (i == 0)
9593 fail("Parse succeeded despite allocation failures");
9594 if (i == max_alloc_count)
9595 fail("Parse failed at maximum allocation count");
9596 if (dummy_handler_flags != DUMMY_NOTATION_DECL_HANDLER_FLAG)
9597 fail("Notation handler not called");
9598 }
9599 END_TEST
9600
9601 /* Test public notation with dodgy allocator */
START_TEST(test_alloc_system_notation)9602 START_TEST(test_alloc_system_notation)
9603 {
9604 const char *text =
9605 "<!DOCTYPE doc [\n"
9606 "<!NOTATION note SYSTEM '"
9607 /* 64 characters per line */
9608 "http://example.com/a/long/enough/name/to/trigger/pool/growth/zz/"
9609 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9610 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9611 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9612 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9613 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9614 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9615 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9616 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9617 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9618 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9619 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9620 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9621 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9622 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9623 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
9624 "'>\n"
9625 "<!ENTITY e SYSTEM 'http://example.com/e' NDATA note>\n"
9626 "<!ELEMENT doc EMPTY>\n"
9627 "]>\n<doc/>";
9628 int i;
9629 const int max_alloc_count = 20;
9630
9631 for (i = 0; i < max_alloc_count; i++) {
9632 allocation_count = i;
9633 dummy_handler_flags = 0;
9634 XML_SetNotationDeclHandler(parser, dummy_notation_decl_handler);
9635 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
9636 XML_TRUE) != XML_STATUS_ERROR)
9637 break;
9638 /* See comment in test_alloc_parse_xdecl() */
9639 alloc_teardown();
9640 alloc_setup();
9641 }
9642 if (i == 0)
9643 fail("Parse succeeded despite allocation failures");
9644 if (i == max_alloc_count)
9645 fail("Parse failed at maximum allocation count");
9646 if (dummy_handler_flags != DUMMY_NOTATION_DECL_HANDLER_FLAG)
9647 fail("Notation handler not called");
9648 }
9649 END_TEST
9650
START_TEST(test_alloc_nested_groups)9651 START_TEST(test_alloc_nested_groups)
9652 {
9653 const char *text =
9654 "<!DOCTYPE doc [\n"
9655 "<!ELEMENT doc "
9656 /* Sixteen elements per line */
9657 "(e,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,"
9658 "(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?"
9659 "))))))))))))))))))))))))))))))))>\n"
9660 "<!ELEMENT e EMPTY>"
9661 "]>\n"
9662 "<doc><e/></doc>";
9663 CharData storage;
9664 int i;
9665 const int max_alloc_count = 20;
9666
9667 for (i = 0; i < max_alloc_count; i++) {
9668 allocation_count = i;
9669 CharData_Init(&storage);
9670 XML_SetElementDeclHandler(parser, dummy_element_decl_handler);
9671 XML_SetStartElementHandler(parser, record_element_start_handler);
9672 XML_SetUserData(parser, &storage);
9673 dummy_handler_flags = 0;
9674 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
9675 XML_TRUE) != XML_STATUS_ERROR)
9676 break;
9677 /* See comment in test_alloc_parse_xdecl() */
9678 alloc_teardown();
9679 alloc_setup();
9680 }
9681
9682 if (i == 0)
9683 fail("Parse succeeded despite failing reallocator");
9684 if (i == max_alloc_count)
9685 fail("Parse failed at maximum reallocation count");
9686 CharData_CheckXMLChars(&storage, XCS("doce"));
9687 if (dummy_handler_flags != DUMMY_ELEMENT_DECL_HANDLER_FLAG)
9688 fail("Element handler not fired");
9689 }
9690 END_TEST
9691
START_TEST(test_alloc_realloc_nested_groups)9692 START_TEST(test_alloc_realloc_nested_groups)
9693 {
9694 const char *text =
9695 "<!DOCTYPE doc [\n"
9696 "<!ELEMENT doc "
9697 /* Sixteen elements per line */
9698 "(e,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,"
9699 "(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?"
9700 "))))))))))))))))))))))))))))))))>\n"
9701 "<!ELEMENT e EMPTY>"
9702 "]>\n"
9703 "<doc><e/></doc>";
9704 CharData storage;
9705 int i;
9706 const int max_realloc_count = 10;
9707
9708 for (i = 0; i < max_realloc_count; i++) {
9709 reallocation_count = i;
9710 CharData_Init(&storage);
9711 XML_SetElementDeclHandler(parser, dummy_element_decl_handler);
9712 XML_SetStartElementHandler(parser, record_element_start_handler);
9713 XML_SetUserData(parser, &storage);
9714 dummy_handler_flags = 0;
9715 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
9716 XML_TRUE) != XML_STATUS_ERROR)
9717 break;
9718 /* See comment in test_alloc_parse_xdecl() */
9719 alloc_teardown();
9720 alloc_setup();
9721 }
9722
9723 if (i == 0)
9724 fail("Parse succeeded despite failing reallocator");
9725 if (i == max_realloc_count)
9726 fail("Parse failed at maximum reallocation count");
9727 CharData_CheckXMLChars(&storage, XCS("doce"));
9728 if (dummy_handler_flags != DUMMY_ELEMENT_DECL_HANDLER_FLAG)
9729 fail("Element handler not fired");
9730 }
9731 END_TEST
9732
START_TEST(test_alloc_large_group)9733 START_TEST(test_alloc_large_group)
9734 {
9735 const char *text =
9736 "<!DOCTYPE doc [\n"
9737 "<!ELEMENT doc ("
9738 "a1|a2|a3|a4|a5|a6|a7|a8|"
9739 "b1|b2|b3|b4|b5|b6|b7|b8|"
9740 "c1|c2|c3|c4|c5|c6|c7|c8|"
9741 "d1|d2|d3|d4|d5|d6|d7|d8|"
9742 "e1"
9743 ")+>\n"
9744 "]>\n"
9745 "<doc>\n"
9746 "<a1/>\n"
9747 "</doc>\n";
9748 int i;
9749 const int max_alloc_count = 50;
9750
9751 for (i = 0; i < max_alloc_count; i++) {
9752 allocation_count = i;
9753 XML_SetElementDeclHandler(parser, dummy_element_decl_handler);
9754 dummy_handler_flags = 0;
9755 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
9756 XML_TRUE) != XML_STATUS_ERROR)
9757 break;
9758 /* See comment in test_alloc_parse_xdecl() */
9759 alloc_teardown();
9760 alloc_setup();
9761 }
9762 if (i == 0)
9763 fail("Parse succeeded despite failing allocator");
9764 if (i == max_alloc_count)
9765 fail("Parse failed at maximum allocation count");
9766 if (dummy_handler_flags != DUMMY_ELEMENT_DECL_HANDLER_FLAG)
9767 fail("Element handler flag not raised");
9768 }
9769 END_TEST
9770
START_TEST(test_alloc_realloc_group_choice)9771 START_TEST(test_alloc_realloc_group_choice)
9772 {
9773 const char *text =
9774 "<!DOCTYPE doc [\n"
9775 "<!ELEMENT doc ("
9776 "a1|a2|a3|a4|a5|a6|a7|a8|"
9777 "b1|b2|b3|b4|b5|b6|b7|b8|"
9778 "c1|c2|c3|c4|c5|c6|c7|c8|"
9779 "d1|d2|d3|d4|d5|d6|d7|d8|"
9780 "e1"
9781 ")+>\n"
9782 "]>\n"
9783 "<doc>\n"
9784 "<a1/>\n"
9785 "<b2 attr='foo'>This is a foo</b2>\n"
9786 "<c3></c3>\n"
9787 "</doc>\n";
9788 int i;
9789 const int max_realloc_count = 10;
9790
9791 for (i = 0; i < max_realloc_count; i++) {
9792 reallocation_count = i;
9793 XML_SetElementDeclHandler(parser, dummy_element_decl_handler);
9794 dummy_handler_flags = 0;
9795 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
9796 XML_TRUE) != XML_STATUS_ERROR)
9797 break;
9798 /* See comment in test_alloc_parse_xdecl() */
9799 alloc_teardown();
9800 alloc_setup();
9801 }
9802 if (i == 0)
9803 fail("Parse succeeded despite failing reallocator");
9804 if (i == max_realloc_count)
9805 fail("Parse failed at maximum reallocation count");
9806 if (dummy_handler_flags != DUMMY_ELEMENT_DECL_HANDLER_FLAG)
9807 fail("Element handler flag not raised");
9808 }
9809 END_TEST
9810
START_TEST(test_alloc_pi_in_epilog)9811 START_TEST(test_alloc_pi_in_epilog)
9812 {
9813 const char *text =
9814 "<doc></doc>\n"
9815 "<?pi in epilog?>";
9816 int i;
9817 const int max_alloc_count = 15;
9818
9819 for (i = 0; i < max_alloc_count; i++) {
9820 allocation_count = i;
9821 XML_SetProcessingInstructionHandler(parser, dummy_pi_handler);
9822 dummy_handler_flags = 0;
9823 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
9824 XML_TRUE) != XML_STATUS_ERROR)
9825 break;
9826 /* See comment in test_alloc_parse_xdecl() */
9827 alloc_teardown();
9828 alloc_setup();
9829 }
9830 if (i == 0)
9831 fail("Parse completed despite failing allocator");
9832 if (i == max_alloc_count)
9833 fail("Parse failed at maximum allocation count");
9834 if (dummy_handler_flags != DUMMY_PI_HANDLER_FLAG)
9835 fail("Processing instruction handler not invoked");
9836 }
9837 END_TEST
9838
START_TEST(test_alloc_comment_in_epilog)9839 START_TEST(test_alloc_comment_in_epilog)
9840 {
9841 const char *text =
9842 "<doc></doc>\n"
9843 "<!-- comment in epilog -->";
9844 int i;
9845 const int max_alloc_count = 15;
9846
9847 for (i = 0; i < max_alloc_count; i++) {
9848 allocation_count = i;
9849 XML_SetCommentHandler(parser, dummy_comment_handler);
9850 dummy_handler_flags = 0;
9851 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
9852 XML_TRUE) != XML_STATUS_ERROR)
9853 break;
9854 /* See comment in test_alloc_parse_xdecl() */
9855 alloc_teardown();
9856 alloc_setup();
9857 }
9858 if (i == 0)
9859 fail("Parse completed despite failing allocator");
9860 if (i == max_alloc_count)
9861 fail("Parse failed at maximum allocation count");
9862 if (dummy_handler_flags != DUMMY_COMMENT_HANDLER_FLAG)
9863 fail("Processing instruction handler not invoked");
9864 }
9865 END_TEST
9866
START_TEST(test_alloc_realloc_long_attribute_value)9867 START_TEST(test_alloc_realloc_long_attribute_value)
9868 {
9869 const char *text =
9870 "<!DOCTYPE doc [<!ENTITY foo '"
9871 /* Each line is 64 characters */
9872 "This entity will be substituted as an attribute value, and is "
9873 "calculated to be exactly long enough that the terminating NUL "
9874 "that the library adds internally will trigger the string pool to"
9875 "grow. GHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9876 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9877 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9878 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9879 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9880 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9881 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9882 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9883 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9884 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9885 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9886 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9887 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9888 "'>]>\n"
9889 "<doc a='&foo;'></doc>";
9890 int i;
9891 const int max_realloc_count = 10;
9892
9893 for (i = 0; i < max_realloc_count; i++) {
9894 reallocation_count = i;
9895 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
9896 XML_TRUE) != XML_STATUS_ERROR)
9897 break;
9898 /* See comment in test_alloc_parse_xdecl() */
9899 alloc_teardown();
9900 alloc_setup();
9901 }
9902 if (i == 0)
9903 fail("Parse succeeded despite failing reallocator");
9904 if (i == max_realloc_count)
9905 fail("Parse failed at maximum reallocation count");
9906 }
9907 END_TEST
9908
START_TEST(test_alloc_attribute_whitespace)9909 START_TEST(test_alloc_attribute_whitespace)
9910 {
9911 const char *text = "<doc a=' '></doc>";
9912 int i;
9913 const int max_alloc_count = 15;
9914
9915 for (i = 0; i < max_alloc_count; i++) {
9916 allocation_count = i;
9917 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
9918 XML_TRUE) != XML_STATUS_ERROR)
9919 break;
9920 /* See comment in test_alloc_parse_xdecl() */
9921 alloc_teardown();
9922 alloc_setup();
9923 }
9924 if (i == 0)
9925 fail("Parse succeeded despite failing allocator");
9926 if (i == max_alloc_count)
9927 fail("Parse failed at maximum allocation count");
9928 }
9929 END_TEST
9930
START_TEST(test_alloc_attribute_predefined_entity)9931 START_TEST(test_alloc_attribute_predefined_entity)
9932 {
9933 const char *text = "<doc a='&'></doc>";
9934 int i;
9935 const int max_alloc_count = 15;
9936
9937 for (i = 0; i < max_alloc_count; i++) {
9938 allocation_count = i;
9939 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
9940 XML_TRUE) != XML_STATUS_ERROR)
9941 break;
9942 /* See comment in test_alloc_parse_xdecl() */
9943 alloc_teardown();
9944 alloc_setup();
9945 }
9946 if (i == 0)
9947 fail("Parse succeeded despite failing allocator");
9948 if (i == max_alloc_count)
9949 fail("Parse failed at maximum allocation count");
9950 }
9951 END_TEST
9952
9953 /* Test that a character reference at the end of a suitably long
9954 * default value for an attribute can trigger pool growth, and recovers
9955 * if the allocator fails on it.
9956 */
START_TEST(test_alloc_long_attr_default_with_char_ref)9957 START_TEST(test_alloc_long_attr_default_with_char_ref)
9958 {
9959 const char *text =
9960 "<!DOCTYPE doc [<!ATTLIST doc a CDATA '"
9961 /* 64 characters per line */
9962 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9963 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9964 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9965 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9966 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9967 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9968 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9969 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9970 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9971 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9972 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9973 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9974 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9975 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9976 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
9977 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHI"
9978 "1'>]>\n"
9979 "<doc/>";
9980 int i;
9981 const int max_alloc_count = 20;
9982
9983 for (i = 0; i < max_alloc_count; i++) {
9984 allocation_count = i;
9985 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
9986 XML_TRUE) != XML_STATUS_ERROR)
9987 break;
9988 /* See comment in test_alloc_parse_xdecl() */
9989 alloc_teardown();
9990 alloc_setup();
9991 }
9992 if (i == 0)
9993 fail("Parse succeeded despite failing allocator");
9994 if (i == max_alloc_count)
9995 fail("Parse failed at maximum allocation count");
9996 }
9997 END_TEST
9998
9999 /* Test that a long character reference substitution triggers a pool
10000 * expansion correctly for an attribute value.
10001 */
START_TEST(test_alloc_long_attr_value)10002 START_TEST(test_alloc_long_attr_value)
10003 {
10004 const char *text =
10005 "<!DOCTYPE test [<!ENTITY foo '\n"
10006 /* 64 characters per line */
10007 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10008 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10009 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10010 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10011 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10012 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10013 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10014 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10015 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10016 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10017 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10018 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10019 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10020 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10021 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10022 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10023 "'>]>\n"
10024 "<test a='&foo;'/>";
10025 int i;
10026 const int max_alloc_count = 25;
10027
10028 for (i = 0; i < max_alloc_count; i++) {
10029 allocation_count = i;
10030 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
10031 XML_TRUE) != XML_STATUS_ERROR)
10032 break;
10033 /* See comment in test_alloc_parse_xdecl() */
10034 alloc_teardown();
10035 alloc_setup();
10036 }
10037 if (i == 0)
10038 fail("Parse succeeded despite failing allocator");
10039 if (i == max_alloc_count)
10040 fail("Parse failed at maximum allocation count");
10041 }
10042 END_TEST
10043
10044 /* Test that an error in a nested parameter entity substitution is
10045 * handled correctly. It seems unlikely that the code path being
10046 * exercised can be reached purely by carefully crafted XML, but an
10047 * allocation error in the right place will definitely do it.
10048 */
START_TEST(test_alloc_nested_entities)10049 START_TEST(test_alloc_nested_entities)
10050 {
10051 const char *text =
10052 "<!DOCTYPE doc SYSTEM 'http://example.org/one.ent'>\n"
10053 "<doc />";
10054 ExtFaults test_data = {
10055 "<!ENTITY % pe1 '"
10056 /* 64 characters per line */
10057 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10058 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10059 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10060 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10061 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10062 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10063 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10064 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10065 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10066 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10067 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10068 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10069 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10070 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10071 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10072 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10073 "'>\n"
10074 "<!ENTITY % pe2 '%pe1;'>\n"
10075 "%pe2;",
10076 "Memory Fail not faulted",
10077 NULL,
10078 XML_ERROR_NO_MEMORY
10079 };
10080
10081 /* Causes an allocation error in a nested storeEntityValue() */
10082 allocation_count = 12;
10083 XML_SetUserData(parser, &test_data);
10084 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
10085 XML_SetExternalEntityRefHandler(parser, external_entity_faulter);
10086 expect_failure(text, XML_ERROR_EXTERNAL_ENTITY_HANDLING,
10087 "Entity allocation failure not noted");
10088 }
10089 END_TEST
10090
START_TEST(test_alloc_realloc_param_entity_newline)10091 START_TEST(test_alloc_realloc_param_entity_newline)
10092 {
10093 const char *text =
10094 "<!DOCTYPE doc SYSTEM 'http://example.org/'>\n"
10095 "<doc/>";
10096 char dtd_text[] =
10097 "<!ENTITY % pe '<!ATTLIST doc att CDATA \""
10098 /* 64 characters per line */
10099 "This default value is carefully crafted so that the carriage "
10100 "return right at the end of the entity string causes an internal "
10101 "string pool to have to grow. This allows us to test the alloc "
10102 "failure path from that point. OPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10103 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10104 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10105 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10106 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10107 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10108 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10109 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10110 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10111 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10112 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10113 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10114 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDE"
10115 "\">\n'>"
10116 "%pe;\n";
10117 int i;
10118 const int max_realloc_count = 5;
10119
10120 for (i = 0; i < max_realloc_count; i++) {
10121 reallocation_count = i;
10122 XML_SetUserData(parser, dtd_text);
10123 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
10124 XML_SetExternalEntityRefHandler(parser, external_entity_alloc);
10125 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
10126 XML_TRUE) != XML_STATUS_ERROR)
10127 break;
10128 /* See comment in test_alloc_parse_xdecl() */
10129 alloc_teardown();
10130 alloc_setup();
10131 }
10132 if (i == 0)
10133 fail("Parse succeeded despite failing reallocator");
10134 if (i == max_realloc_count)
10135 fail("Parse failed at maximum reallocation count");
10136 }
10137 END_TEST
10138
START_TEST(test_alloc_realloc_ce_extends_pe)10139 START_TEST(test_alloc_realloc_ce_extends_pe)
10140 {
10141 const char *text =
10142 "<!DOCTYPE doc SYSTEM 'http://example.org/'>\n"
10143 "<doc/>";
10144 char dtd_text[] =
10145 "<!ENTITY % pe '<!ATTLIST doc att CDATA \""
10146 /* 64 characters per line */
10147 "This default value is carefully crafted so that the character "
10148 "entity at the end causes an internal string pool to have to "
10149 "grow. This allows us to test the allocation failure path from "
10150 "that point onwards. EFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10151 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10152 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10153 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10154 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10155 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10156 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10157 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10158 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10159 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10160 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10161 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
10162 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGQ"
10163 "\">\n'>"
10164 "%pe;\n";
10165 int i;
10166 const int max_realloc_count = 5;
10167
10168 for (i = 0; i < max_realloc_count; i++) {
10169 reallocation_count = i;
10170 XML_SetUserData(parser, dtd_text);
10171 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
10172 XML_SetExternalEntityRefHandler(parser, external_entity_alloc);
10173 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
10174 XML_TRUE) != XML_STATUS_ERROR)
10175 break;
10176 /* See comment in test_alloc_parse_xdecl() */
10177 alloc_teardown();
10178 alloc_setup();
10179 }
10180 if (i == 0)
10181 fail("Parse succeeded despite failing reallocator");
10182 if (i == max_realloc_count)
10183 fail("Parse failed at maximum reallocation count");
10184 }
10185 END_TEST
10186
START_TEST(test_alloc_realloc_attributes)10187 START_TEST(test_alloc_realloc_attributes)
10188 {
10189 const char *text =
10190 "<!DOCTYPE doc [\n"
10191 " <!ATTLIST doc\n"
10192 " a1 (a|b|c) 'a'\n"
10193 " a2 (foo|bar) #IMPLIED\n"
10194 " a3 NMTOKEN #IMPLIED\n"
10195 " a4 NMTOKENS #IMPLIED\n"
10196 " a5 ID #IMPLIED\n"
10197 " a6 IDREF #IMPLIED\n"
10198 " a7 IDREFS #IMPLIED\n"
10199 " a8 ENTITY #IMPLIED\n"
10200 " a9 ENTITIES #IMPLIED\n"
10201 " a10 CDATA #IMPLIED\n"
10202 " >]>\n"
10203 "<doc>wombat</doc>\n";
10204 int i;
10205 const int max_realloc_count = 5;
10206
10207 for (i = 0; i < max_realloc_count; i++) {
10208 reallocation_count = i;
10209 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
10210 XML_TRUE) != XML_STATUS_ERROR)
10211 break;
10212 /* See comment in test_alloc_parse_xdecl() */
10213 alloc_teardown();
10214 alloc_setup();
10215 }
10216
10217 if (i == 0)
10218 fail("Parse succeeded despite failing reallocator");
10219 if (i == max_realloc_count)
10220 fail("Parse failed at maximum reallocation count");
10221 }
10222 END_TEST
10223
START_TEST(test_alloc_long_doc_name)10224 START_TEST(test_alloc_long_doc_name)
10225 {
10226 const char *text =
10227 /* 64 characters per line */
10228 "<LongRootElementNameThatWillCauseTheNextAllocationToExpandTheStr"
10229 "ingPoolForTheDTDQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10230 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10231 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10232 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10233 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10234 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10235 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10236 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10237 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10238 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10239 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10240 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10241 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10242 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10243 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10244 " a='1'/>";
10245 int i;
10246 const int max_alloc_count = 20;
10247
10248 for (i = 0; i < max_alloc_count; i++) {
10249 allocation_count = i;
10250 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
10251 XML_TRUE) != XML_STATUS_ERROR)
10252 break;
10253 /* See comment in test_alloc_parse_xdecl() */
10254 alloc_teardown();
10255 alloc_setup();
10256 }
10257 if (i == 0)
10258 fail("Parsing worked despite failing reallocations");
10259 else if (i == max_alloc_count)
10260 fail("Parsing failed even at max reallocation count");
10261 }
10262 END_TEST
10263
START_TEST(test_alloc_long_base)10264 START_TEST(test_alloc_long_base)
10265 {
10266 const char *text =
10267 "<!DOCTYPE doc [\n"
10268 " <!ENTITY e SYSTEM 'foo'>\n"
10269 "]>\n"
10270 "<doc>&e;</doc>";
10271 char entity_text[] = "Hello world";
10272 const XML_Char *base =
10273 /* 64 characters per line */
10274 XCS("LongBaseURI/that/will/overflow/an/internal/buffer/and/cause/it/t")
10275 XCS("o/have/to/grow/PQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
10276 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
10277 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
10278 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
10279 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
10280 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
10281 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
10282 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
10283 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
10284 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
10285 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
10286 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
10287 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
10288 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
10289 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/");
10290 int i;
10291 const int max_alloc_count = 25;
10292
10293 for (i = 0; i < max_alloc_count; i++) {
10294 allocation_count = i;
10295 XML_SetUserData(parser, entity_text);
10296 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
10297 XML_SetExternalEntityRefHandler(parser, external_entity_alloc);
10298 if (XML_SetBase(parser, base) == XML_STATUS_ERROR) {
10299 XML_ParserReset(parser, NULL);
10300 continue;
10301 }
10302 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
10303 XML_TRUE) != XML_STATUS_ERROR)
10304 break;
10305 /* See comment in test_alloc_parse_xdecl() */
10306 alloc_teardown();
10307 alloc_setup();
10308 }
10309 if (i == 0)
10310 fail("Parsing worked despite failing allocations");
10311 else if (i == max_alloc_count)
10312 fail("Parsing failed even at max allocation count");
10313 }
10314 END_TEST
10315
START_TEST(test_alloc_long_public_id)10316 START_TEST(test_alloc_long_public_id)
10317 {
10318 const char *text =
10319 "<!DOCTYPE doc [\n"
10320 " <!ENTITY e PUBLIC '"
10321 /* 64 characters per line */
10322 "LongPublicIDThatShouldResultInAnInternalStringPoolGrowingAtASpec"
10323 "ificMomentKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10324 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10325 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10326 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10327 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10328 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10329 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10330 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10331 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10332 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10333 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10334 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10335 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10336 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10337 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10338 "' 'bar'>\n"
10339 "]>\n"
10340 "<doc>&e;</doc>";
10341 char entity_text[] = "Hello world";
10342 int i;
10343 const int max_alloc_count = 40;
10344
10345 for (i = 0; i < max_alloc_count; i++) {
10346 allocation_count = i;
10347 XML_SetUserData(parser, entity_text);
10348 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
10349 XML_SetExternalEntityRefHandler(parser, external_entity_alloc);
10350 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
10351 XML_TRUE) != XML_STATUS_ERROR)
10352 break;
10353 /* See comment in test_alloc_parse_xdecl() */
10354 alloc_teardown();
10355 alloc_setup();
10356 }
10357 if (i == 0)
10358 fail("Parsing worked despite failing allocations");
10359 else if (i == max_alloc_count)
10360 fail("Parsing failed even at max allocation count");
10361 }
10362 END_TEST
10363
START_TEST(test_alloc_long_entity_value)10364 START_TEST(test_alloc_long_entity_value)
10365 {
10366 const char *text =
10367 "<!DOCTYPE doc [\n"
10368 " <!ENTITY e1 '"
10369 /* 64 characters per line */
10370 "Long entity value that should provoke a string pool to grow whil"
10371 "e setting up to parse the external entity below. xyz0123456789AB"
10372 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10373 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10374 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10375 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10376 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10377 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10378 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10379 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10380 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10381 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10382 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10383 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10384 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10385 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10386 "'>\n"
10387 " <!ENTITY e2 SYSTEM 'bar'>\n"
10388 "]>\n"
10389 "<doc>&e2;</doc>";
10390 char entity_text[] = "Hello world";
10391 int i;
10392 const int max_alloc_count = 40;
10393
10394 for (i = 0; i < max_alloc_count; i++) {
10395 allocation_count = i;
10396 XML_SetUserData(parser, entity_text);
10397 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
10398 XML_SetExternalEntityRefHandler(parser, external_entity_alloc);
10399 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
10400 XML_TRUE) != XML_STATUS_ERROR)
10401 break;
10402 /* See comment in test_alloc_parse_xdecl() */
10403 alloc_teardown();
10404 alloc_setup();
10405 }
10406 if (i == 0)
10407 fail("Parsing worked despite failing allocations");
10408 else if (i == max_alloc_count)
10409 fail("Parsing failed even at max allocation count");
10410 }
10411 END_TEST
10412
START_TEST(test_alloc_long_notation)10413 START_TEST(test_alloc_long_notation)
10414 {
10415 const char *text =
10416 "<!DOCTYPE doc [\n"
10417 " <!NOTATION note SYSTEM '"
10418 /* 64 characters per line */
10419 "ALongNotationNameThatShouldProvokeStringPoolGrowthWhileCallingAn"
10420 "ExternalEntityParserUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10421 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10422 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10423 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10424 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10425 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10426 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10427 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10428 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10429 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10430 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10431 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10432 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10433 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10434 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10435 "'>\n"
10436 " <!ENTITY e1 SYSTEM 'foo' NDATA "
10437 /* 64 characters per line */
10438 "ALongNotationNameThatShouldProvokeStringPoolGrowthWhileCallingAn"
10439 "ExternalEntityParserUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10440 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10441 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10442 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10443 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10444 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10445 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10446 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10447 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10448 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10449 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10450 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10451 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10452 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10453 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
10454 ">\n"
10455 " <!ENTITY e2 SYSTEM 'bar'>\n"
10456 "]>\n"
10457 "<doc>&e2;</doc>";
10458 ExtOption options[] = {
10459 { XCS("foo"), "Entity Foo" },
10460 { XCS("bar"), "Entity Bar" },
10461 { NULL, NULL }
10462 };
10463 int i;
10464 const int max_alloc_count = 40;
10465
10466 for (i = 0; i < max_alloc_count; i++) {
10467 allocation_count = i;
10468 XML_SetUserData(parser, options);
10469 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
10470 XML_SetExternalEntityRefHandler(parser, external_entity_optioner);
10471 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
10472 XML_TRUE) != XML_STATUS_ERROR)
10473 break;
10474
10475 /* See comment in test_alloc_parse_xdecl() */
10476 alloc_teardown();
10477 alloc_setup();
10478 }
10479 if (i == 0)
10480 fail("Parsing worked despite failing allocations");
10481 else if (i == max_alloc_count)
10482 fail("Parsing failed even at max allocation count");
10483 }
10484 END_TEST
10485
10486
10487 static void
nsalloc_setup(void)10488 nsalloc_setup(void)
10489 {
10490 XML_Memory_Handling_Suite memsuite = {
10491 duff_allocator,
10492 duff_reallocator,
10493 free
10494 };
10495 XML_Char ns_sep[2] = { ' ', '\0' };
10496
10497 /* Ensure the parser creation will go through */
10498 allocation_count = ALLOC_ALWAYS_SUCCEED;
10499 reallocation_count = REALLOC_ALWAYS_SUCCEED;
10500 parser = XML_ParserCreate_MM(NULL, &memsuite, ns_sep);
10501 if (parser == NULL)
10502 fail("Parser not created");
10503 }
10504
10505 static void
nsalloc_teardown(void)10506 nsalloc_teardown(void)
10507 {
10508 basic_teardown();
10509 }
10510
10511
10512 /* Test the effects of allocation failure in simple namespace parsing.
10513 * Based on test_ns_default_with_empty_uri()
10514 */
START_TEST(test_nsalloc_xmlns)10515 START_TEST(test_nsalloc_xmlns)
10516 {
10517 const char *text =
10518 "<doc xmlns='http://example.org/'>\n"
10519 " <e xmlns=''/>\n"
10520 "</doc>";
10521 unsigned int i;
10522 const unsigned int max_alloc_count = 30;
10523
10524 for (i = 0; i < max_alloc_count; i++) {
10525 allocation_count = i;
10526 /* Exercise more code paths with a default handler */
10527 XML_SetDefaultHandler(parser, dummy_default_handler);
10528 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
10529 XML_TRUE) != XML_STATUS_ERROR)
10530 break;
10531 /* Resetting the parser is insufficient, because some memory
10532 * allocations are cached within the parser. Instead we use
10533 * the teardown and setup routines to ensure that we have the
10534 * right sort of parser back in our hands.
10535 */
10536 nsalloc_teardown();
10537 nsalloc_setup();
10538 }
10539 if (i == 0)
10540 fail("Parsing worked despite failing allocations");
10541 else if (i == max_alloc_count)
10542 fail("Parsing failed even at maximum allocation count");
10543 }
10544 END_TEST
10545
10546 /* Test XML_ParseBuffer interface with namespace and a dicky allocator */
START_TEST(test_nsalloc_parse_buffer)10547 START_TEST(test_nsalloc_parse_buffer)
10548 {
10549 const char *text = "<doc>Hello</doc>";
10550 void *buffer;
10551
10552 /* Try a parse before the start of the world */
10553 /* (Exercises new code path) */
10554 allocation_count = 0;
10555 if (XML_ParseBuffer(parser, 0, XML_FALSE) != XML_STATUS_ERROR)
10556 fail("Pre-init XML_ParseBuffer not faulted");
10557 if (XML_GetErrorCode(parser) != XML_ERROR_NO_MEMORY)
10558 fail("Pre-init XML_ParseBuffer faulted for wrong reason");
10559
10560 /* Now with actual memory allocation */
10561 allocation_count = ALLOC_ALWAYS_SUCCEED;
10562 if (XML_ParseBuffer(parser, 0, XML_FALSE) != XML_STATUS_OK)
10563 xml_failure(parser);
10564
10565 /* Check that resuming an unsuspended parser is faulted */
10566 if (XML_ResumeParser(parser) != XML_STATUS_ERROR)
10567 fail("Resuming unsuspended parser not faulted");
10568 if (XML_GetErrorCode(parser) != XML_ERROR_NOT_SUSPENDED)
10569 xml_failure(parser);
10570
10571 /* Get the parser into suspended state */
10572 XML_SetCharacterDataHandler(parser, clearing_aborting_character_handler);
10573 resumable = XML_TRUE;
10574 buffer = XML_GetBuffer(parser, (int)strlen(text));
10575 if (buffer == NULL)
10576 fail("Could not acquire parse buffer");
10577 memcpy(buffer, text, strlen(text));
10578 if (XML_ParseBuffer(parser, (int)strlen(text),
10579 XML_TRUE) != XML_STATUS_SUSPENDED)
10580 xml_failure(parser);
10581 if (XML_GetErrorCode(parser) != XML_ERROR_NONE)
10582 xml_failure(parser);
10583 if (XML_ParseBuffer(parser, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR)
10584 fail("Suspended XML_ParseBuffer not faulted");
10585 if (XML_GetErrorCode(parser) != XML_ERROR_SUSPENDED)
10586 xml_failure(parser);
10587 if (XML_GetBuffer(parser, (int)strlen(text)) != NULL)
10588 fail("Suspended XML_GetBuffer not faulted");
10589
10590 /* Get it going again and complete the world */
10591 XML_SetCharacterDataHandler(parser, NULL);
10592 if (XML_ResumeParser(parser) != XML_STATUS_OK)
10593 xml_failure(parser);
10594 if (XML_ParseBuffer(parser, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR)
10595 fail("Post-finishing XML_ParseBuffer not faulted");
10596 if (XML_GetErrorCode(parser) != XML_ERROR_FINISHED)
10597 xml_failure(parser);
10598 if (XML_GetBuffer(parser, (int)strlen(text)) != NULL)
10599 fail("Post-finishing XML_GetBuffer not faulted");
10600 }
10601 END_TEST
10602
10603 /* Check handling of long prefix names (pool growth) */
START_TEST(test_nsalloc_long_prefix)10604 START_TEST(test_nsalloc_long_prefix)
10605 {
10606 const char *text =
10607 "<"
10608 /* 64 characters per line */
10609 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10610 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10611 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10612 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10613 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10614 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10615 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10616 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10617 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10618 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10619 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10620 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10621 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10622 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10623 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10624 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10625 ":foo xmlns:"
10626 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10627 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10628 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10629 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10630 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10631 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10632 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10633 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10634 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10635 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10636 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10637 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10638 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10639 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10640 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10641 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10642 "='http://example.org/'>"
10643 "</"
10644 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10645 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10646 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10647 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10648 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10649 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10650 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10651 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10652 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10653 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10654 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10655 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10656 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10657 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10658 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10659 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10660 ":foo>";
10661 int i;
10662 const int max_alloc_count = 40;
10663
10664 for (i = 0; i < max_alloc_count; i++) {
10665 allocation_count = i;
10666 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
10667 XML_TRUE) != XML_STATUS_ERROR)
10668 break;
10669 /* See comment in test_nsalloc_xmlns() */
10670 nsalloc_teardown();
10671 nsalloc_setup();
10672 }
10673 if (i == 0)
10674 fail("Parsing worked despite failing allocations");
10675 else if (i == max_alloc_count)
10676 fail("Parsing failed even at max allocation count");
10677 }
10678 END_TEST
10679
10680 /* Check handling of long uri names (pool growth) */
START_TEST(test_nsalloc_long_uri)10681 START_TEST(test_nsalloc_long_uri)
10682 {
10683 const char *text =
10684 "<foo:e xmlns:foo='http://example.org/"
10685 /* 64 characters per line */
10686 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
10687 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
10688 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
10689 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
10690 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
10691 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
10692 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
10693 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
10694 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
10695 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
10696 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
10697 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
10698 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
10699 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
10700 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
10701 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
10702 "' bar:a='12'\n"
10703 "xmlns:bar='http://example.org/"
10704 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
10705 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
10706 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
10707 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
10708 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
10709 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
10710 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
10711 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
10712 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
10713 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
10714 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
10715 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
10716 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
10717 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
10718 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
10719 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
10720 "'>"
10721 "</foo:e>";
10722 int i;
10723 const int max_alloc_count = 40;
10724
10725 for (i = 0; i < max_alloc_count; i++) {
10726 allocation_count = i;
10727 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
10728 XML_TRUE) != XML_STATUS_ERROR)
10729 break;
10730 /* See comment in test_nsalloc_xmlns() */
10731 nsalloc_teardown();
10732 nsalloc_setup();
10733 }
10734 if (i == 0)
10735 fail("Parsing worked despite failing allocations");
10736 else if (i == max_alloc_count)
10737 fail("Parsing failed even at max allocation count");
10738 }
10739 END_TEST
10740
10741 /* Test handling of long attribute names with prefixes */
START_TEST(test_nsalloc_long_attr)10742 START_TEST(test_nsalloc_long_attr)
10743 {
10744 const char *text =
10745 "<foo:e xmlns:foo='http://example.org/' bar:"
10746 /* 64 characters per line */
10747 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10748 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10749 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10750 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10751 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10752 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10753 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10754 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10755 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10756 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10757 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10758 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10759 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10760 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10761 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10762 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10763 "='12'\n"
10764 "xmlns:bar='http://example.org/'>"
10765 "</foo:e>";
10766 int i;
10767 const int max_alloc_count = 40;
10768
10769 for (i = 0; i < max_alloc_count; i++) {
10770 allocation_count = i;
10771 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
10772 XML_TRUE) != XML_STATUS_ERROR)
10773 break;
10774 /* See comment in test_nsalloc_xmlns() */
10775 nsalloc_teardown();
10776 nsalloc_setup();
10777 }
10778 if (i == 0)
10779 fail("Parsing worked despite failing allocations");
10780 else if (i == max_alloc_count)
10781 fail("Parsing failed even at max allocation count");
10782 }
10783 END_TEST
10784
10785 /* Test handling of an attribute name with a long namespace prefix */
START_TEST(test_nsalloc_long_attr_prefix)10786 START_TEST(test_nsalloc_long_attr_prefix)
10787 {
10788 const char *text =
10789 "<foo:e xmlns:foo='http://example.org/' "
10790 /* 64 characters per line */
10791 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10792 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10793 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10794 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10795 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10796 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10797 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10798 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10799 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10800 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10801 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10802 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10803 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10804 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10805 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10806 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10807 ":a='12'\n"
10808 "xmlns:"
10809 /* 64 characters per line */
10810 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10811 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10812 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10813 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10814 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10815 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10816 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10817 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10818 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10819 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10820 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10821 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10822 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10823 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10824 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10825 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10826 "='http://example.org/'>"
10827 "</foo:e>";
10828 const XML_Char *elemstr[] = {
10829 XCS("http://example.org/ e foo"),
10830 XCS("http://example.org/ a ")
10831 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ")
10832 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ")
10833 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ")
10834 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ")
10835 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ")
10836 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ")
10837 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ")
10838 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ")
10839 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ")
10840 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ")
10841 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ")
10842 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ")
10843 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ")
10844 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ")
10845 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ")
10846 XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ")
10847 };
10848 int i;
10849 const int max_alloc_count = 40;
10850
10851 for (i = 0; i < max_alloc_count; i++) {
10852 allocation_count = i;
10853 XML_SetReturnNSTriplet(parser, XML_TRUE);
10854 XML_SetUserData(parser, (void *)elemstr);
10855 XML_SetElementHandler(parser,
10856 triplet_start_checker,
10857 triplet_end_checker);
10858 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
10859 XML_TRUE) != XML_STATUS_ERROR)
10860 break;
10861 /* See comment in test_nsalloc_xmlns() */
10862 nsalloc_teardown();
10863 nsalloc_setup();
10864 }
10865 if (i == 0)
10866 fail("Parsing worked despite failing allocations");
10867 else if (i == max_alloc_count)
10868 fail("Parsing failed even at max allocation count");
10869 }
10870 END_TEST
10871
10872 /* Test attribute handling in the face of a dodgy reallocator */
START_TEST(test_nsalloc_realloc_attributes)10873 START_TEST(test_nsalloc_realloc_attributes)
10874 {
10875 const char *text =
10876 "<foo:e xmlns:foo='http://example.org/' bar:a='12'\n"
10877 " xmlns:bar='http://example.org/'>"
10878 "</foo:e>";
10879 int i;
10880 const int max_realloc_count = 10;
10881
10882 for (i = 0; i < max_realloc_count; i++) {
10883 reallocation_count = i;
10884 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
10885 XML_TRUE) != XML_STATUS_ERROR)
10886 break;
10887 /* See comment in test_nsalloc_xmlns() */
10888 nsalloc_teardown();
10889 nsalloc_setup();
10890 }
10891 if (i == 0)
10892 fail("Parsing worked despite failing reallocations");
10893 else if (i == max_realloc_count)
10894 fail("Parsing failed at max reallocation count");
10895 }
10896 END_TEST
10897
10898 /* Test long element names with namespaces under a failing allocator */
START_TEST(test_nsalloc_long_element)10899 START_TEST(test_nsalloc_long_element)
10900 {
10901 const char *text =
10902 "<foo:thisisalongenoughelementnametotriggerareallocation\n"
10903 " xmlns:foo='http://example.org/' bar:a='12'\n"
10904 " xmlns:bar='http://example.org/'>"
10905 "</foo:thisisalongenoughelementnametotriggerareallocation>";
10906 const XML_Char *elemstr[] = {
10907 XCS("http://example.org/")
10908 XCS(" thisisalongenoughelementnametotriggerareallocation foo"),
10909 XCS("http://example.org/ a bar")
10910 };
10911 int i;
10912 const int max_alloc_count = 30;
10913
10914 for (i = 0; i < max_alloc_count; i++) {
10915 allocation_count = i;
10916 XML_SetReturnNSTriplet(parser, XML_TRUE);
10917 XML_SetUserData(parser, (void *)elemstr);
10918 XML_SetElementHandler(parser,
10919 triplet_start_checker,
10920 triplet_end_checker);
10921 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
10922 XML_TRUE) != XML_STATUS_ERROR)
10923 break;
10924 /* See comment in test_nsalloc_xmlns() */
10925 nsalloc_teardown();
10926 nsalloc_setup();
10927 }
10928 if (i == 0)
10929 fail("Parsing worked despite failing reallocations");
10930 else if (i == max_alloc_count)
10931 fail("Parsing failed at max reallocation count");
10932 }
10933 END_TEST
10934
10935 /* Test the effects of reallocation failure when reassigning a
10936 * binding.
10937 *
10938 * XML_ParserReset does not free the BINDING structures used by a
10939 * parser, but instead adds them to an internal free list to be reused
10940 * as necessary. Likewise the URI buffers allocated for the binding
10941 * aren't freed, but kept attached to their existing binding. If the
10942 * new binding has a longer URI, it will need reallocation. This test
10943 * provokes that reallocation, and tests the control path if it fails.
10944 */
START_TEST(test_nsalloc_realloc_binding_uri)10945 START_TEST(test_nsalloc_realloc_binding_uri)
10946 {
10947 const char *first =
10948 "<doc xmlns='http://example.org/'>\n"
10949 " <e xmlns='' />\n"
10950 "</doc>";
10951 const char *second =
10952 "<doc xmlns='http://example.org/long/enough/URI/to/reallocate/'>\n"
10953 " <e xmlns='' />\n"
10954 "</doc>";
10955 unsigned i;
10956 const unsigned max_realloc_count = 10;
10957
10958 /* First, do a full parse that will leave bindings around */
10959 if (_XML_Parse_SINGLE_BYTES(parser, first, (int)strlen(first),
10960 XML_TRUE) == XML_STATUS_ERROR)
10961 xml_failure(parser);
10962
10963 /* Now repeat with a longer URI and a duff reallocator */
10964 for (i = 0; i < max_realloc_count; i++) {
10965 XML_ParserReset(parser, NULL);
10966 reallocation_count = i;
10967 if (_XML_Parse_SINGLE_BYTES(parser, second, (int)strlen(second),
10968 XML_TRUE) != XML_STATUS_ERROR)
10969 break;
10970 }
10971 if (i == 0)
10972 fail("Parsing worked despite failing reallocation");
10973 else if (i == max_realloc_count)
10974 fail("Parsing failed at max reallocation count");
10975 }
10976 END_TEST
10977
10978 /* Check handling of long prefix names (pool growth) */
START_TEST(test_nsalloc_realloc_long_prefix)10979 START_TEST(test_nsalloc_realloc_long_prefix)
10980 {
10981 const char *text =
10982 "<"
10983 /* 64 characters per line */
10984 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10985 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10986 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10987 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10988 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10989 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10990 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10991 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10992 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10993 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10994 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10995 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10996 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10997 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10998 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
10999 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11000 ":foo xmlns:"
11001 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11002 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11003 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11004 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11005 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11006 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11007 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11008 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11009 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11010 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11011 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11012 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11013 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11014 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11015 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11016 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11017 "='http://example.org/'>"
11018 "</"
11019 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11020 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11021 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11022 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11023 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11024 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11025 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11026 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11027 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11028 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11029 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11030 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11031 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11032 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11033 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11034 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11035 ":foo>";
11036 int i;
11037 const int max_realloc_count = 12;
11038
11039 for (i = 0; i < max_realloc_count; i++) {
11040 reallocation_count = i;
11041 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
11042 XML_TRUE) != XML_STATUS_ERROR)
11043 break;
11044 /* See comment in test_nsalloc_xmlns() */
11045 nsalloc_teardown();
11046 nsalloc_setup();
11047 }
11048 if (i == 0)
11049 fail("Parsing worked despite failing reallocations");
11050 else if (i == max_realloc_count)
11051 fail("Parsing failed even at max reallocation count");
11052 }
11053 END_TEST
11054
11055 /* Check handling of even long prefix names (different code path) */
START_TEST(test_nsalloc_realloc_longer_prefix)11056 START_TEST(test_nsalloc_realloc_longer_prefix)
11057 {
11058 const char *text =
11059 "<"
11060 /* 64 characters per line */
11061 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11062 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11063 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11064 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11065 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11066 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11067 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11068 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11069 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11070 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11071 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11072 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11073 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11074 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11075 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11076 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11077 "Q:foo xmlns:"
11078 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11079 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11080 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11081 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11082 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11083 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11084 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11085 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11086 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11087 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11088 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11089 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11090 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11091 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11092 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11093 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11094 "Q='http://example.org/'>"
11095 "</"
11096 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11097 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11098 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11099 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11100 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11101 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11102 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11103 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11104 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11105 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11106 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11107 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11108 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11109 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11110 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11111 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11112 "Q:foo>";
11113 int i;
11114 const int max_realloc_count = 12;
11115
11116 for (i = 0; i < max_realloc_count; i++) {
11117 reallocation_count = i;
11118 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
11119 XML_TRUE) != XML_STATUS_ERROR)
11120 break;
11121 /* See comment in test_nsalloc_xmlns() */
11122 nsalloc_teardown();
11123 nsalloc_setup();
11124 }
11125 if (i == 0)
11126 fail("Parsing worked despite failing reallocations");
11127 else if (i == max_realloc_count)
11128 fail("Parsing failed even at max reallocation count");
11129 }
11130 END_TEST
11131
START_TEST(test_nsalloc_long_namespace)11132 START_TEST(test_nsalloc_long_namespace)
11133 {
11134 const char *text1 =
11135 "<"
11136 /* 64 characters per line */
11137 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11138 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11139 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11140 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11141 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11142 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11143 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11144 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11145 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11146 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11147 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11148 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11149 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11150 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11151 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11152 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11153 ":e xmlns:"
11154 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11155 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11156 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11157 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11158 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11159 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11160 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11161 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11162 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11163 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11164 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11165 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11166 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11167 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11168 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11169 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11170 "='http://example.org/'>\n";
11171 const char *text2 =
11172 "<"
11173 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11174 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11175 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11176 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11177 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11178 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11179 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11180 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11181 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11182 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11183 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11184 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11185 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11186 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11187 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11188 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11189 ":f "
11190 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11191 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11192 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11193 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11194 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11195 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11196 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11197 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11198 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11199 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11200 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11201 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11202 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11203 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11204 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11205 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11206 ":attr='foo'/>\n"
11207 "</"
11208 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11209 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11210 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11211 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11212 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11213 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11214 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11215 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11216 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11217 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11218 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11219 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11220 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11221 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11222 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11223 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11224 ":e>";
11225 int i;
11226 const int max_alloc_count = 40;
11227
11228 for (i = 0; i < max_alloc_count; i++) {
11229 allocation_count = i;
11230 if (_XML_Parse_SINGLE_BYTES(parser, text1, (int)strlen(text1),
11231 XML_FALSE) != XML_STATUS_ERROR &&
11232 _XML_Parse_SINGLE_BYTES(parser, text2, (int)strlen(text2),
11233 XML_TRUE) != XML_STATUS_ERROR)
11234 break;
11235 /* See comment in test_nsalloc_xmlns() */
11236 nsalloc_teardown();
11237 nsalloc_setup();
11238 }
11239 if (i == 0)
11240 fail("Parsing worked despite failing allocations");
11241 else if (i == max_alloc_count)
11242 fail("Parsing failed even at max allocation count");
11243 }
11244 END_TEST
11245
11246 /* Using a slightly shorter namespace name provokes allocations in
11247 * slightly different places in the code.
11248 */
START_TEST(test_nsalloc_less_long_namespace)11249 START_TEST(test_nsalloc_less_long_namespace)
11250 {
11251 const char *text =
11252 "<"
11253 /* 64 characters per line */
11254 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11255 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11256 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11257 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11258 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11259 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11260 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11261 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678"
11262 ":e xmlns:"
11263 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11264 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11265 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11266 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11267 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11268 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11269 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11270 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678"
11271 "='http://example.org/'>\n"
11272 "<"
11273 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11274 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11275 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11276 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11277 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11278 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11279 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11280 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678"
11281 ":f "
11282 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11283 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11284 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11285 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11286 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11287 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11288 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11289 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678"
11290 ":att='foo'/>\n"
11291 "</"
11292 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11293 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11294 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11295 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11296 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11297 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11298 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
11299 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678"
11300 ":e>";
11301 int i;
11302 const int max_alloc_count = 40;
11303
11304 for (i = 0; i < max_alloc_count; i++) {
11305 allocation_count = i;
11306 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
11307 XML_TRUE) != XML_STATUS_ERROR)
11308 break;
11309 /* See comment in test_nsalloc_xmlns() */
11310 nsalloc_teardown();
11311 nsalloc_setup();
11312 }
11313 if (i == 0)
11314 fail("Parsing worked despite failing allocations");
11315 else if (i == max_alloc_count)
11316 fail("Parsing failed even at max allocation count");
11317 }
11318 END_TEST
11319
START_TEST(test_nsalloc_long_context)11320 START_TEST(test_nsalloc_long_context)
11321 {
11322 const char *text =
11323 "<!DOCTYPE doc SYSTEM 'foo' [\n"
11324 " <!ATTLIST doc baz ID #REQUIRED>\n"
11325 " <!ENTITY en SYSTEM 'bar'>\n"
11326 "]>\n"
11327 "<doc xmlns='http://example.org/"
11328 /* 64 characters per line */
11329 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11330 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11331 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11332 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11333 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11334 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11335 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11336 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11337 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11338 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11339 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11340 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11341 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11342 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11343 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11344 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKL"
11345 "' baz='2'>\n"
11346 "&en;"
11347 "</doc>";
11348 ExtOption options[] = {
11349 { XCS("foo"), "<!ELEMENT e EMPTY>"},
11350 { XCS("bar"), "<e/>" },
11351 { NULL, NULL }
11352 };
11353 int i;
11354 const int max_alloc_count = 70;
11355
11356 for (i = 0; i < max_alloc_count; i++) {
11357 allocation_count = i;
11358 XML_SetUserData(parser, options);
11359 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
11360 XML_SetExternalEntityRefHandler(parser, external_entity_optioner);
11361 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
11362 XML_TRUE) != XML_STATUS_ERROR)
11363 break;
11364
11365 /* See comment in test_nsalloc_xmlns() */
11366 nsalloc_teardown();
11367 nsalloc_setup();
11368 }
11369 if (i == 0)
11370 fail("Parsing worked despite failing allocations");
11371 else if (i == max_alloc_count)
11372 fail("Parsing failed even at max allocation count");
11373 }
11374 END_TEST
11375
11376 /* This function is void; it will throw a fail() on error, so if it
11377 * returns normally it must have succeeded.
11378 */
11379 static void
context_realloc_test(const char * text)11380 context_realloc_test(const char *text)
11381 {
11382 ExtOption options[] = {
11383 { XCS("foo"), "<!ELEMENT e EMPTY>"},
11384 { XCS("bar"), "<e/>" },
11385 { NULL, NULL }
11386 };
11387 int i;
11388 const int max_realloc_count = 6;
11389
11390 for (i = 0; i < max_realloc_count; i++) {
11391 reallocation_count = i;
11392 XML_SetUserData(parser, options);
11393 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
11394 XML_SetExternalEntityRefHandler(parser, external_entity_optioner);
11395 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
11396 XML_TRUE) != XML_STATUS_ERROR)
11397 break;
11398 /* See comment in test_nsalloc_xmlns() */
11399 nsalloc_teardown();
11400 nsalloc_setup();
11401 }
11402 if (i == 0)
11403 fail("Parsing worked despite failing reallocations");
11404 else if (i == max_realloc_count)
11405 fail("Parsing failed even at max reallocation count");
11406 }
11407
START_TEST(test_nsalloc_realloc_long_context)11408 START_TEST(test_nsalloc_realloc_long_context)
11409 {
11410 const char *text =
11411 "<!DOCTYPE doc SYSTEM 'foo' [\n"
11412 " <!ENTITY en SYSTEM 'bar'>\n"
11413 "]>\n"
11414 "<doc xmlns='http://example.org/"
11415 /* 64 characters per line */
11416 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11417 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11418 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11419 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11420 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11421 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11422 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11423 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11424 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11425 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11426 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11427 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11428 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11429 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11430 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11431 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKL"
11432 "'>\n"
11433 "&en;"
11434 "</doc>";
11435
11436 context_realloc_test(text);
11437 }
11438 END_TEST
11439
START_TEST(test_nsalloc_realloc_long_context_2)11440 START_TEST(test_nsalloc_realloc_long_context_2)
11441 {
11442 const char *text =
11443 "<!DOCTYPE doc SYSTEM 'foo' [\n"
11444 " <!ENTITY en SYSTEM 'bar'>\n"
11445 "]>\n"
11446 "<doc xmlns='http://example.org/"
11447 /* 64 characters per line */
11448 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11449 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11450 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11451 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11452 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11453 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11454 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11455 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11456 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11457 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11458 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11459 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11460 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11461 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11462 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11463 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJK"
11464 "'>\n"
11465 "&en;"
11466 "</doc>";
11467
11468 context_realloc_test(text);
11469 }
11470 END_TEST
11471
START_TEST(test_nsalloc_realloc_long_context_3)11472 START_TEST(test_nsalloc_realloc_long_context_3)
11473 {
11474 const char *text =
11475 "<!DOCTYPE doc SYSTEM 'foo' [\n"
11476 " <!ENTITY en SYSTEM 'bar'>\n"
11477 "]>\n"
11478 "<doc xmlns='http://example.org/"
11479 /* 64 characters per line */
11480 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11481 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11482 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11483 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11484 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11485 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11486 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11487 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11488 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11489 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11490 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11491 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11492 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11493 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11494 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11495 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGH"
11496 "'>\n"
11497 "&en;"
11498 "</doc>";
11499
11500 context_realloc_test(text);
11501 }
11502 END_TEST
11503
START_TEST(test_nsalloc_realloc_long_context_4)11504 START_TEST(test_nsalloc_realloc_long_context_4)
11505 {
11506 const char *text =
11507 "<!DOCTYPE doc SYSTEM 'foo' [\n"
11508 " <!ENTITY en SYSTEM 'bar'>\n"
11509 "]>\n"
11510 "<doc xmlns='http://example.org/"
11511 /* 64 characters per line */
11512 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11513 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11514 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11515 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11516 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11517 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11518 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11519 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11520 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11521 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11522 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11523 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11524 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11525 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11526 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11527 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO"
11528 "'>\n"
11529 "&en;"
11530 "</doc>";
11531
11532 context_realloc_test(text);
11533 }
11534 END_TEST
11535
START_TEST(test_nsalloc_realloc_long_context_5)11536 START_TEST(test_nsalloc_realloc_long_context_5)
11537 {
11538 const char *text =
11539 "<!DOCTYPE doc SYSTEM 'foo' [\n"
11540 " <!ENTITY en SYSTEM 'bar'>\n"
11541 "]>\n"
11542 "<doc xmlns='http://example.org/"
11543 /* 64 characters per line */
11544 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11545 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11546 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11547 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11548 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11549 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11550 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11551 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11552 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11553 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11554 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11555 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11556 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11557 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11558 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11559 "ABC"
11560 "'>\n"
11561 "&en;"
11562 "</doc>";
11563
11564 context_realloc_test(text);
11565 }
11566 END_TEST
11567
START_TEST(test_nsalloc_realloc_long_context_6)11568 START_TEST(test_nsalloc_realloc_long_context_6)
11569 {
11570 const char *text =
11571 "<!DOCTYPE doc SYSTEM 'foo' [\n"
11572 " <!ENTITY en SYSTEM 'bar'>\n"
11573 "]>\n"
11574 "<doc xmlns='http://example.org/"
11575 /* 64 characters per line */
11576 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11577 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11578 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11579 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11580 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11581 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11582 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11583 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11584 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11585 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11586 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11587 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11588 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11589 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11590 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
11591 "'>\n"
11592 "&en;"
11593 "</doc>";
11594
11595 context_realloc_test(text);
11596 }
11597 END_TEST
11598
START_TEST(test_nsalloc_realloc_long_context_7)11599 START_TEST(test_nsalloc_realloc_long_context_7)
11600 {
11601 const char *text =
11602 "<!DOCTYPE doc SYSTEM 'foo' [\n"
11603 " <!ENTITY en SYSTEM 'bar'>\n"
11604 "]>\n"
11605 "<doc xmlns='http://example.org/"
11606 /* 64 characters per line */
11607 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11608 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11609 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11610 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11611 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11612 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11613 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11614 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11615 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11616 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11617 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11618 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11619 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11620 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11621 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11622 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLM"
11623 "'>\n"
11624 "&en;"
11625 "</doc>";
11626
11627 context_realloc_test(text);
11628 }
11629 END_TEST
11630
START_TEST(test_nsalloc_realloc_long_ge_name)11631 START_TEST(test_nsalloc_realloc_long_ge_name)
11632 {
11633 const char *text =
11634 "<!DOCTYPE doc SYSTEM 'foo' [\n"
11635 " <!ENTITY "
11636 /* 64 characters per line */
11637 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11638 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11639 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11640 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11641 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11642 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11643 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11644 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11645 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11646 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11647 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11648 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11649 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11650 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11651 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11652 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11653 " SYSTEM 'bar'>\n"
11654 "]>\n"
11655 "<doc xmlns='http://example.org/baz'>\n"
11656 "&"
11657 /* 64 characters per line */
11658 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11659 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11660 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11661 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11662 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11663 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11664 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11665 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11666 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11667 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11668 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11669 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11670 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11671 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11672 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11673 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11674 ";"
11675 "</doc>";
11676 ExtOption options[] = {
11677 { XCS("foo"), "<!ELEMENT el EMPTY>" },
11678 { XCS("bar"), "<el/>" },
11679 { NULL, NULL }
11680 };
11681 int i;
11682 const int max_realloc_count = 10;
11683
11684 for (i = 0; i < max_realloc_count; i++) {
11685 reallocation_count = i;
11686 XML_SetUserData(parser, options);
11687 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
11688 XML_SetExternalEntityRefHandler(parser, external_entity_optioner);
11689 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
11690 XML_TRUE) != XML_STATUS_ERROR)
11691 break;
11692 /* See comment in test_nsalloc_xmlns() */
11693 nsalloc_teardown();
11694 nsalloc_setup();
11695 }
11696 if (i == 0)
11697 fail("Parsing worked despite failing reallocations");
11698 else if (i == max_realloc_count)
11699 fail("Parsing failed even at max reallocation count");
11700 }
11701 END_TEST
11702
11703 /* Test that when a namespace is passed through the context mechanism
11704 * to an external entity parser, the parsers handle reallocation
11705 * failures correctly. The prefix is exactly the right length to
11706 * provoke particular uncommon code paths.
11707 */
START_TEST(test_nsalloc_realloc_long_context_in_dtd)11708 START_TEST(test_nsalloc_realloc_long_context_in_dtd)
11709 {
11710 const char *text1 =
11711 "<!DOCTYPE "
11712 /* 64 characters per line */
11713 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11714 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11715 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11716 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11717 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11718 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11719 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11720 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11721 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11722 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11723 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11724 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11725 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11726 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11727 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11728 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11729 ":doc [\n"
11730 " <!ENTITY First SYSTEM 'foo/First'>\n"
11731 "]>\n"
11732 "<"
11733 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11734 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11735 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11736 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11737 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11738 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11739 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11740 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11741 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11742 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11743 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11744 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11745 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11746 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11747 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11748 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11749 ":doc xmlns:"
11750 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11751 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11752 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11753 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11754 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11755 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11756 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11757 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11758 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11759 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11760 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11761 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11762 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11763 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11764 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11765 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11766 "='foo/Second'>&First;";
11767 const char *text2 = "</"
11768 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11769 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11770 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11771 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11772 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11773 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11774 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11775 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11776 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11777 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11778 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11779 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11780 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11781 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11782 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11783 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11784 ":doc>";
11785 ExtOption options[] = {
11786 { XCS("foo/First"), "Hello world" },
11787 { NULL, NULL }
11788 };
11789 int i;
11790 const int max_realloc_count = 20;
11791
11792 for (i = 0; i < max_realloc_count; i++) {
11793 reallocation_count = i;
11794 XML_SetUserData(parser, options);
11795 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
11796 XML_SetExternalEntityRefHandler(parser, external_entity_optioner);
11797 if (_XML_Parse_SINGLE_BYTES(parser, text1, (int)strlen(text1),
11798 XML_FALSE) != XML_STATUS_ERROR &&
11799 _XML_Parse_SINGLE_BYTES(parser, text2, (int)strlen(text2),
11800 XML_TRUE) != XML_STATUS_ERROR)
11801 break;
11802 /* See comment in test_nsalloc_xmlns() */
11803 nsalloc_teardown();
11804 nsalloc_setup();
11805 }
11806 if (i == 0)
11807 fail("Parsing worked despite failing reallocations");
11808 else if (i == max_realloc_count)
11809 fail("Parsing failed even at max reallocation count");
11810 }
11811 END_TEST
11812
START_TEST(test_nsalloc_long_default_in_ext)11813 START_TEST(test_nsalloc_long_default_in_ext)
11814 {
11815 const char *text =
11816 "<!DOCTYPE doc [\n"
11817 " <!ATTLIST e a1 CDATA '"
11818 /* 64 characters per line */
11819 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11820 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11821 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11822 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11823 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11824 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11825 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11826 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11827 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11828 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11829 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11830 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11831 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11832 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11833 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11834 "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
11835 "'>\n"
11836 " <!ENTITY x SYSTEM 'foo'>\n"
11837 "]>\n"
11838 "<doc>&x;</doc>";
11839 ExtOption options[] = {
11840 { XCS("foo"), "<e/>"},
11841 { NULL, NULL }
11842 };
11843 int i;
11844 const int max_alloc_count = 50;
11845
11846 for (i = 0; i < max_alloc_count; i++) {
11847 allocation_count = i;
11848 XML_SetUserData(parser, options);
11849 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
11850 XML_SetExternalEntityRefHandler(parser, external_entity_optioner);
11851 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
11852 XML_TRUE) != XML_STATUS_ERROR)
11853 break;
11854
11855 /* See comment in test_nsalloc_xmlns() */
11856 nsalloc_teardown();
11857 nsalloc_setup();
11858 }
11859 if (i == 0)
11860 fail("Parsing worked despite failing allocations");
11861 else if (i == max_alloc_count)
11862 fail("Parsing failed even at max allocation count");
11863 }
11864 END_TEST
11865
START_TEST(test_nsalloc_long_systemid_in_ext)11866 START_TEST(test_nsalloc_long_systemid_in_ext)
11867 {
11868 const char *text =
11869 "<!DOCTYPE doc SYSTEM 'foo' [\n"
11870 " <!ENTITY en SYSTEM '"
11871 /* 64 characters per line */
11872 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11873 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11874 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11875 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11876 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11877 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11878 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11879 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11880 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11881 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11882 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11883 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11884 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11885 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11886 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11887 "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
11888 "'>\n"
11889 "]>\n"
11890 "<doc>&en;</doc>";
11891 ExtOption options[] = {
11892 { XCS("foo"), "<!ELEMENT e EMPTY>" },
11893 {
11894 XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/")
11895 XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/")
11896 XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/")
11897 XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/")
11898 XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/")
11899 XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/")
11900 XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/")
11901 XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/")
11902 XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/")
11903 XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/")
11904 XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/")
11905 XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/")
11906 XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/")
11907 XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/")
11908 XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/")
11909 XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"),
11910 "<e/>"
11911 },
11912 { NULL, NULL }
11913 };
11914 int i;
11915 const int max_alloc_count = 55;
11916
11917 for (i = 0; i < max_alloc_count; i++) {
11918 allocation_count = i;
11919 XML_SetUserData(parser, options);
11920 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
11921 XML_SetExternalEntityRefHandler(parser, external_entity_optioner);
11922 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
11923 XML_TRUE) != XML_STATUS_ERROR)
11924 break;
11925
11926 /* See comment in test_nsalloc_xmlns() */
11927 nsalloc_teardown();
11928 nsalloc_setup();
11929 }
11930 if (i == 0)
11931 fail("Parsing worked despite failing allocations");
11932 else if (i == max_alloc_count)
11933 fail("Parsing failed even at max allocation count");
11934 }
11935 END_TEST
11936
11937 /* Test the effects of allocation failure on parsing an element in a
11938 * namespace. Based on test_nsalloc_long_context.
11939 */
START_TEST(test_nsalloc_prefixed_element)11940 START_TEST(test_nsalloc_prefixed_element)
11941 {
11942 const char *text =
11943 "<!DOCTYPE pfx:element SYSTEM 'foo' [\n"
11944 " <!ATTLIST pfx:element baz ID #REQUIRED>\n"
11945 " <!ENTITY en SYSTEM 'bar'>\n"
11946 "]>\n"
11947 "<pfx:element xmlns:pfx='http://example.org/' baz='2'>\n"
11948 "&en;"
11949 "</pfx:element>";
11950 ExtOption options[] = {
11951 { XCS("foo"), "<!ELEMENT e EMPTY>" },
11952 { XCS("bar"), "<e/>" },
11953 { NULL, NULL }
11954 };
11955 int i;
11956 const int max_alloc_count = 70;
11957
11958 for (i = 0; i < max_alloc_count; i++) {
11959 allocation_count = i;
11960 XML_SetUserData(parser, options);
11961 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
11962 XML_SetExternalEntityRefHandler(parser, external_entity_optioner);
11963 if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
11964 XML_TRUE) != XML_STATUS_ERROR)
11965 break;
11966
11967 /* See comment in test_nsalloc_xmlns() */
11968 nsalloc_teardown();
11969 nsalloc_setup();
11970 }
11971 if (i == 0)
11972 fail("Success despite failing allocator");
11973 else if (i == max_alloc_count)
11974 fail("Failed even at full allocation count");
11975 }
11976 END_TEST
11977
11978 static Suite *
make_suite(void)11979 make_suite(void)
11980 {
11981 Suite *s = suite_create("basic");
11982 TCase *tc_basic = tcase_create("basic tests");
11983 TCase *tc_namespace = tcase_create("XML namespaces");
11984 TCase *tc_misc = tcase_create("miscellaneous tests");
11985 TCase *tc_alloc = tcase_create("allocation tests");
11986 TCase *tc_nsalloc = tcase_create("namespace allocation tests");
11987
11988 suite_add_tcase(s, tc_basic);
11989 tcase_add_checked_fixture(tc_basic, basic_setup, basic_teardown);
11990 tcase_add_test(tc_basic, test_nul_byte);
11991 tcase_add_test(tc_basic, test_u0000_char);
11992 tcase_add_test(tc_basic, test_siphash_self);
11993 tcase_add_test(tc_basic, test_siphash_spec);
11994 tcase_add_test(tc_basic, test_bom_utf8);
11995 tcase_add_test(tc_basic, test_bom_utf16_be);
11996 tcase_add_test(tc_basic, test_bom_utf16_le);
11997 tcase_add_test(tc_basic, test_nobom_utf16_le);
11998 tcase_add_test(tc_basic, test_illegal_utf8);
11999 tcase_add_test(tc_basic, test_utf8_auto_align);
12000 tcase_add_test(tc_basic, test_utf16);
12001 tcase_add_test(tc_basic, test_utf16_le_epilog_newline);
12002 tcase_add_test(tc_basic, test_not_utf16);
12003 tcase_add_test(tc_basic, test_bad_encoding);
12004 tcase_add_test(tc_basic, test_latin1_umlauts);
12005 tcase_add_test(tc_basic, test_long_utf8_character);
12006 tcase_add_test(tc_basic, test_long_latin1_attribute);
12007 tcase_add_test(tc_basic, test_long_ascii_attribute);
12008 /* Regression test for SF bug #491986. */
12009 tcase_add_test(tc_basic, test_danish_latin1);
12010 /* Regression test for SF bug #514281. */
12011 tcase_add_test(tc_basic, test_french_charref_hexidecimal);
12012 tcase_add_test(tc_basic, test_french_charref_decimal);
12013 tcase_add_test(tc_basic, test_french_latin1);
12014 tcase_add_test(tc_basic, test_french_utf8);
12015 tcase_add_test(tc_basic, test_utf8_false_rejection);
12016 tcase_add_test(tc_basic, test_line_number_after_parse);
12017 tcase_add_test(tc_basic, test_column_number_after_parse);
12018 tcase_add_test(tc_basic, test_line_and_column_numbers_inside_handlers);
12019 tcase_add_test(tc_basic, test_line_number_after_error);
12020 tcase_add_test(tc_basic, test_column_number_after_error);
12021 tcase_add_test(tc_basic, test_really_long_lines);
12022 tcase_add_test(tc_basic, test_really_long_encoded_lines);
12023 tcase_add_test(tc_basic, test_end_element_events);
12024 tcase_add_test(tc_basic, test_attr_whitespace_normalization);
12025 tcase_add_test(tc_basic, test_xmldecl_misplaced);
12026 tcase_add_test(tc_basic, test_xmldecl_invalid);
12027 tcase_add_test(tc_basic, test_xmldecl_missing_attr);
12028 tcase_add_test(tc_basic, test_xmldecl_missing_value);
12029 tcase_add_test(tc_basic, test_unknown_encoding_internal_entity);
12030 tcase_add_test(tc_basic, test_unrecognised_encoding_internal_entity);
12031 tcase_add_test(tc_basic,
12032 test_wfc_undeclared_entity_unread_external_subset);
12033 tcase_add_test(tc_basic, test_wfc_undeclared_entity_no_external_subset);
12034 tcase_add_test(tc_basic, test_wfc_undeclared_entity_standalone);
12035 tcase_add_test(tc_basic, test_wfc_undeclared_entity_with_external_subset);
12036 tcase_add_test(tc_basic, test_not_standalone_handler_reject);
12037 tcase_add_test(tc_basic, test_not_standalone_handler_accept);
12038 tcase_add_test(tc_basic,
12039 test_wfc_undeclared_entity_with_external_subset_standalone);
12040 tcase_add_test(tc_basic,
12041 test_entity_with_external_subset_unless_standalone);
12042 tcase_add_test(tc_basic, test_wfc_no_recursive_entity_refs);
12043 tcase_add_test(tc_basic, test_ext_entity_set_encoding);
12044 tcase_add_test(tc_basic, test_ext_entity_no_handler);
12045 tcase_add_test(tc_basic, test_ext_entity_set_bom);
12046 tcase_add_test(tc_basic, test_ext_entity_bad_encoding);
12047 tcase_add_test(tc_basic, test_ext_entity_bad_encoding_2);
12048 tcase_add_test(tc_basic, test_ext_entity_invalid_parse);
12049 tcase_add_test(tc_basic, test_ext_entity_invalid_suspended_parse);
12050 tcase_add_test(tc_basic, test_dtd_default_handling);
12051 tcase_add_test(tc_basic, test_dtd_attr_handling);
12052 tcase_add_test(tc_basic, test_empty_ns_without_namespaces);
12053 tcase_add_test(tc_basic, test_ns_in_attribute_default_without_namespaces);
12054 tcase_add_test(tc_basic, test_stop_parser_between_char_data_calls);
12055 tcase_add_test(tc_basic, test_suspend_parser_between_char_data_calls);
12056 tcase_add_test(tc_basic, test_repeated_stop_parser_between_char_data_calls);
12057 tcase_add_test(tc_basic, test_good_cdata_ascii);
12058 tcase_add_test(tc_basic, test_good_cdata_utf16);
12059 tcase_add_test(tc_basic, test_good_cdata_utf16_le);
12060 tcase_add_test(tc_basic, test_long_cdata_utf16);
12061 tcase_add_test(tc_basic, test_multichar_cdata_utf16);
12062 tcase_add_test(tc_basic, test_utf16_bad_surrogate_pair);
12063 tcase_add_test(tc_basic, test_bad_cdata);
12064 tcase_add_test(tc_basic, test_bad_cdata_utf16);
12065 tcase_add_test(tc_basic, test_stop_parser_between_cdata_calls);
12066 tcase_add_test(tc_basic, test_suspend_parser_between_cdata_calls);
12067 tcase_add_test(tc_basic, test_memory_allocation);
12068 tcase_add_test(tc_basic, test_default_current);
12069 tcase_add_test(tc_basic, test_dtd_elements);
12070 tcase_add_test(tc_basic, test_set_foreign_dtd);
12071 tcase_add_test(tc_basic, test_foreign_dtd_not_standalone);
12072 tcase_add_test(tc_basic, test_invalid_foreign_dtd);
12073 tcase_add_test(tc_basic, test_foreign_dtd_with_doctype);
12074 tcase_add_test(tc_basic, test_foreign_dtd_without_external_subset);
12075 tcase_add_test(tc_basic, test_empty_foreign_dtd);
12076 tcase_add_test(tc_basic, test_set_base);
12077 tcase_add_test(tc_basic, test_attributes);
12078 tcase_add_test(tc_basic, test_reset_in_entity);
12079 tcase_add_test(tc_basic, test_resume_invalid_parse);
12080 tcase_add_test(tc_basic, test_resume_resuspended);
12081 tcase_add_test(tc_basic, test_cdata_default);
12082 tcase_add_test(tc_basic, test_subordinate_reset);
12083 tcase_add_test(tc_basic, test_subordinate_suspend);
12084 tcase_add_test(tc_basic, test_subordinate_xdecl_suspend);
12085 tcase_add_test(tc_basic, test_subordinate_xdecl_abort);
12086 tcase_add_test(tc_basic, test_explicit_encoding);
12087 tcase_add_test(tc_basic, test_trailing_cr);
12088 tcase_add_test(tc_basic, test_ext_entity_trailing_cr);
12089 tcase_add_test(tc_basic, test_trailing_rsqb);
12090 tcase_add_test(tc_basic, test_ext_entity_trailing_rsqb);
12091 tcase_add_test(tc_basic, test_ext_entity_good_cdata);
12092 tcase_add_test(tc_basic, test_user_parameters);
12093 tcase_add_test(tc_basic, test_ext_entity_ref_parameter);
12094 tcase_add_test(tc_basic, test_empty_parse);
12095 tcase_add_test(tc_basic, test_get_buffer_1);
12096 tcase_add_test(tc_basic, test_get_buffer_2);
12097 tcase_add_test(tc_basic, test_byte_info_at_end);
12098 tcase_add_test(tc_basic, test_byte_info_at_error);
12099 tcase_add_test(tc_basic, test_byte_info_at_cdata);
12100 tcase_add_test(tc_basic, test_predefined_entities);
12101 tcase_add_test(tc_basic, test_invalid_tag_in_dtd);
12102 tcase_add_test(tc_basic, test_not_predefined_entities);
12103 tcase_add_test(tc_basic, test_ignore_section);
12104 tcase_add_test(tc_basic, test_ignore_section_utf16);
12105 tcase_add_test(tc_basic, test_ignore_section_utf16_be);
12106 tcase_add_test(tc_basic, test_bad_ignore_section);
12107 tcase_add_test(tc_basic, test_external_entity_values);
12108 tcase_add_test(tc_basic, test_ext_entity_not_standalone);
12109 tcase_add_test(tc_basic, test_ext_entity_value_abort);
12110 tcase_add_test(tc_basic, test_bad_public_doctype);
12111 tcase_add_test(tc_basic, test_attribute_enum_value);
12112 tcase_add_test(tc_basic, test_predefined_entity_redefinition);
12113 tcase_add_test(tc_basic, test_dtd_stop_processing);
12114 tcase_add_test(tc_basic, test_public_notation_no_sysid);
12115 tcase_add_test(tc_basic, test_nested_groups);
12116 tcase_add_test(tc_basic, test_group_choice);
12117 tcase_add_test(tc_basic, test_standalone_parameter_entity);
12118 tcase_add_test(tc_basic, test_skipped_parameter_entity);
12119 tcase_add_test(tc_basic, test_recursive_external_parameter_entity);
12120 tcase_add_test(tc_basic, test_undefined_ext_entity_in_external_dtd);
12121 tcase_add_test(tc_basic, test_suspend_xdecl);
12122 tcase_add_test(tc_basic, test_abort_epilog);
12123 tcase_add_test(tc_basic, test_abort_epilog_2);
12124 tcase_add_test(tc_basic, test_suspend_epilog);
12125 tcase_add_test(tc_basic, test_suspend_in_sole_empty_tag);
12126 tcase_add_test(tc_basic, test_unfinished_epilog);
12127 tcase_add_test(tc_basic, test_partial_char_in_epilog);
12128 tcase_add_test(tc_basic, test_hash_collision);
12129 tcase_add_test(tc_basic, test_suspend_resume_internal_entity);
12130 tcase_add_test(tc_basic, test_resume_entity_with_syntax_error);
12131 tcase_add_test(tc_basic, test_suspend_resume_parameter_entity);
12132 tcase_add_test(tc_basic, test_restart_on_error);
12133 tcase_add_test(tc_basic, test_reject_lt_in_attribute_value);
12134 tcase_add_test(tc_basic, test_reject_unfinished_param_in_att_value);
12135 tcase_add_test(tc_basic, test_trailing_cr_in_att_value);
12136 tcase_add_test(tc_basic, test_standalone_internal_entity);
12137 tcase_add_test(tc_basic, test_skipped_external_entity);
12138 tcase_add_test(tc_basic, test_skipped_null_loaded_ext_entity);
12139 tcase_add_test(tc_basic, test_skipped_unloaded_ext_entity);
12140 tcase_add_test(tc_basic, test_param_entity_with_trailing_cr);
12141 tcase_add_test(tc_basic, test_invalid_character_entity);
12142 tcase_add_test(tc_basic, test_invalid_character_entity_2);
12143 tcase_add_test(tc_basic, test_invalid_character_entity_3);
12144 tcase_add_test(tc_basic, test_invalid_character_entity_4);
12145 tcase_add_test(tc_basic, test_pi_handled_in_default);
12146 tcase_add_test(tc_basic, test_comment_handled_in_default);
12147 tcase_add_test(tc_basic, test_pi_yml);
12148 tcase_add_test(tc_basic, test_pi_xnl);
12149 tcase_add_test(tc_basic, test_pi_xmm);
12150 tcase_add_test(tc_basic, test_utf16_pi);
12151 tcase_add_test(tc_basic, test_utf16_be_pi);
12152 tcase_add_test(tc_basic, test_utf16_be_comment);
12153 tcase_add_test(tc_basic, test_utf16_le_comment);
12154 tcase_add_test(tc_basic, test_missing_encoding_conversion_fn);
12155 tcase_add_test(tc_basic, test_failing_encoding_conversion_fn);
12156 tcase_add_test(tc_basic, test_unknown_encoding_success);
12157 tcase_add_test(tc_basic, test_unknown_encoding_bad_name);
12158 tcase_add_test(tc_basic, test_unknown_encoding_bad_name_2);
12159 tcase_add_test(tc_basic, test_unknown_encoding_long_name_1);
12160 tcase_add_test(tc_basic, test_unknown_encoding_long_name_2);
12161 tcase_add_test(tc_basic, test_invalid_unknown_encoding);
12162 tcase_add_test(tc_basic, test_unknown_ascii_encoding_ok);
12163 tcase_add_test(tc_basic, test_unknown_ascii_encoding_fail);
12164 tcase_add_test(tc_basic, test_unknown_encoding_invalid_length);
12165 tcase_add_test(tc_basic, test_unknown_encoding_invalid_topbit);
12166 tcase_add_test(tc_basic, test_unknown_encoding_invalid_surrogate);
12167 tcase_add_test(tc_basic, test_unknown_encoding_invalid_high);
12168 tcase_add_test(tc_basic, test_unknown_encoding_invalid_attr_value);
12169 tcase_add_test(tc_basic, test_ext_entity_latin1_utf16le_bom);
12170 tcase_add_test(tc_basic, test_ext_entity_latin1_utf16be_bom);
12171 tcase_add_test(tc_basic, test_ext_entity_latin1_utf16le_bom2);
12172 tcase_add_test(tc_basic, test_ext_entity_latin1_utf16be_bom2);
12173 tcase_add_test(tc_basic, test_ext_entity_utf16_be);
12174 tcase_add_test(tc_basic, test_ext_entity_utf16_le);
12175 tcase_add_test(tc_basic, test_ext_entity_utf16_unknown);
12176 tcase_add_test(tc_basic, test_ext_entity_utf8_non_bom);
12177 tcase_add_test(tc_basic, test_utf8_in_cdata_section);
12178 tcase_add_test(tc_basic, test_utf8_in_cdata_section_2);
12179 tcase_add_test(tc_basic, test_trailing_spaces_in_elements);
12180 tcase_add_test(tc_basic, test_utf16_attribute);
12181 tcase_add_test(tc_basic, test_utf16_second_attr);
12182 tcase_add_test(tc_basic, test_attr_after_solidus);
12183 tcase_add_test(tc_basic, test_utf16_pe);
12184 tcase_add_test(tc_basic, test_bad_attr_desc_keyword);
12185 tcase_add_test(tc_basic, test_bad_attr_desc_keyword_utf16);
12186 tcase_add_test(tc_basic, test_bad_doctype);
12187 tcase_add_test(tc_basic, test_bad_doctype_utf16);
12188 tcase_add_test(tc_basic, test_bad_doctype_plus);
12189 tcase_add_test(tc_basic, test_bad_doctype_star);
12190 tcase_add_test(tc_basic, test_bad_doctype_query);
12191 tcase_add_test(tc_basic, test_unknown_encoding_bad_ignore);
12192 tcase_add_test(tc_basic, test_entity_in_utf16_be_attr);
12193 tcase_add_test(tc_basic, test_entity_in_utf16_le_attr);
12194 tcase_add_test(tc_basic, test_entity_public_utf16_be);
12195 tcase_add_test(tc_basic, test_entity_public_utf16_le);
12196 tcase_add_test(tc_basic, test_short_doctype);
12197 tcase_add_test(tc_basic, test_short_doctype_2);
12198 tcase_add_test(tc_basic, test_short_doctype_3);
12199 tcase_add_test(tc_basic, test_long_doctype);
12200 tcase_add_test(tc_basic, test_bad_entity);
12201 tcase_add_test(tc_basic, test_bad_entity_2);
12202 tcase_add_test(tc_basic, test_bad_entity_3);
12203 tcase_add_test(tc_basic, test_bad_entity_4);
12204 tcase_add_test(tc_basic, test_bad_notation);
12205 tcase_add_test(tc_basic, test_default_doctype_handler);
12206 tcase_add_test(tc_basic, test_empty_element_abort);
12207
12208 suite_add_tcase(s, tc_namespace);
12209 tcase_add_checked_fixture(tc_namespace,
12210 namespace_setup, namespace_teardown);
12211 tcase_add_test(tc_namespace, test_return_ns_triplet);
12212 tcase_add_test(tc_namespace, test_ns_tagname_overwrite);
12213 tcase_add_test(tc_namespace, test_ns_tagname_overwrite_triplet);
12214 tcase_add_test(tc_namespace, test_start_ns_clears_start_element);
12215 tcase_add_test(tc_namespace, test_default_ns_from_ext_subset_and_ext_ge);
12216 tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_1);
12217 tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_2);
12218 tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_3);
12219 tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_4);
12220 tcase_add_test(tc_namespace, test_ns_unbound_prefix);
12221 tcase_add_test(tc_namespace, test_ns_default_with_empty_uri);
12222 tcase_add_test(tc_namespace, test_ns_duplicate_attrs_diff_prefixes);
12223 tcase_add_test(tc_namespace, test_ns_duplicate_hashes);
12224 tcase_add_test(tc_namespace, test_ns_unbound_prefix_on_attribute);
12225 tcase_add_test(tc_namespace, test_ns_unbound_prefix_on_element);
12226 tcase_add_test(tc_namespace, test_ns_parser_reset);
12227 tcase_add_test(tc_namespace, test_ns_long_element);
12228 tcase_add_test(tc_namespace, test_ns_mixed_prefix_atts);
12229 tcase_add_test(tc_namespace, test_ns_extend_uri_buffer);
12230 tcase_add_test(tc_namespace, test_ns_reserved_attributes);
12231 tcase_add_test(tc_namespace, test_ns_reserved_attributes_2);
12232 tcase_add_test(tc_namespace, test_ns_extremely_long_prefix);
12233 tcase_add_test(tc_namespace, test_ns_unknown_encoding_success);
12234 tcase_add_test(tc_namespace, test_ns_double_colon);
12235 tcase_add_test(tc_namespace, test_ns_double_colon_element);
12236 tcase_add_test(tc_namespace, test_ns_bad_attr_leafname);
12237 tcase_add_test(tc_namespace, test_ns_bad_element_leafname);
12238 tcase_add_test(tc_namespace, test_ns_utf16_leafname);
12239 tcase_add_test(tc_namespace, test_ns_utf16_element_leafname);
12240 tcase_add_test(tc_namespace, test_ns_utf16_doctype);
12241 tcase_add_test(tc_namespace, test_ns_invalid_doctype);
12242 tcase_add_test(tc_namespace, test_ns_double_colon_doctype);
12243
12244 suite_add_tcase(s, tc_misc);
12245 tcase_add_checked_fixture(tc_misc, NULL, basic_teardown);
12246 tcase_add_test(tc_misc, test_misc_alloc_create_parser);
12247 tcase_add_test(tc_misc, test_misc_alloc_create_parser_with_encoding);
12248 tcase_add_test(tc_misc, test_misc_null_parser);
12249 tcase_add_test(tc_misc, test_misc_error_string);
12250 tcase_add_test(tc_misc, test_misc_version);
12251 tcase_add_test(tc_misc, test_misc_features);
12252 tcase_add_test(tc_misc, test_misc_attribute_leak);
12253 tcase_add_test(tc_misc, test_misc_utf16le);
12254
12255 suite_add_tcase(s, tc_alloc);
12256 tcase_add_checked_fixture(tc_alloc, alloc_setup, alloc_teardown);
12257 tcase_add_test(tc_alloc, test_alloc_parse_xdecl);
12258 tcase_add_test(tc_alloc, test_alloc_parse_xdecl_2);
12259 tcase_add_test(tc_alloc, test_alloc_parse_pi);
12260 tcase_add_test(tc_alloc, test_alloc_parse_pi_2);
12261 tcase_add_test(tc_alloc, test_alloc_parse_pi_3);
12262 tcase_add_test(tc_alloc, test_alloc_parse_comment);
12263 tcase_add_test(tc_alloc, test_alloc_parse_comment_2);
12264 tcase_add_test(tc_alloc, test_alloc_create_external_parser);
12265 tcase_add_test(tc_alloc, test_alloc_run_external_parser);
12266 tcase_add_test(tc_alloc, test_alloc_dtd_copy_default_atts);
12267 tcase_add_test(tc_alloc, test_alloc_external_entity);
12268 tcase_add_test(tc_alloc, test_alloc_ext_entity_set_encoding);
12269 tcase_add_test(tc_alloc, test_alloc_internal_entity);
12270 tcase_add_test(tc_alloc, test_alloc_dtd_default_handling);
12271 tcase_add_test(tc_alloc, test_alloc_explicit_encoding);
12272 tcase_add_test(tc_alloc, test_alloc_set_base);
12273 tcase_add_test(tc_alloc, test_alloc_realloc_buffer);
12274 tcase_add_test(tc_alloc, test_alloc_ext_entity_realloc_buffer);
12275 tcase_add_test(tc_alloc, test_alloc_realloc_many_attributes);
12276 tcase_add_test(tc_alloc, test_alloc_public_entity_value);
12277 tcase_add_test(tc_alloc, test_alloc_realloc_subst_public_entity_value);
12278 tcase_add_test(tc_alloc, test_alloc_parse_public_doctype);
12279 tcase_add_test(tc_alloc, test_alloc_parse_public_doctype_long_name);
12280 tcase_add_test(tc_alloc, test_alloc_set_foreign_dtd);
12281 tcase_add_test(tc_alloc, test_alloc_attribute_enum_value);
12282 tcase_add_test(tc_alloc, test_alloc_realloc_attribute_enum_value);
12283 tcase_add_test(tc_alloc, test_alloc_realloc_implied_attribute);
12284 tcase_add_test(tc_alloc, test_alloc_realloc_default_attribute);
12285 tcase_add_test(tc_alloc, test_alloc_notation);
12286 tcase_add_test(tc_alloc, test_alloc_public_notation);
12287 tcase_add_test(tc_alloc, test_alloc_system_notation);
12288 tcase_add_test(tc_alloc, test_alloc_nested_groups);
12289 tcase_add_test(tc_alloc, test_alloc_realloc_nested_groups);
12290 tcase_add_test(tc_alloc, test_alloc_large_group);
12291 tcase_add_test(tc_alloc, test_alloc_realloc_group_choice);
12292 tcase_add_test(tc_alloc, test_alloc_pi_in_epilog);
12293 tcase_add_test(tc_alloc, test_alloc_comment_in_epilog);
12294 tcase_add_test(tc_alloc, test_alloc_realloc_long_attribute_value);
12295 tcase_add_test(tc_alloc, test_alloc_attribute_whitespace);
12296 tcase_add_test(tc_alloc, test_alloc_attribute_predefined_entity);
12297 tcase_add_test(tc_alloc, test_alloc_long_attr_default_with_char_ref);
12298 tcase_add_test(tc_alloc, test_alloc_long_attr_value);
12299 tcase_add_test(tc_alloc, test_alloc_nested_entities);
12300 tcase_add_test(tc_alloc, test_alloc_realloc_param_entity_newline);
12301 tcase_add_test(tc_alloc, test_alloc_realloc_ce_extends_pe);
12302 tcase_add_test(tc_alloc, test_alloc_realloc_attributes);
12303 tcase_add_test(tc_alloc, test_alloc_long_doc_name);
12304 tcase_add_test(tc_alloc, test_alloc_long_base);
12305 tcase_add_test(tc_alloc, test_alloc_long_public_id);
12306 tcase_add_test(tc_alloc, test_alloc_long_entity_value);
12307 tcase_add_test(tc_alloc, test_alloc_long_notation);
12308
12309 suite_add_tcase(s, tc_nsalloc);
12310 tcase_add_checked_fixture(tc_nsalloc, nsalloc_setup, nsalloc_teardown);
12311 tcase_add_test(tc_nsalloc, test_nsalloc_xmlns);
12312 tcase_add_test(tc_nsalloc, test_nsalloc_parse_buffer);
12313 tcase_add_test(tc_nsalloc, test_nsalloc_long_prefix);
12314 tcase_add_test(tc_nsalloc, test_nsalloc_long_uri);
12315 tcase_add_test(tc_nsalloc, test_nsalloc_long_attr);
12316 tcase_add_test(tc_nsalloc, test_nsalloc_long_attr_prefix);
12317 tcase_add_test(tc_nsalloc, test_nsalloc_realloc_attributes);
12318 tcase_add_test(tc_nsalloc, test_nsalloc_long_element);
12319 tcase_add_test(tc_nsalloc, test_nsalloc_realloc_binding_uri);
12320 tcase_add_test(tc_nsalloc, test_nsalloc_realloc_long_prefix);
12321 tcase_add_test(tc_nsalloc, test_nsalloc_realloc_longer_prefix);
12322 tcase_add_test(tc_nsalloc, test_nsalloc_long_namespace);
12323 tcase_add_test(tc_nsalloc, test_nsalloc_less_long_namespace);
12324 tcase_add_test(tc_nsalloc, test_nsalloc_long_context);
12325 tcase_add_test(tc_nsalloc, test_nsalloc_realloc_long_context);
12326 tcase_add_test(tc_nsalloc, test_nsalloc_realloc_long_context_2);
12327 tcase_add_test(tc_nsalloc, test_nsalloc_realloc_long_context_3);
12328 tcase_add_test(tc_nsalloc, test_nsalloc_realloc_long_context_4);
12329 tcase_add_test(tc_nsalloc, test_nsalloc_realloc_long_context_5);
12330 tcase_add_test(tc_nsalloc, test_nsalloc_realloc_long_context_6);
12331 tcase_add_test(tc_nsalloc, test_nsalloc_realloc_long_context_7);
12332 tcase_add_test(tc_nsalloc, test_nsalloc_realloc_long_ge_name);
12333 tcase_add_test(tc_nsalloc, test_nsalloc_realloc_long_context_in_dtd);
12334 tcase_add_test(tc_nsalloc, test_nsalloc_long_default_in_ext);
12335 tcase_add_test(tc_nsalloc, test_nsalloc_long_systemid_in_ext);
12336 tcase_add_test(tc_nsalloc, test_nsalloc_prefixed_element);
12337
12338 return s;
12339 }
12340
12341
12342 int
main(int argc,char * argv[])12343 main(int argc, char *argv[])
12344 {
12345 int i, nf;
12346 int verbosity = CK_NORMAL;
12347 Suite *s = make_suite();
12348 SRunner *sr = srunner_create(s);
12349
12350 /* run the tests for internal helper functions */
12351 testhelper_is_whitespace_normalized();
12352
12353 for (i = 1; i < argc; ++i) {
12354 char *opt = argv[i];
12355 if (strcmp(opt, "-v") == 0 || strcmp(opt, "--verbose") == 0)
12356 verbosity = CK_VERBOSE;
12357 else if (strcmp(opt, "-q") == 0 || strcmp(opt, "--quiet") == 0)
12358 verbosity = CK_SILENT;
12359 else {
12360 fprintf(stderr, "runtests: unknown option '%s'\n", opt);
12361 return 2;
12362 }
12363 }
12364 if (verbosity != CK_SILENT)
12365 printf("Expat version: %" XML_FMT_STR "\n", XML_ExpatVersion());
12366 srunner_run_all(sr, verbosity);
12367 nf = srunner_ntests_failed(sr);
12368 srunner_free(sr);
12369
12370 return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
12371 }
12372