1 /* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
2 See the file COPYING for copying permission.
4 runtest.c : run the Expat test suite
7 #ifdef HAVE_EXPAT_CONFIG_H
8 #include <expat_config.h>
16 #include <stddef.h> /* ptrdiff_t */
23 #include "internal.h" /* for UNUSED_P only */
24 #include "minicheck.h"
26 #if defined(__amigaos__) && defined(__USE_INLINE__)
27 #include <proto/expat.h>
31 #define XML_FMT_INT_MOD "ll"
33 #define XML_FMT_INT_MOD "l"
36 static XML_Parser parser;
42 parser = XML_ParserCreate(NULL);
44 fail("Parser not created.");
51 XML_ParserFree(parser);
54 /* Generate a failure using the parser state to create an error message;
55 this should be used when the parser reports an error we weren't
59 _xml_failure(XML_Parser parser, const char *file, int line)
62 enum XML_Error err = XML_GetErrorCode(parser);
64 " %d: %s (line %" XML_FMT_INT_MOD "u, offset %"\
65 XML_FMT_INT_MOD "u)\n reported from %s, line %d\n",
68 XML_GetCurrentLineNumber(parser),
69 XML_GetCurrentColumnNumber(parser),
71 _fail_unless(0, file, line, buffer);
74 static enum XML_Status
75 _XML_Parse_SINGLE_BYTES(XML_Parser parser, const char *s, int len, int isFinal)
77 enum XML_Status res = XML_STATUS_ERROR;
81 return XML_Parse(parser, s, len, isFinal);
84 for (; offset < len; offset++) {
85 const int innerIsFinal = (offset == len - 1) && isFinal;
86 const char c = s[offset]; /* to help out-of-bounds detection */
87 res = XML_Parse(parser, &c, sizeof(char), innerIsFinal);
88 if (res != XML_STATUS_OK) {
95 #define xml_failure(parser) _xml_failure((parser), __FILE__, __LINE__)
98 _expect_failure(const char *text, enum XML_Error errorCode, const char *errorMessage,
99 const char *file, int lineno)
101 if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_OK)
102 /* Hackish use of _fail_unless() macro, but let's us report
103 the right filename and line number. */
104 _fail_unless(0, file, lineno, errorMessage);
105 if (XML_GetErrorCode(parser) != errorCode)
106 _xml_failure(parser, file, lineno);
109 #define expect_failure(text, errorCode, errorMessage) \
110 _expect_failure((text), (errorCode), (errorMessage), \
113 /* Dummy handlers for when we need to set a handler to tickle a bug,
114 but it doesn't need to do anything.
118 dummy_start_doctype_handler(void *UNUSED_P(userData),
119 const XML_Char *UNUSED_P(doctypeName),
120 const XML_Char *UNUSED_P(sysid),
121 const XML_Char *UNUSED_P(pubid),
122 int UNUSED_P(has_internal_subset))
126 dummy_end_doctype_handler(void *UNUSED_P(userData))
130 dummy_entity_decl_handler(void *UNUSED_P(userData),
131 const XML_Char *UNUSED_P(entityName),
132 int UNUSED_P(is_parameter_entity),
133 const XML_Char *UNUSED_P(value),
134 int UNUSED_P(value_length),
135 const XML_Char *UNUSED_P(base),
136 const XML_Char *UNUSED_P(systemId),
137 const XML_Char *UNUSED_P(publicId),
138 const XML_Char *UNUSED_P(notationName))
142 dummy_notation_decl_handler(void *UNUSED_P(userData),
143 const XML_Char *UNUSED_P(notationName),
144 const XML_Char *UNUSED_P(base),
145 const XML_Char *UNUSED_P(systemId),
146 const XML_Char *UNUSED_P(publicId))
150 dummy_element_decl_handler(void *UNUSED_P(userData),
151 const XML_Char *UNUSED_P(name),
152 XML_Content *UNUSED_P(model))
156 dummy_attlist_decl_handler(void *UNUSED_P(userData),
157 const XML_Char *UNUSED_P(elname),
158 const XML_Char *UNUSED_P(attname),
159 const XML_Char *UNUSED_P(att_type),
160 const XML_Char *UNUSED_P(dflt),
161 int UNUSED_P(isrequired))
165 dummy_comment_handler(void *UNUSED_P(userData), const XML_Char *UNUSED_P(data))
169 dummy_pi_handler(void *UNUSED_P(userData), const XML_Char *UNUSED_P(target), const XML_Char *UNUSED_P(data))
173 dummy_start_element(void *UNUSED_P(userData),
174 const XML_Char *UNUSED_P(name), const XML_Char **UNUSED_P(atts))
179 * Character & encoding tests.
182 START_TEST(test_nul_byte)
184 char text[] = "<doc>\0</doc>";
186 /* test that a NUL byte (in US-ASCII data) is an error */
187 if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text) - 1, XML_TRUE) == XML_STATUS_OK)
188 fail("Parser did not report error on NUL-byte.");
189 if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_TOKEN)
195 START_TEST(test_u0000_char)
197 /* test that a NUL byte (in US-ASCII data) is an error */
198 expect_failure("<doc>�</doc>",
199 XML_ERROR_BAD_CHAR_REF,
200 "Parser did not report error on NUL-byte.");
204 START_TEST(test_bom_utf8)
206 /* This test is really just making sure we don't core on a UTF-8 BOM. */
207 const char *text = "\357\273\277<e/>";
209 if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
214 START_TEST(test_bom_utf16_be)
216 char text[] = "\376\377\0<\0e\0/\0>";
218 if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text)-1, XML_TRUE) == XML_STATUS_ERROR)
223 START_TEST(test_bom_utf16_le)
225 char text[] = "\377\376<\0e\0/\0>\0";
227 if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text)-1, XML_TRUE) == XML_STATUS_ERROR)
233 accumulate_characters(void *userData, const XML_Char *s, int len)
235 CharData_AppendXMLChars((CharData *)userData, s, len);
239 accumulate_attribute(void *userData, const XML_Char *UNUSED_P(name),
240 const XML_Char **atts)
242 CharData *storage = (CharData *)userData;
243 if (storage->count < 0 && atts != NULL && atts[0] != NULL) {
244 /* "accumulate" the value of the first attribute we see */
245 CharData_AppendXMLChars(storage, atts[1], -1);
251 _run_character_check(const XML_Char *text, const XML_Char *expected,
252 const char *file, int line)
256 CharData_Init(&storage);
257 XML_SetUserData(parser, &storage);
258 XML_SetCharacterDataHandler(parser, accumulate_characters);
259 if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
260 _xml_failure(parser, file, line);
261 CharData_CheckXMLChars(&storage, expected);
264 #define run_character_check(text, expected) \
265 _run_character_check(text, expected, __FILE__, __LINE__)
268 _run_attribute_check(const XML_Char *text, const XML_Char *expected,
269 const char *file, int line)
273 CharData_Init(&storage);
274 XML_SetUserData(parser, &storage);
275 XML_SetStartElementHandler(parser, accumulate_attribute);
276 if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
277 _xml_failure(parser, file, line);
278 CharData_CheckXMLChars(&storage, expected);
281 #define run_attribute_check(text, expected) \
282 _run_attribute_check(text, expected, __FILE__, __LINE__)
284 /* Regression test for SF bug #491986. */
285 START_TEST(test_danish_latin1)
288 "<?xml version='1.0' encoding='iso-8859-1'?>\n"
289 "<e>J\xF8rgen \xE6\xF8\xE5\xC6\xD8\xC5</e>";
290 run_character_check(text,
291 "J\xC3\xB8rgen \xC3\xA6\xC3\xB8\xC3\xA5\xC3\x86\xC3\x98\xC3\x85");
296 /* Regression test for SF bug #514281. */
297 START_TEST(test_french_charref_hexidecimal)
300 "<?xml version='1.0' encoding='iso-8859-1'?>\n"
301 "<doc>éèàçêÈ</doc>";
302 run_character_check(text,
303 "\xC3\xA9\xC3\xA8\xC3\xA0\xC3\xA7\xC3\xAA\xC3\x88");
307 START_TEST(test_french_charref_decimal)
310 "<?xml version='1.0' encoding='iso-8859-1'?>\n"
311 "<doc>éèàçêÈ</doc>";
312 run_character_check(text,
313 "\xC3\xA9\xC3\xA8\xC3\xA0\xC3\xA7\xC3\xAA\xC3\x88");
317 START_TEST(test_french_latin1)
320 "<?xml version='1.0' encoding='iso-8859-1'?>\n"
321 "<doc>\xE9\xE8\xE0\xE7\xEa\xC8</doc>";
322 run_character_check(text,
323 "\xC3\xA9\xC3\xA8\xC3\xA0\xC3\xA7\xC3\xAA\xC3\x88");
327 START_TEST(test_french_utf8)
330 "<?xml version='1.0' encoding='utf-8'?>\n"
331 "<doc>\xC3\xA9</doc>";
332 run_character_check(text, "\xC3\xA9");
336 /* Regression test for SF bug #600479.
337 XXX There should be a test that exercises all legal XML Unicode
338 characters as PCDATA and attribute value content, and XML Name
339 characters as part of element and attribute names.
341 START_TEST(test_utf8_false_rejection)
343 const char *text = "<doc>\xEF\xBA\xBF</doc>";
344 run_character_check(text, "\xEF\xBA\xBF");
348 /* Regression test for SF bug #477667.
349 This test assures that any 8-bit character followed by a 7-bit
350 character will not be mistakenly interpreted as a valid UTF-8
353 START_TEST(test_illegal_utf8)
358 for (i = 128; i <= 255; ++i) {
359 sprintf(text, "<e>%ccd</e>", i);
360 if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_OK) {
362 "expected token error for '%c' (ordinal %d) in UTF-8 text",
366 else if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_TOKEN)
368 /* Reset the parser since we use the same parser repeatedly. */
369 XML_ParserReset(parser, NULL);
375 /* Examples, not masks: */
376 #define UTF8_LEAD_1 "\x7f" /* 0b01111111 */
377 #define UTF8_LEAD_2 "\xdf" /* 0b11011111 */
378 #define UTF8_LEAD_3 "\xef" /* 0b11101111 */
379 #define UTF8_LEAD_4 "\xf7" /* 0b11110111 */
380 #define UTF8_FOLLOW "\xbf" /* 0b10111111 */
382 START_TEST(test_utf8_auto_align)
385 ptrdiff_t expectedMovementInChars;
389 struct TestCase cases[] = {
395 {00, UTF8_LEAD_2 UTF8_FOLLOW},
398 {-2, UTF8_LEAD_3 UTF8_FOLLOW},
399 {00, UTF8_LEAD_3 UTF8_FOLLOW UTF8_FOLLOW},
402 {-2, UTF8_LEAD_4 UTF8_FOLLOW},
403 {-3, UTF8_LEAD_4 UTF8_FOLLOW UTF8_FOLLOW},
404 {00, UTF8_LEAD_4 UTF8_FOLLOW UTF8_FOLLOW UTF8_FOLLOW},
409 for (; i < sizeof(cases) / sizeof(*cases); i++) {
410 const char * fromLim = cases[i].input + strlen(cases[i].input);
411 const char * const fromLimInitially = fromLim;
412 ptrdiff_t actualMovementInChars;
414 align_limit_to_full_utf8_characters(cases[i].input, &fromLim);
416 actualMovementInChars = (fromLim - fromLimInitially);
417 if (actualMovementInChars != cases[i].expectedMovementInChars) {
420 printf("[-] UTF-8 case %2lu: Expected movement by %2ld chars"
421 ", actually moved by %2ld chars: \"",
422 i + 1, cases[i].expectedMovementInChars, actualMovementInChars);
423 for (; j < strlen(cases[i].input); j++) {
424 printf("\\x%02x", (unsigned char)cases[i].input[j]);
431 fail("UTF-8 auto-alignment is not bullet-proof\n");
436 START_TEST(test_utf16)
438 /* <?xml version="1.0" encoding="UTF-16"?>
439 <doc a='123'>some text</doc>
442 "\000<\000?\000x\000m\000\154\000 \000v\000e\000r\000s\000i\000o"
443 "\000n\000=\000'\0001\000.\000\060\000'\000 \000e\000n\000c\000o"
444 "\000d\000i\000n\000g\000=\000'\000U\000T\000F\000-\0001\000\066"
445 "\000'\000?\000>\000\n"
446 "\000<\000d\000o\000c\000 \000a\000=\000'\0001\0002\0003\000'"
447 "\000>\000s\000o\000m\000e\000 \000t\000e\000x\000t\000<\000/"
448 "\000d\000o\000c\000>";
449 if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text)-1, XML_TRUE) == XML_STATUS_ERROR)
454 START_TEST(test_utf16_le_epilog_newline)
456 unsigned int first_chunk_bytes = 17;
459 "<\000e\000/\000>\000" /* document element */
460 "\r\000\n\000\r\000\n\000"; /* epilog */
462 if (first_chunk_bytes >= sizeof(text) - 1)
463 fail("bad value of first_chunk_bytes");
464 if ( _XML_Parse_SINGLE_BYTES(parser, text, first_chunk_bytes, XML_FALSE)
469 rc = _XML_Parse_SINGLE_BYTES(parser, text + first_chunk_bytes,
470 sizeof(text) - first_chunk_bytes - 1, XML_TRUE);
471 if (rc == XML_STATUS_ERROR)
477 /* Regression test for SF bug #481609, #774028. */
478 START_TEST(test_latin1_umlauts)
481 "<?xml version='1.0' encoding='iso-8859-1'?>\n"
482 "<e a='\xE4 \xF6 \xFC ä ö ü ä ö ü >'\n"
483 " >\xE4 \xF6 \xFC ä ö ü ä ö ü ></e>";
485 "\xC3\xA4 \xC3\xB6 \xC3\xBC "
486 "\xC3\xA4 \xC3\xB6 \xC3\xBC "
487 "\xC3\xA4 \xC3\xB6 \xC3\xBC >";
488 run_character_check(text, utf8);
489 XML_ParserReset(parser, NULL);
490 run_attribute_check(text, utf8);
494 /* Regression test #1 for SF bug #653180. */
495 START_TEST(test_line_number_after_parse)
503 if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_FALSE) == XML_STATUS_ERROR)
505 lineno = XML_GetCurrentLineNumber(parser);
509 "expected 4 lines, saw %" XML_FMT_INT_MOD "u", lineno);
515 /* Regression test #2 for SF bug #653180. */
516 START_TEST(test_column_number_after_parse)
518 const char *text = "<tag></tag>";
521 if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_FALSE) == XML_STATUS_ERROR)
523 colno = XML_GetCurrentColumnNumber(parser);
527 "expected 11 columns, saw %" XML_FMT_INT_MOD "u", colno);
534 start_element_event_handler2(void *userData, const XML_Char *name,
535 const XML_Char **UNUSED_P(attr))
537 CharData *storage = (CharData *) userData;
541 "<%s> at col:%" XML_FMT_INT_MOD "u line:%"\
542 XML_FMT_INT_MOD "u\n", name,
543 XML_GetCurrentColumnNumber(parser),
544 XML_GetCurrentLineNumber(parser));
545 CharData_AppendString(storage, buffer);
549 end_element_event_handler2(void *userData, const XML_Char *name)
551 CharData *storage = (CharData *) userData;
555 "</%s> at col:%" XML_FMT_INT_MOD "u line:%"\
556 XML_FMT_INT_MOD "u\n", name,
557 XML_GetCurrentColumnNumber(parser),
558 XML_GetCurrentLineNumber(parser));
559 CharData_AppendString(storage, buffer);
562 /* Regression test #3 for SF bug #653180. */
563 START_TEST(test_line_and_column_numbers_inside_handlers)
566 "<a>\n" /* Unix end-of-line */
567 " <b>\r\n" /* Windows end-of-line */
568 " <c/>\r" /* Mac OS end-of-line */
574 const char *expected =
575 "<a> at col:0 line:1\n"
576 "<b> at col:2 line:2\n"
577 "<c> at col:4 line:3\n"
578 "</c> at col:8 line:3\n"
579 "</b> at col:2 line:4\n"
580 "<d> at col:2 line:5\n"
581 "<f> at col:4 line:6\n"
582 "</f> at col:8 line:6\n"
583 "</d> at col:2 line:7\n"
584 "</a> at col:0 line:8\n";
587 CharData_Init(&storage);
588 XML_SetUserData(parser, &storage);
589 XML_SetStartElementHandler(parser, start_element_event_handler2);
590 XML_SetEndElementHandler(parser, end_element_event_handler2);
591 if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
594 CharData_CheckString(&storage, expected);
598 /* Regression test #4 for SF bug #653180. */
599 START_TEST(test_line_number_after_error)
604 " </a>"; /* missing </b> */
606 if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_FALSE) != XML_STATUS_ERROR)
607 fail("Expected a parse error");
609 lineno = XML_GetCurrentLineNumber(parser);
612 sprintf(buffer, "expected 3 lines, saw %" XML_FMT_INT_MOD "u", lineno);
618 /* Regression test #5 for SF bug #653180. */
619 START_TEST(test_column_number_after_error)
624 " </a>"; /* missing </b> */
626 if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_FALSE) != XML_STATUS_ERROR)
627 fail("Expected a parse error");
629 colno = XML_GetCurrentColumnNumber(parser);
633 "expected 4 columns, saw %" XML_FMT_INT_MOD "u", colno);
639 /* Regression test for SF bug #478332. */
640 START_TEST(test_really_long_lines)
642 /* This parses an input line longer than INIT_DATA_BUF_SIZE
643 characters long (defined to be 1024 in xmlparse.c). We take a
644 really cheesy approach to building the input buffer, because
645 this avoids writing bugs in buffer-filling code.
650 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
651 /* until we have at least 1024 characters on the line: */
652 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
653 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
654 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
655 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
656 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
657 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
658 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
659 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
660 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
661 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
662 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
663 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
664 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
665 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
666 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
667 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
669 if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
676 * Element event tests.
680 end_element_event_handler(void *userData, const XML_Char *name)
682 CharData *storage = (CharData *) userData;
683 CharData_AppendString(storage, "/");
684 CharData_AppendXMLChars(storage, name, -1);
687 START_TEST(test_end_element_events)
689 const char *text = "<a><b><c/></b><d><f/></d></a>";
690 const char *expected = "/c/b/f/d/a";
693 CharData_Init(&storage);
694 XML_SetUserData(parser, &storage);
695 XML_SetEndElementHandler(parser, end_element_event_handler);
696 if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
698 CharData_CheckString(&storage, expected);
707 /* Helpers used by the following test; this checks any "attr" and "refs"
708 attributes to make sure whitespace has been normalized.
710 Return true if whitespace has been normalized in a string, using
711 the rules for attribute value normalization. The 'is_cdata' flag
712 is needed since CDATA attributes don't need to have multiple
713 whitespace characters collapsed to a single space, while other
714 attribute data types do. (Section 3.3.3 of the recommendation.)
717 is_whitespace_normalized(const XML_Char *s, int is_cdata)
724 else if (*s == '\t' || *s == '\n' || *s == '\r')
729 if (blanks && !is_cdata)
730 /* illegal leading blanks */
733 else if (blanks > 1 && !is_cdata)
739 if (blanks && !is_cdata)
744 /* Check the attribute whitespace checker: */
746 testhelper_is_whitespace_normalized(void)
748 assert(is_whitespace_normalized("abc", 0));
749 assert(is_whitespace_normalized("abc", 1));
750 assert(is_whitespace_normalized("abc def ghi", 0));
751 assert(is_whitespace_normalized("abc def ghi", 1));
752 assert(!is_whitespace_normalized(" abc def ghi", 0));
753 assert(is_whitespace_normalized(" abc def ghi", 1));
754 assert(!is_whitespace_normalized("abc def ghi", 0));
755 assert(is_whitespace_normalized("abc def ghi", 1));
756 assert(!is_whitespace_normalized("abc def ghi ", 0));
757 assert(is_whitespace_normalized("abc def ghi ", 1));
758 assert(!is_whitespace_normalized(" ", 0));
759 assert(is_whitespace_normalized(" ", 1));
760 assert(!is_whitespace_normalized("\t", 0));
761 assert(!is_whitespace_normalized("\t", 1));
762 assert(!is_whitespace_normalized("\n", 0));
763 assert(!is_whitespace_normalized("\n", 1));
764 assert(!is_whitespace_normalized("\r", 0));
765 assert(!is_whitespace_normalized("\r", 1));
766 assert(!is_whitespace_normalized("abc\t def", 1));
770 check_attr_contains_normalized_whitespace(void *UNUSED_P(userData),
771 const XML_Char *UNUSED_P(name),
772 const XML_Char **atts)
775 for (i = 0; atts[i] != NULL; i += 2) {
776 const XML_Char *attrname = atts[i];
777 const XML_Char *value = atts[i + 1];
778 if (strcmp("attr", attrname) == 0
779 || strcmp("ents", attrname) == 0
780 || strcmp("refs", attrname) == 0) {
781 if (!is_whitespace_normalized(value, 0)) {
783 sprintf(buffer, "attribute value not normalized: %s='%s'",
791 START_TEST(test_attr_whitespace_normalization)
796 " attr NMTOKENS #REQUIRED\n"
797 " ents ENTITIES #REQUIRED\n"
798 " refs IDREFS #REQUIRED>\n"
800 "<doc attr=' a b c\t\td\te\t' refs=' id-1 \t id-2\t\t' \n"
801 " ents=' ent-1 \t\r\n"
807 XML_SetStartElementHandler(parser,
808 check_attr_contains_normalized_whitespace);
809 if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
816 * XML declaration tests.
819 START_TEST(test_xmldecl_misplaced)
822 "<?xml version='1.0'?>\n"
824 XML_ERROR_MISPLACED_XML_PI,
825 "failed to report misplaced XML declaration");
829 /* Regression test for SF bug #584832. */
831 UnknownEncodingHandler(void *UNUSED_P(data),const XML_Char *encoding,XML_Encoding *info)
833 if (strcmp(encoding,"unsupported-encoding") == 0) {
835 for (i = 0; i < 256; ++i)
838 info->convert = NULL;
839 info->release = NULL;
840 return XML_STATUS_OK;
842 return XML_STATUS_ERROR;
845 START_TEST(test_unknown_encoding_internal_entity)
848 "<?xml version='1.0' encoding='unsupported-encoding'?>\n"
849 "<!DOCTYPE test [<!ENTITY foo 'bar'>]>\n"
852 XML_SetUnknownEncodingHandler(parser, UnknownEncodingHandler, NULL);
853 if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
858 /* Regression test for SF bug #620106. */
860 external_entity_loader_set_encoding(XML_Parser parser,
861 const XML_Char *context,
862 const XML_Char *UNUSED_P(base),
863 const XML_Char *UNUSED_P(systemId),
864 const XML_Char *UNUSED_P(publicId))
866 /* This text says it's an unsupported encoding, but it's really
867 UTF-8, which we tell Expat using XML_SetEncoding().
870 "<?xml encoding='iso-8859-3'?>"
872 XML_Parser extparser;
874 extparser = XML_ExternalEntityParserCreate(parser, context, NULL);
875 if (extparser == NULL)
876 fail("Could not create external entity parser.");
877 if (!XML_SetEncoding(extparser, "utf-8"))
878 fail("XML_SetEncoding() ignored for external entity");
879 if ( _XML_Parse_SINGLE_BYTES(extparser, text, strlen(text), XML_TRUE)
880 == XML_STATUS_ERROR) {
887 START_TEST(test_ext_entity_set_encoding)
891 " <!ENTITY en SYSTEM 'http://xml.libexpat.org/dummy.ent'>\n"
895 XML_SetExternalEntityRefHandler(parser,
896 external_entity_loader_set_encoding);
897 run_character_check(text, "\xC3\xA9");
901 /* Test that no error is reported for unknown entities if we don't
902 read an external subset. This was fixed in Expat 1.95.5.
904 START_TEST(test_wfc_undeclared_entity_unread_external_subset) {
906 "<!DOCTYPE doc SYSTEM 'foo'>\n"
907 "<doc>&entity;</doc>";
909 if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
914 /* Test that an error is reported for unknown entities if we don't
915 have an external subset.
917 START_TEST(test_wfc_undeclared_entity_no_external_subset) {
918 expect_failure("<doc>&entity;</doc>",
919 XML_ERROR_UNDEFINED_ENTITY,
920 "Parser did not report undefined entity w/out a DTD.");
924 /* Test that an error is reported for unknown entities if we don't
925 read an external subset, but have been declared standalone.
927 START_TEST(test_wfc_undeclared_entity_standalone) {
929 "<?xml version='1.0' encoding='us-ascii' standalone='yes'?>\n"
930 "<!DOCTYPE doc SYSTEM 'foo'>\n"
931 "<doc>&entity;</doc>";
934 XML_ERROR_UNDEFINED_ENTITY,
935 "Parser did not report undefined entity (standalone).");
940 external_entity_loader(XML_Parser parser,
941 const XML_Char *context,
942 const XML_Char *UNUSED_P(base),
943 const XML_Char *UNUSED_P(systemId),
944 const XML_Char *UNUSED_P(publicId))
946 char *text = (char *)XML_GetUserData(parser);
947 XML_Parser extparser;
949 extparser = XML_ExternalEntityParserCreate(parser, context, NULL);
950 if (extparser == NULL)
951 fail("Could not create external entity parser.");
952 if ( _XML_Parse_SINGLE_BYTES(extparser, text, strlen(text), XML_TRUE)
953 == XML_STATUS_ERROR) {
955 return XML_STATUS_ERROR;
957 return XML_STATUS_OK;
960 /* Test that an error is reported for unknown entities if we have read
961 an external subset, and standalone is true.
963 START_TEST(test_wfc_undeclared_entity_with_external_subset_standalone) {
965 "<?xml version='1.0' encoding='us-ascii' standalone='yes'?>\n"
966 "<!DOCTYPE doc SYSTEM 'foo'>\n"
967 "<doc>&entity;</doc>";
969 "<!ELEMENT doc (#PCDATA)*>";
971 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
972 XML_SetUserData(parser, foo_text);
973 XML_SetExternalEntityRefHandler(parser, external_entity_loader);
975 XML_ERROR_UNDEFINED_ENTITY,
976 "Parser did not report undefined entity (external DTD).");
980 /* Test that no error is reported for unknown entities if we have read
981 an external subset, and standalone is false.
983 START_TEST(test_wfc_undeclared_entity_with_external_subset) {
985 "<?xml version='1.0' encoding='us-ascii'?>\n"
986 "<!DOCTYPE doc SYSTEM 'foo'>\n"
987 "<doc>&entity;</doc>";
989 "<!ELEMENT doc (#PCDATA)*>";
991 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
992 XML_SetUserData(parser, foo_text);
993 XML_SetExternalEntityRefHandler(parser, external_entity_loader);
994 if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
999 START_TEST(test_wfc_no_recursive_entity_refs)
1003 " <!ENTITY entity '&entity;'>\n"
1005 "<doc>&entity;</doc>";
1007 expect_failure(text,
1008 XML_ERROR_RECURSIVE_ENTITY_REF,
1009 "Parser did not report recursive entity reference.");
1013 /* Regression test for SF bug #483514. */
1014 START_TEST(test_dtd_default_handling)
1018 "<!ENTITY e SYSTEM 'http://xml.libexpat.org/e'>\n"
1019 "<!NOTATION n SYSTEM 'http://xml.libexpat.org/n'>\n"
1020 "<!ELEMENT doc EMPTY>\n"
1021 "<!ATTLIST doc a CDATA #IMPLIED>\n"
1023 "<!--comment in dtd-->\n"
1026 XML_SetDefaultHandler(parser, accumulate_characters);
1027 XML_SetDoctypeDeclHandler(parser,
1028 dummy_start_doctype_handler,
1029 dummy_end_doctype_handler);
1030 XML_SetEntityDeclHandler(parser, dummy_entity_decl_handler);
1031 XML_SetNotationDeclHandler(parser, dummy_notation_decl_handler);
1032 XML_SetElementDeclHandler(parser, dummy_element_decl_handler);
1033 XML_SetAttlistDeclHandler(parser, dummy_attlist_decl_handler);
1034 XML_SetProcessingInstructionHandler(parser, dummy_pi_handler);
1035 XML_SetCommentHandler(parser, dummy_comment_handler);
1036 run_character_check(text, "\n\n\n\n\n\n\n<doc/>");
1040 /* See related SF bug #673791.
1041 When namespace processing is enabled, setting the namespace URI for
1042 a prefix is not allowed; this test ensures that it *is* allowed
1043 when namespace processing is not enabled.
1044 (See Namespaces in XML, section 2.)
1046 START_TEST(test_empty_ns_without_namespaces)
1049 "<doc xmlns:prefix='http://www.example.com/'>\n"
1050 " <e xmlns:prefix=''/>\n"
1053 if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
1054 xml_failure(parser);
1058 /* Regression test for SF bug #824420.
1059 Checks that an xmlns:prefix attribute set in an attribute's default
1060 value isn't misinterpreted.
1062 START_TEST(test_ns_in_attribute_default_without_namespaces)
1065 "<!DOCTYPE e:element [\n"
1066 " <!ATTLIST e:element\n"
1067 " xmlns:e CDATA 'http://example.com/'>\n"
1071 if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
1072 xml_failure(parser);
1076 static const char *long_character_data_text =
1077 "<?xml version='1.0' encoding='iso-8859-1'?><s>"
1078 "012345678901234567890123456789012345678901234567890123456789"
1079 "012345678901234567890123456789012345678901234567890123456789"
1080 "012345678901234567890123456789012345678901234567890123456789"
1081 "012345678901234567890123456789012345678901234567890123456789"
1082 "012345678901234567890123456789012345678901234567890123456789"
1083 "012345678901234567890123456789012345678901234567890123456789"
1084 "012345678901234567890123456789012345678901234567890123456789"
1085 "012345678901234567890123456789012345678901234567890123456789"
1086 "012345678901234567890123456789012345678901234567890123456789"
1087 "012345678901234567890123456789012345678901234567890123456789"
1088 "012345678901234567890123456789012345678901234567890123456789"
1089 "012345678901234567890123456789012345678901234567890123456789"
1090 "012345678901234567890123456789012345678901234567890123456789"
1091 "012345678901234567890123456789012345678901234567890123456789"
1092 "012345678901234567890123456789012345678901234567890123456789"
1093 "012345678901234567890123456789012345678901234567890123456789"
1094 "012345678901234567890123456789012345678901234567890123456789"
1095 "012345678901234567890123456789012345678901234567890123456789"
1096 "012345678901234567890123456789012345678901234567890123456789"
1097 "012345678901234567890123456789012345678901234567890123456789"
1100 static XML_Bool resumable = XML_FALSE;
1103 clearing_aborting_character_handler(void *UNUSED_P(userData),
1104 const XML_Char *UNUSED_P(s), int UNUSED_P(len))
1106 XML_StopParser(parser, resumable);
1107 XML_SetCharacterDataHandler(parser, NULL);
1110 /* Regression test for SF bug #1515266: missing check of stopped
1111 parser in doContext() 'for' loop. */
1112 START_TEST(test_stop_parser_between_char_data_calls)
1114 /* The sample data must be big enough that there are two calls to
1115 the character data handler from within the inner "for" loop of
1116 the XML_TOK_DATA_CHARS case in doContent(), and the character
1117 handler must stop the parser and clear the character data
1120 const char *text = long_character_data_text;
1122 XML_SetCharacterDataHandler(parser, clearing_aborting_character_handler);
1123 resumable = XML_FALSE;
1124 if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) != XML_STATUS_ERROR)
1125 xml_failure(parser);
1126 if (XML_GetErrorCode(parser) != XML_ERROR_ABORTED)
1127 xml_failure(parser);
1131 /* Regression test for SF bug #1515266: missing check of stopped
1132 parser in doContext() 'for' loop. */
1133 START_TEST(test_suspend_parser_between_char_data_calls)
1135 /* The sample data must be big enough that there are two calls to
1136 the character data handler from within the inner "for" loop of
1137 the XML_TOK_DATA_CHARS case in doContent(), and the character
1138 handler must stop the parser and clear the character data
1141 const char *text = long_character_data_text;
1143 XML_SetCharacterDataHandler(parser, clearing_aborting_character_handler);
1144 resumable = XML_TRUE;
1145 if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) != XML_STATUS_SUSPENDED)
1146 xml_failure(parser);
1147 if (XML_GetErrorCode(parser) != XML_ERROR_NONE)
1148 xml_failure(parser);
1152 START_TEST(test_good_cdata_ascii)
1154 const char *text = "<a><![CDATA[<greeting>Hello, world!</greeting>]]></a>";
1155 const char *expected = "<greeting>Hello, world!</greeting>";
1158 CharData_Init(&storage);
1159 XML_SetUserData(parser, &storage);
1160 XML_SetCharacterDataHandler(parser, accumulate_characters);
1162 if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
1163 xml_failure(parser);
1164 CharData_CheckXMLChars(&storage, expected);
1168 START_TEST(test_good_cdata_utf16)
1171 * <?xml version='1.0' encoding='utf-16'?>
1172 * <a><![CDATA[hello]]></a>
1176 " \0v\0e\0r\0s\0i\0o\0n\0=\0'\0\x31\0.\0\x30\0'\0"
1177 " \0e\0n\0c\0o\0d\0i\0n\0g\0=\0'\0u\0t\0f\0-\0""1\0""6\0'"
1179 "\0<\0a\0>\0<\0!\0[\0C\0D\0A\0T\0A\0[\0h\0e\0l\0l\0o\0]\0]\0>\0<\0/\0a\0>";
1180 const char *expected = "hello";
1183 CharData_Init(&storage);
1184 XML_SetUserData(parser, &storage);
1185 XML_SetCharacterDataHandler(parser, accumulate_characters);
1187 if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text) - 1, XML_TRUE) == XML_STATUS_ERROR)
1188 xml_failure(parser);
1189 CharData_CheckXMLChars(&storage, expected);
1193 START_TEST(test_bad_cdata)
1197 enum XML_Error expectedError;
1200 struct CaseData cases[] = {
1201 {"<a><", XML_ERROR_UNCLOSED_TOKEN},
1202 {"<a><!", XML_ERROR_UNCLOSED_TOKEN},
1203 {"<a><![", XML_ERROR_UNCLOSED_TOKEN},
1204 {"<a><![C", XML_ERROR_UNCLOSED_TOKEN},
1205 {"<a><![CD", XML_ERROR_UNCLOSED_TOKEN},
1206 {"<a><![CDA", XML_ERROR_UNCLOSED_TOKEN},
1207 {"<a><![CDAT", XML_ERROR_UNCLOSED_TOKEN},
1208 {"<a><![CDATA", XML_ERROR_UNCLOSED_TOKEN},
1210 {"<a><![CDATA[", XML_ERROR_UNCLOSED_CDATA_SECTION},
1211 {"<a><![CDATA[]", XML_ERROR_UNCLOSED_CDATA_SECTION},
1212 {"<a><![CDATA[]]", XML_ERROR_UNCLOSED_CDATA_SECTION},
1214 {"<a><!<a/>", XML_ERROR_INVALID_TOKEN},
1215 {"<a><![<a/>", XML_ERROR_UNCLOSED_TOKEN}, /* ?! */
1216 {"<a><![C<a/>", XML_ERROR_UNCLOSED_TOKEN}, /* ?! */
1217 {"<a><![CD<a/>", XML_ERROR_INVALID_TOKEN},
1218 {"<a><![CDA<a/>", XML_ERROR_INVALID_TOKEN},
1219 {"<a><![CDAT<a/>", XML_ERROR_INVALID_TOKEN},
1220 {"<a><![CDATA<a/>", XML_ERROR_INVALID_TOKEN},
1222 {"<a><![CDATA[<a/>", XML_ERROR_UNCLOSED_CDATA_SECTION},
1223 {"<a><![CDATA[]<a/>", XML_ERROR_UNCLOSED_CDATA_SECTION},
1224 {"<a><![CDATA[]]<a/>", XML_ERROR_UNCLOSED_CDATA_SECTION}
1228 for (; i < sizeof(cases) / sizeof(struct CaseData); i++) {
1229 const enum XML_Status actualStatus = _XML_Parse_SINGLE_BYTES(
1230 parser, cases[i].text, strlen(cases[i].text), XML_TRUE);
1231 const enum XML_Error actualError = XML_GetErrorCode(parser);
1233 assert(actualStatus == XML_STATUS_ERROR);
1235 if (actualError != cases[i].expectedError) {
1237 sprintf(message, "Expected error %d but got error %d for case %u: \"%s\"\n",
1238 cases[i].expectedError, actualError, (unsigned int)i + 1, cases[i].text);
1242 XML_ParserReset(parser, NULL);
1253 namespace_setup(void)
1255 parser = XML_ParserCreateNS(NULL, ' ');
1257 fail("Parser not created.");
1261 namespace_teardown(void)
1266 /* Check that an element name and attribute name match the expected values.
1267 The expected values are passed as an array reference of string pointers
1268 provided as the userData argument; the first is the expected
1269 element name, and the second is the expected attribute name.
1272 triplet_start_checker(void *userData, const XML_Char *name,
1273 const XML_Char **atts)
1275 char **elemstr = (char **)userData;
1277 if (strcmp(elemstr[0], name) != 0) {
1278 sprintf(buffer, "unexpected start string: '%s'", name);
1281 if (strcmp(elemstr[1], atts[0]) != 0) {
1282 sprintf(buffer, "unexpected attribute string: '%s'", atts[0]);
1287 /* Check that the element name passed to the end-element handler matches
1288 the expected value. The expected value is passed as the first element
1289 in an array of strings passed as the userData argument.
1292 triplet_end_checker(void *userData, const XML_Char *name)
1294 char **elemstr = (char **)userData;
1295 if (strcmp(elemstr[0], name) != 0) {
1297 sprintf(buffer, "unexpected end string: '%s'", name);
1302 START_TEST(test_return_ns_triplet)
1305 "<foo:e xmlns:foo='http://expat.sf.net/' bar:a='12'\n"
1306 " xmlns:bar='http://expat.sf.net/'></foo:e>";
1307 const char *elemstr[] = {
1308 "http://expat.sf.net/ e foo",
1309 "http://expat.sf.net/ a bar"
1311 XML_SetReturnNSTriplet(parser, XML_TRUE);
1312 XML_SetUserData(parser, elemstr);
1313 XML_SetElementHandler(parser, triplet_start_checker, triplet_end_checker);
1314 if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
1315 xml_failure(parser);
1320 overwrite_start_checker(void *userData, const XML_Char *name,
1321 const XML_Char **atts)
1323 CharData *storage = (CharData *) userData;
1324 CharData_AppendString(storage, "start ");
1325 CharData_AppendXMLChars(storage, name, -1);
1326 while (*atts != NULL) {
1327 CharData_AppendString(storage, "\nattribute ");
1328 CharData_AppendXMLChars(storage, *atts, -1);
1331 CharData_AppendString(storage, "\n");
1335 overwrite_end_checker(void *userData, const XML_Char *name)
1337 CharData *storage = (CharData *) userData;
1338 CharData_AppendString(storage, "end ");
1339 CharData_AppendXMLChars(storage, name, -1);
1340 CharData_AppendString(storage, "\n");
1344 run_ns_tagname_overwrite_test(const char *text, const char *result)
1347 CharData_Init(&storage);
1348 XML_SetUserData(parser, &storage);
1349 XML_SetElementHandler(parser,
1350 overwrite_start_checker, overwrite_end_checker);
1351 if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
1352 xml_failure(parser);
1353 CharData_CheckString(&storage, result);
1356 /* Regression test for SF bug #566334. */
1357 START_TEST(test_ns_tagname_overwrite)
1360 "<n:e xmlns:n='http://xml.libexpat.org/'>\n"
1361 " <n:f n:attr='foo'/>\n"
1362 " <n:g n:attr2='bar'/>\n"
1364 const char *result =
1365 "start http://xml.libexpat.org/ e\n"
1366 "start http://xml.libexpat.org/ f\n"
1367 "attribute http://xml.libexpat.org/ attr\n"
1368 "end http://xml.libexpat.org/ f\n"
1369 "start http://xml.libexpat.org/ g\n"
1370 "attribute http://xml.libexpat.org/ attr2\n"
1371 "end http://xml.libexpat.org/ g\n"
1372 "end http://xml.libexpat.org/ e\n";
1373 run_ns_tagname_overwrite_test(text, result);
1377 /* Regression test for SF bug #566334. */
1378 START_TEST(test_ns_tagname_overwrite_triplet)
1381 "<n:e xmlns:n='http://xml.libexpat.org/'>\n"
1382 " <n:f n:attr='foo'/>\n"
1383 " <n:g n:attr2='bar'/>\n"
1385 const char *result =
1386 "start http://xml.libexpat.org/ e n\n"
1387 "start http://xml.libexpat.org/ f n\n"
1388 "attribute http://xml.libexpat.org/ attr n\n"
1389 "end http://xml.libexpat.org/ f n\n"
1390 "start http://xml.libexpat.org/ g n\n"
1391 "attribute http://xml.libexpat.org/ attr2 n\n"
1392 "end http://xml.libexpat.org/ g n\n"
1393 "end http://xml.libexpat.org/ e n\n";
1394 XML_SetReturnNSTriplet(parser, XML_TRUE);
1395 run_ns_tagname_overwrite_test(text, result);
1400 /* Regression test for SF bug #620343. */
1402 start_element_fail(void *UNUSED_P(userData),
1403 const XML_Char *UNUSED_P(name), const XML_Char **UNUSED_P(atts))
1405 /* We should never get here. */
1406 fail("should never reach start_element_fail()");
1410 start_ns_clearing_start_element(void *userData,
1411 const XML_Char *UNUSED_P(prefix),
1412 const XML_Char *UNUSED_P(uri))
1414 XML_SetStartElementHandler((XML_Parser) userData, NULL);
1417 START_TEST(test_start_ns_clears_start_element)
1419 /* This needs to use separate start/end tags; using the empty tag
1420 syntax doesn't cause the problematic path through Expat to be
1423 const char *text = "<e xmlns='http://xml.libexpat.org/'></e>";
1425 XML_SetStartElementHandler(parser, start_element_fail);
1426 XML_SetStartNamespaceDeclHandler(parser, start_ns_clearing_start_element);
1427 XML_UseParserAsHandlerArg(parser);
1428 if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
1429 xml_failure(parser);
1433 /* Regression test for SF bug #616863. */
1435 external_entity_handler(XML_Parser parser,
1436 const XML_Char *context,
1437 const XML_Char *UNUSED_P(base),
1438 const XML_Char *UNUSED_P(systemId),
1439 const XML_Char *UNUSED_P(publicId))
1441 intptr_t callno = 1 + (intptr_t)XML_GetUserData(parser);
1446 text = ("<!ELEMENT doc (e+)>\n"
1447 "<!ATTLIST doc xmlns CDATA #IMPLIED>\n"
1448 "<!ELEMENT e EMPTY>\n");
1450 text = ("<?xml version='1.0' encoding='us-ascii'?>"
1453 XML_SetUserData(parser, (void *) callno);
1454 p2 = XML_ExternalEntityParserCreate(parser, context, NULL);
1455 if (_XML_Parse_SINGLE_BYTES(p2, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) {
1463 START_TEST(test_default_ns_from_ext_subset_and_ext_ge)
1466 "<?xml version='1.0'?>\n"
1467 "<!DOCTYPE doc SYSTEM 'http://xml.libexpat.org/doc.dtd' [\n"
1468 " <!ENTITY en SYSTEM 'http://xml.libexpat.org/entity.ent'>\n"
1470 "<doc xmlns='http://xml.libexpat.org/ns1'>\n"
1474 XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
1475 XML_SetExternalEntityRefHandler(parser, external_entity_handler);
1476 /* We actually need to set this handler to tickle this bug. */
1477 XML_SetStartElementHandler(parser, dummy_start_element);
1478 XML_SetUserData(parser, NULL);
1479 if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
1480 xml_failure(parser);
1484 /* Regression test #1 for SF bug #673791. */
1485 START_TEST(test_ns_prefix_with_empty_uri_1)
1488 "<doc xmlns:prefix='http://xml.libexpat.org/'>\n"
1489 " <e xmlns:prefix=''/>\n"
1492 expect_failure(text,
1493 XML_ERROR_UNDECLARING_PREFIX,
1494 "Did not report re-setting namespace"
1495 " URI with prefix to ''.");
1499 /* Regression test #2 for SF bug #673791. */
1500 START_TEST(test_ns_prefix_with_empty_uri_2)
1503 "<?xml version='1.0'?>\n"
1504 "<docelem xmlns:pre=''/>";
1506 expect_failure(text,
1507 XML_ERROR_UNDECLARING_PREFIX,
1508 "Did not report setting namespace URI with prefix to ''.");
1512 /* Regression test #3 for SF bug #673791. */
1513 START_TEST(test_ns_prefix_with_empty_uri_3)
1517 " <!ELEMENT doc EMPTY>\n"
1519 " xmlns:prefix CDATA ''>\n"
1523 expect_failure(text,
1524 XML_ERROR_UNDECLARING_PREFIX,
1525 "Didn't report attr default setting NS w/ prefix to ''.");
1529 /* Regression test #4 for SF bug #673791. */
1530 START_TEST(test_ns_prefix_with_empty_uri_4)
1534 " <!ELEMENT prefix:doc EMPTY>\n"
1535 " <!ATTLIST prefix:doc\n"
1536 " xmlns:prefix CDATA 'http://xml.libexpat.org/'>\n"
1539 /* Packaged info expected by the end element handler;
1540 the weird structuring lets us re-use the triplet_end_checker()
1541 function also used for another test. */
1542 const char *elemstr[] = {
1543 "http://xml.libexpat.org/ doc prefix"
1545 XML_SetReturnNSTriplet(parser, XML_TRUE);
1546 XML_SetUserData(parser, elemstr);
1547 XML_SetEndElementHandler(parser, triplet_end_checker);
1548 if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
1549 xml_failure(parser);
1553 START_TEST(test_ns_default_with_empty_uri)
1556 "<doc xmlns='http://xml.libexpat.org/'>\n"
1559 if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
1560 xml_failure(parser);
1564 /* Regression test for SF bug #692964: two prefixes for one namespace. */
1565 START_TEST(test_ns_duplicate_attrs_diff_prefixes)
1568 "<doc xmlns:a='http://xml.libexpat.org/a'\n"
1569 " xmlns:b='http://xml.libexpat.org/a'\n"
1570 " a:a='v' b:a='v' />";
1571 expect_failure(text,
1572 XML_ERROR_DUPLICATE_ATTRIBUTE,
1573 "did not report multiple attributes with same URI+name");
1577 /* Regression test for SF bug #695401: unbound prefix. */
1578 START_TEST(test_ns_unbound_prefix_on_attribute)
1580 const char *text = "<doc a:attr=''/>";
1581 expect_failure(text,
1582 XML_ERROR_UNBOUND_PREFIX,
1583 "did not report unbound prefix on attribute");
1587 /* Regression test for SF bug #695401: unbound prefix. */
1588 START_TEST(test_ns_unbound_prefix_on_element)
1590 const char *text = "<a:doc/>";
1591 expect_failure(text,
1592 XML_ERROR_UNBOUND_PREFIX,
1593 "did not report unbound prefix on element");
1600 Suite *s = suite_create("basic");
1601 TCase *tc_basic = tcase_create("basic tests");
1602 TCase *tc_namespace = tcase_create("XML namespaces");
1604 suite_add_tcase(s, tc_basic);
1605 tcase_add_checked_fixture(tc_basic, basic_setup, basic_teardown);
1606 tcase_add_test(tc_basic, test_nul_byte);
1607 tcase_add_test(tc_basic, test_u0000_char);
1608 tcase_add_test(tc_basic, test_bom_utf8);
1609 tcase_add_test(tc_basic, test_bom_utf16_be);
1610 tcase_add_test(tc_basic, test_bom_utf16_le);
1611 tcase_add_test(tc_basic, test_illegal_utf8);
1612 tcase_add_test(tc_basic, test_utf8_auto_align);
1613 tcase_add_test(tc_basic, test_utf16);
1614 tcase_add_test(tc_basic, test_utf16_le_epilog_newline);
1615 tcase_add_test(tc_basic, test_latin1_umlauts);
1616 /* Regression test for SF bug #491986. */
1617 tcase_add_test(tc_basic, test_danish_latin1);
1618 /* Regression test for SF bug #514281. */
1619 tcase_add_test(tc_basic, test_french_charref_hexidecimal);
1620 tcase_add_test(tc_basic, test_french_charref_decimal);
1621 tcase_add_test(tc_basic, test_french_latin1);
1622 tcase_add_test(tc_basic, test_french_utf8);
1623 tcase_add_test(tc_basic, test_utf8_false_rejection);
1624 tcase_add_test(tc_basic, test_line_number_after_parse);
1625 tcase_add_test(tc_basic, test_column_number_after_parse);
1626 tcase_add_test(tc_basic, test_line_and_column_numbers_inside_handlers);
1627 tcase_add_test(tc_basic, test_line_number_after_error);
1628 tcase_add_test(tc_basic, test_column_number_after_error);
1629 tcase_add_test(tc_basic, test_really_long_lines);
1630 tcase_add_test(tc_basic, test_end_element_events);
1631 tcase_add_test(tc_basic, test_attr_whitespace_normalization);
1632 tcase_add_test(tc_basic, test_xmldecl_misplaced);
1633 tcase_add_test(tc_basic, test_unknown_encoding_internal_entity);
1634 tcase_add_test(tc_basic,
1635 test_wfc_undeclared_entity_unread_external_subset);
1636 tcase_add_test(tc_basic, test_wfc_undeclared_entity_no_external_subset);
1637 tcase_add_test(tc_basic, test_wfc_undeclared_entity_standalone);
1638 tcase_add_test(tc_basic, test_wfc_undeclared_entity_with_external_subset);
1639 tcase_add_test(tc_basic,
1640 test_wfc_undeclared_entity_with_external_subset_standalone);
1641 tcase_add_test(tc_basic, test_wfc_no_recursive_entity_refs);
1642 tcase_add_test(tc_basic, test_ext_entity_set_encoding);
1643 tcase_add_test(tc_basic, test_dtd_default_handling);
1644 tcase_add_test(tc_basic, test_empty_ns_without_namespaces);
1645 tcase_add_test(tc_basic, test_ns_in_attribute_default_without_namespaces);
1646 tcase_add_test(tc_basic, test_stop_parser_between_char_data_calls);
1647 tcase_add_test(tc_basic, test_suspend_parser_between_char_data_calls);
1648 tcase_add_test(tc_basic, test_good_cdata_ascii);
1649 tcase_add_test(tc_basic, test_good_cdata_utf16);
1650 tcase_add_test(tc_basic, test_bad_cdata);
1652 suite_add_tcase(s, tc_namespace);
1653 tcase_add_checked_fixture(tc_namespace,
1654 namespace_setup, namespace_teardown);
1655 tcase_add_test(tc_namespace, test_return_ns_triplet);
1656 tcase_add_test(tc_namespace, test_ns_tagname_overwrite);
1657 tcase_add_test(tc_namespace, test_ns_tagname_overwrite_triplet);
1658 tcase_add_test(tc_namespace, test_start_ns_clears_start_element);
1659 tcase_add_test(tc_namespace, test_default_ns_from_ext_subset_and_ext_ge);
1660 tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_1);
1661 tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_2);
1662 tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_3);
1663 tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_4);
1664 tcase_add_test(tc_namespace, test_ns_default_with_empty_uri);
1665 tcase_add_test(tc_namespace, test_ns_duplicate_attrs_diff_prefixes);
1666 tcase_add_test(tc_namespace, test_ns_unbound_prefix_on_attribute);
1667 tcase_add_test(tc_namespace, test_ns_unbound_prefix_on_element);
1674 main(int argc, char *argv[])
1677 int verbosity = CK_NORMAL;
1678 Suite *s = make_suite();
1679 SRunner *sr = srunner_create(s);
1681 /* run the tests for internal helper functions */
1682 testhelper_is_whitespace_normalized();
1684 for (i = 1; i < argc; ++i) {
1685 char *opt = argv[i];
1686 if (strcmp(opt, "-v") == 0 || strcmp(opt, "--verbose") == 0)
1687 verbosity = CK_VERBOSE;
1688 else if (strcmp(opt, "-q") == 0 || strcmp(opt, "--quiet") == 0)
1689 verbosity = CK_SILENT;
1691 fprintf(stderr, "runtests: unknown option '%s'\n", opt);
1695 if (verbosity != CK_SILENT)
1696 printf("Expat version: %s\n", XML_ExpatVersion());
1697 srunner_run_all(sr, verbosity);
1698 nf = srunner_ntests_failed(sr);
1701 return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;