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>
18 #include "minicheck.h"
20 #ifdef AMIGA_SHARED_LIB
21 #include <proto/expat.h>
25 #define XML_FMT_INT_MOD "ll"
27 #define XML_FMT_INT_MOD "l"
30 static XML_Parser parser
;
36 parser
= XML_ParserCreate(NULL
);
38 fail("Parser not created.");
45 XML_ParserFree(parser
);
48 /* Generate a failure using the parser state to create an error message;
49 this should be used when the parser reports an error we weren't
53 _xml_failure(XML_Parser parser
, const char *file
, int line
)
57 "\n %s (line %" XML_FMT_INT_MOD
"u, offset %"\
58 XML_FMT_INT_MOD
"u)\n reported from %s, line %d",
59 XML_ErrorString(XML_GetErrorCode(parser
)),
60 XML_GetCurrentLineNumber(parser
),
61 XML_GetCurrentColumnNumber(parser
),
63 _fail_unless(0, file
, line
, buffer
);
66 #define xml_failure(parser) _xml_failure((parser), __FILE__, __LINE__)
69 _expect_failure(char *text
, enum XML_Error errorCode
, char *errorMessage
,
70 char *file
, int lineno
)
72 if (XML_Parse(parser
, text
, strlen(text
), XML_TRUE
) == XML_STATUS_OK
)
73 /* Hackish use of _fail_unless() macro, but let's us report
74 the right filename and line number. */
75 _fail_unless(0, file
, lineno
, errorMessage
);
76 if (XML_GetErrorCode(parser
) != errorCode
)
77 _xml_failure(parser
, file
, lineno
);
80 #define expect_failure(text, errorCode, errorMessage) \
81 _expect_failure((text), (errorCode), (errorMessage), \
84 /* Dummy handlers for when we need to set a handler to tickle a bug,
85 but it doesn't need to do anything.
89 dummy_start_doctype_handler(void *userData
,
90 const XML_Char
*doctypeName
,
91 const XML_Char
*sysid
,
92 const XML_Char
*pubid
,
93 int has_internal_subset
)
97 dummy_end_doctype_handler(void *userData
)
101 dummy_entity_decl_handler(void *userData
,
102 const XML_Char
*entityName
,
103 int is_parameter_entity
,
104 const XML_Char
*value
,
106 const XML_Char
*base
,
107 const XML_Char
*systemId
,
108 const XML_Char
*publicId
,
109 const XML_Char
*notationName
)
113 dummy_notation_decl_handler(void *userData
,
114 const XML_Char
*notationName
,
115 const XML_Char
*base
,
116 const XML_Char
*systemId
,
117 const XML_Char
*publicId
)
121 dummy_element_decl_handler(void *userData
,
122 const XML_Char
*name
,
127 dummy_attlist_decl_handler(void *userData
,
128 const XML_Char
*elname
,
129 const XML_Char
*attname
,
130 const XML_Char
*att_type
,
131 const XML_Char
*dflt
,
136 dummy_comment_handler(void *userData
, const XML_Char
*data
)
140 dummy_pi_handler(void *userData
, const XML_Char
*target
, const XML_Char
*data
)
144 dummy_start_element(void *userData
,
145 const XML_Char
*name
, const XML_Char
**atts
)
150 * Character & encoding tests.
153 START_TEST(test_nul_byte
)
155 char text
[] = "<doc>\0</doc>";
157 /* test that a NUL byte (in US-ASCII data) is an error */
158 if (XML_Parse(parser
, text
, sizeof(text
) - 1, XML_TRUE
) == XML_STATUS_OK
)
159 fail("Parser did not report error on NUL-byte.");
160 if (XML_GetErrorCode(parser
) != XML_ERROR_INVALID_TOKEN
)
166 START_TEST(test_u0000_char
)
168 /* test that a NUL byte (in US-ASCII data) is an error */
169 expect_failure("<doc>�</doc>",
170 XML_ERROR_BAD_CHAR_REF
,
171 "Parser did not report error on NUL-byte.");
175 START_TEST(test_bom_utf8
)
177 /* This test is really just making sure we don't core on a UTF-8 BOM. */
178 char *text
= "\357\273\277<e/>";
180 if (XML_Parse(parser
, text
, strlen(text
), XML_TRUE
) == XML_STATUS_ERROR
)
185 START_TEST(test_bom_utf16_be
)
187 char text
[] = "\376\377\0<\0e\0/\0>";
189 if (XML_Parse(parser
, text
, sizeof(text
)-1, XML_TRUE
) == XML_STATUS_ERROR
)
194 START_TEST(test_bom_utf16_le
)
196 char text
[] = "\377\376<\0e\0/\0>\0";
198 if (XML_Parse(parser
, text
, sizeof(text
)-1, XML_TRUE
) == XML_STATUS_ERROR
)
204 accumulate_characters(void *userData
, const XML_Char
*s
, int len
)
206 CharData_AppendXMLChars((CharData
*)userData
, s
, len
);
210 accumulate_attribute(void *userData
, const XML_Char
*name
,
211 const XML_Char
**atts
)
213 CharData
*storage
= (CharData
*)userData
;
214 if (storage
->count
< 0 && atts
!= NULL
&& atts
[0] != NULL
) {
215 /* "accumulate" the value of the first attribute we see */
216 CharData_AppendXMLChars(storage
, atts
[1], -1);
222 _run_character_check(XML_Char
*text
, XML_Char
*expected
,
223 const char *file
, int line
)
227 CharData_Init(&storage
);
228 XML_SetUserData(parser
, &storage
);
229 XML_SetCharacterDataHandler(parser
, accumulate_characters
);
230 if (XML_Parse(parser
, text
, strlen(text
), XML_TRUE
) == XML_STATUS_ERROR
)
231 _xml_failure(parser
, file
, line
);
232 CharData_CheckXMLChars(&storage
, expected
);
235 #define run_character_check(text, expected) \
236 _run_character_check(text, expected, __FILE__, __LINE__)
239 _run_attribute_check(XML_Char
*text
, XML_Char
*expected
,
240 const char *file
, int line
)
244 CharData_Init(&storage
);
245 XML_SetUserData(parser
, &storage
);
246 XML_SetStartElementHandler(parser
, accumulate_attribute
);
247 if (XML_Parse(parser
, text
, strlen(text
), XML_TRUE
) == XML_STATUS_ERROR
)
248 _xml_failure(parser
, file
, line
);
249 CharData_CheckXMLChars(&storage
, expected
);
252 #define run_attribute_check(text, expected) \
253 _run_attribute_check(text, expected, __FILE__, __LINE__)
255 /* Regression test for SF bug #491986. */
256 START_TEST(test_danish_latin1
)
259 "<?xml version='1.0' encoding='iso-8859-1'?>\n"
260 "<e>J\xF8rgen \xE6\xF8\xE5\xC6\xD8\xC5</e>";
261 run_character_check(text
,
262 "J\xC3\xB8rgen \xC3\xA6\xC3\xB8\xC3\xA5\xC3\x86\xC3\x98\xC3\x85");
267 /* Regression test for SF bug #514281. */
268 START_TEST(test_french_charref_hexidecimal
)
271 "<?xml version='1.0' encoding='iso-8859-1'?>\n"
272 "<doc>éèàçêÈ</doc>";
273 run_character_check(text
,
274 "\xC3\xA9\xC3\xA8\xC3\xA0\xC3\xA7\xC3\xAA\xC3\x88");
278 START_TEST(test_french_charref_decimal
)
281 "<?xml version='1.0' encoding='iso-8859-1'?>\n"
282 "<doc>éèàçêÈ</doc>";
283 run_character_check(text
,
284 "\xC3\xA9\xC3\xA8\xC3\xA0\xC3\xA7\xC3\xAA\xC3\x88");
288 START_TEST(test_french_latin1
)
291 "<?xml version='1.0' encoding='iso-8859-1'?>\n"
292 "<doc>\xE9\xE8\xE0\xE7\xEa\xC8</doc>";
293 run_character_check(text
,
294 "\xC3\xA9\xC3\xA8\xC3\xA0\xC3\xA7\xC3\xAA\xC3\x88");
298 START_TEST(test_french_utf8
)
301 "<?xml version='1.0' encoding='utf-8'?>\n"
302 "<doc>\xC3\xA9</doc>";
303 run_character_check(text
, "\xC3\xA9");
307 /* Regression test for SF bug #600479.
308 XXX There should be a test that exercises all legal XML Unicode
309 characters as PCDATA and attribute value content, and XML Name
310 characters as part of element and attribute names.
312 START_TEST(test_utf8_false_rejection
)
314 char *text
= "<doc>\xEF\xBA\xBF</doc>";
315 run_character_check(text
, "\xEF\xBA\xBF");
319 /* Regression test for SF bug #477667.
320 This test assures that any 8-bit character followed by a 7-bit
321 character will not be mistakenly interpreted as a valid UTF-8
324 START_TEST(test_illegal_utf8
)
329 for (i
= 128; i
<= 255; ++i
) {
330 sprintf(text
, "<e>%ccd</e>", i
);
331 if (XML_Parse(parser
, text
, strlen(text
), XML_TRUE
) == XML_STATUS_OK
) {
333 "expected token error for '%c' (ordinal %d) in UTF-8 text",
337 else if (XML_GetErrorCode(parser
) != XML_ERROR_INVALID_TOKEN
)
339 /* Reset the parser since we use the same parser repeatedly. */
340 XML_ParserReset(parser
, NULL
);
345 START_TEST(test_utf16
)
347 /* <?xml version="1.0" encoding="UTF-16"?>
348 <doc a='123'>some text</doc>
351 "\000<\000?\000x\000m\000\154\000 \000v\000e\000r\000s\000i\000o"
352 "\000n\000=\000'\0001\000.\000\060\000'\000 \000e\000n\000c\000o"
353 "\000d\000i\000n\000g\000=\000'\000U\000T\000F\000-\0001\000\066"
354 "\000'\000?\000>\000\n"
355 "\000<\000d\000o\000c\000 \000a\000=\000'\0001\0002\0003\000'"
356 "\000>\000s\000o\000m\000e\000 \000t\000e\000x\000t\000<\000/"
357 "\000d\000o\000c\000>";
358 if (XML_Parse(parser
, text
, sizeof(text
)-1, XML_TRUE
) == XML_STATUS_ERROR
)
363 START_TEST(test_utf16_le_epilog_newline
)
365 int first_chunk_bytes
= 17;
368 "<\000e\000/\000>\000" /* document element */
369 "\r\000\n\000\r\000\n\000"; /* epilog */
371 if (first_chunk_bytes
>= sizeof(text
) - 1)
372 fail("bad value of first_chunk_bytes");
373 if ( XML_Parse(parser
, text
, first_chunk_bytes
, XML_FALSE
)
378 rc
= XML_Parse(parser
, text
+ first_chunk_bytes
,
379 sizeof(text
) - first_chunk_bytes
- 1, XML_TRUE
);
380 if (rc
== XML_STATUS_ERROR
)
386 /* Regression test for SF bug #481609, #774028. */
387 START_TEST(test_latin1_umlauts
)
390 "<?xml version='1.0' encoding='iso-8859-1'?>\n"
391 "<e a='\xE4 \xF6 \xFC ä ö ü ä ö ü >'\n"
392 " >\xE4 \xF6 \xFC ä ö ü ä ö ü ></e>";
394 "\xC3\xA4 \xC3\xB6 \xC3\xBC "
395 "\xC3\xA4 \xC3\xB6 \xC3\xBC "
396 "\xC3\xA4 \xC3\xB6 \xC3\xBC >";
397 run_character_check(text
, utf8
);
398 XML_ParserReset(parser
, NULL
);
399 run_attribute_check(text
, utf8
);
403 /* Regression test #1 for SF bug #653180. */
404 START_TEST(test_line_number_after_parse
)
412 if (XML_Parse(parser
, text
, strlen(text
), XML_FALSE
) == XML_STATUS_ERROR
)
414 lineno
= XML_GetCurrentLineNumber(parser
);
418 "expected 4 lines, saw %" XML_FMT_INT_MOD
"u", lineno
);
424 /* Regression test #2 for SF bug #653180. */
425 START_TEST(test_column_number_after_parse
)
427 char *text
= "<tag></tag>";
430 if (XML_Parse(parser
, text
, strlen(text
), XML_FALSE
) == XML_STATUS_ERROR
)
432 colno
= XML_GetCurrentColumnNumber(parser
);
436 "expected 11 columns, saw %" XML_FMT_INT_MOD
"u", colno
);
443 start_element_event_handler2(void *userData
, const XML_Char
*name
,
444 const XML_Char
**attr
)
446 CharData
*storage
= (CharData
*) userData
;
450 "<%s> at col:%" XML_FMT_INT_MOD
"u line:%"\
451 XML_FMT_INT_MOD
"u\n", name
,
452 XML_GetCurrentColumnNumber(parser
),
453 XML_GetCurrentLineNumber(parser
));
454 CharData_AppendString(storage
, buffer
);
458 end_element_event_handler2(void *userData
, const XML_Char
*name
)
460 CharData
*storage
= (CharData
*) userData
;
464 "</%s> at col:%" XML_FMT_INT_MOD
"u line:%"\
465 XML_FMT_INT_MOD
"u\n", name
,
466 XML_GetCurrentColumnNumber(parser
),
467 XML_GetCurrentLineNumber(parser
));
468 CharData_AppendString(storage
, buffer
);
471 /* Regression test #3 for SF bug #653180. */
472 START_TEST(test_line_and_column_numbers_inside_handlers
)
475 "<a>\n" /* Unix end-of-line */
476 " <b>\r\n" /* Windows end-of-line */
477 " <c/>\r" /* Mac OS end-of-line */
484 "<a> at col:0 line:1\n"
485 "<b> at col:2 line:2\n"
486 "<c> at col:4 line:3\n"
487 "</c> at col:8 line:3\n"
488 "</b> at col:2 line:4\n"
489 "<d> at col:2 line:5\n"
490 "<f> at col:4 line:6\n"
491 "</f> at col:8 line:6\n"
492 "</d> at col:2 line:7\n"
493 "</a> at col:0 line:8\n";
496 CharData_Init(&storage
);
497 XML_SetUserData(parser
, &storage
);
498 XML_SetStartElementHandler(parser
, start_element_event_handler2
);
499 XML_SetEndElementHandler(parser
, end_element_event_handler2
);
500 if (XML_Parse(parser
, text
, strlen(text
), XML_TRUE
) == XML_STATUS_ERROR
)
503 CharData_CheckString(&storage
, expected
);
507 /* Regression test #4 for SF bug #653180. */
508 START_TEST(test_line_number_after_error
)
513 " </a>"; /* missing </b> */
515 if (XML_Parse(parser
, text
, strlen(text
), XML_FALSE
) != XML_STATUS_ERROR
)
516 fail("Expected a parse error");
518 lineno
= XML_GetCurrentLineNumber(parser
);
521 sprintf(buffer
, "expected 3 lines, saw %" XML_FMT_INT_MOD
"u", lineno
);
527 /* Regression test #5 for SF bug #653180. */
528 START_TEST(test_column_number_after_error
)
533 " </a>"; /* missing </b> */
535 if (XML_Parse(parser
, text
, strlen(text
), XML_FALSE
) != XML_STATUS_ERROR
)
536 fail("Expected a parse error");
538 colno
= XML_GetCurrentColumnNumber(parser
);
542 "expected 4 columns, saw %" XML_FMT_INT_MOD
"u", colno
);
548 /* Regression test for SF bug #478332. */
549 START_TEST(test_really_long_lines
)
551 /* This parses an input line longer than INIT_DATA_BUF_SIZE
552 characters long (defined to be 1024 in xmlparse.c). We take a
553 really cheesy approach to building the input buffer, because
554 this avoids writing bugs in buffer-filling code.
559 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
560 /* until we have at least 1024 characters on the line: */
561 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
562 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
563 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
564 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
565 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
566 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
567 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
568 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
569 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
570 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
571 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
572 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
573 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
574 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
575 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
576 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
578 if (XML_Parse(parser
, text
, strlen(text
), XML_TRUE
) == XML_STATUS_ERROR
)
585 * Element event tests.
589 end_element_event_handler(void *userData
, const XML_Char
*name
)
591 CharData
*storage
= (CharData
*) userData
;
592 CharData_AppendString(storage
, "/");
593 CharData_AppendXMLChars(storage
, name
, -1);
596 START_TEST(test_end_element_events
)
598 char *text
= "<a><b><c/></b><d><f/></d></a>";
599 char *expected
= "/c/b/f/d/a";
602 CharData_Init(&storage
);
603 XML_SetUserData(parser
, &storage
);
604 XML_SetEndElementHandler(parser
, end_element_event_handler
);
605 if (XML_Parse(parser
, text
, strlen(text
), XML_TRUE
) == XML_STATUS_ERROR
)
607 CharData_CheckString(&storage
, expected
);
616 /* Helpers used by the following test; this checks any "attr" and "refs"
617 attributes to make sure whitespace has been normalized.
619 Return true if whitespace has been normalized in a string, using
620 the rules for attribute value normalization. The 'is_cdata' flag
621 is needed since CDATA attributes don't need to have multiple
622 whitespace characters collapsed to a single space, while other
623 attribute data types do. (Section 3.3.3 of the recommendation.)
626 is_whitespace_normalized(const XML_Char
*s
, int is_cdata
)
633 else if (*s
== '\t' || *s
== '\n' || *s
== '\r')
638 if (blanks
&& !is_cdata
)
639 /* illegal leading blanks */
642 else if (blanks
> 1 && !is_cdata
)
648 if (blanks
&& !is_cdata
)
653 /* Check the attribute whitespace checker: */
655 testhelper_is_whitespace_normalized(void)
657 assert(is_whitespace_normalized("abc", 0));
658 assert(is_whitespace_normalized("abc", 1));
659 assert(is_whitespace_normalized("abc def ghi", 0));
660 assert(is_whitespace_normalized("abc def ghi", 1));
661 assert(!is_whitespace_normalized(" abc def ghi", 0));
662 assert(is_whitespace_normalized(" abc def ghi", 1));
663 assert(!is_whitespace_normalized("abc def ghi", 0));
664 assert(is_whitespace_normalized("abc def ghi", 1));
665 assert(!is_whitespace_normalized("abc def ghi ", 0));
666 assert(is_whitespace_normalized("abc def ghi ", 1));
667 assert(!is_whitespace_normalized(" ", 0));
668 assert(is_whitespace_normalized(" ", 1));
669 assert(!is_whitespace_normalized("\t", 0));
670 assert(!is_whitespace_normalized("\t", 1));
671 assert(!is_whitespace_normalized("\n", 0));
672 assert(!is_whitespace_normalized("\n", 1));
673 assert(!is_whitespace_normalized("\r", 0));
674 assert(!is_whitespace_normalized("\r", 1));
675 assert(!is_whitespace_normalized("abc\t def", 1));
679 check_attr_contains_normalized_whitespace(void *userData
,
680 const XML_Char
*name
,
681 const XML_Char
**atts
)
684 for (i
= 0; atts
[i
] != NULL
; i
+= 2) {
685 const XML_Char
*attrname
= atts
[i
];
686 const XML_Char
*value
= atts
[i
+ 1];
687 if (strcmp("attr", attrname
) == 0
688 || strcmp("ents", attrname
) == 0
689 || strcmp("refs", attrname
) == 0) {
690 if (!is_whitespace_normalized(value
, 0)) {
692 sprintf(buffer
, "attribute value not normalized: %s='%s'",
700 START_TEST(test_attr_whitespace_normalization
)
705 " attr NMTOKENS #REQUIRED\n"
706 " ents ENTITIES #REQUIRED\n"
707 " refs IDREFS #REQUIRED>\n"
709 "<doc attr=' a b c\t\td\te\t' refs=' id-1 \t id-2\t\t' \n"
710 " ents=' ent-1 \t\r\n"
716 XML_SetStartElementHandler(parser
,
717 check_attr_contains_normalized_whitespace
);
718 if (XML_Parse(parser
, text
, strlen(text
), XML_TRUE
) == XML_STATUS_ERROR
)
725 * XML declaration tests.
728 START_TEST(test_xmldecl_misplaced
)
731 "<?xml version='1.0'?>\n"
733 XML_ERROR_MISPLACED_XML_PI
,
734 "failed to report misplaced XML declaration");
738 /* Regression test for SF bug #584832. */
740 UnknownEncodingHandler(void *data
,const XML_Char
*encoding
,XML_Encoding
*info
)
742 if (strcmp(encoding
,"unsupported-encoding") == 0) {
744 for (i
= 0; i
< 256; ++i
)
747 info
->convert
= NULL
;
748 info
->release
= NULL
;
749 return XML_STATUS_OK
;
751 return XML_STATUS_ERROR
;
754 START_TEST(test_unknown_encoding_internal_entity
)
757 "<?xml version='1.0' encoding='unsupported-encoding'?>\n"
758 "<!DOCTYPE test [<!ENTITY foo 'bar'>]>\n"
761 XML_SetUnknownEncodingHandler(parser
, UnknownEncodingHandler
, NULL
);
762 if (XML_Parse(parser
, text
, strlen(text
), XML_TRUE
) == XML_STATUS_ERROR
)
767 /* Regression test for SF bug #620106. */
769 external_entity_loader_set_encoding(XML_Parser parser
,
770 const XML_Char
*context
,
771 const XML_Char
*base
,
772 const XML_Char
*systemId
,
773 const XML_Char
*publicId
)
775 /* This text says it's an unsupported encoding, but it's really
776 UTF-8, which we tell Expat using XML_SetEncoding().
779 "<?xml encoding='iso-8859-3'?>"
781 XML_Parser extparser
;
783 extparser
= XML_ExternalEntityParserCreate(parser
, context
, NULL
);
784 if (extparser
== NULL
)
785 fail("Could not create external entity parser.");
786 if (!XML_SetEncoding(extparser
, "utf-8"))
787 fail("XML_SetEncoding() ignored for external entity");
788 if ( XML_Parse(extparser
, text
, strlen(text
), XML_TRUE
)
789 == XML_STATUS_ERROR
) {
796 START_TEST(test_ext_entity_set_encoding
)
800 " <!ENTITY en SYSTEM 'http://xml.libexpat.org/dummy.ent'>\n"
804 XML_SetExternalEntityRefHandler(parser
,
805 external_entity_loader_set_encoding
);
806 run_character_check(text
, "\xC3\xA9");
810 /* Test that no error is reported for unknown entities if we don't
811 read an external subset. This was fixed in Expat 1.95.5.
813 START_TEST(test_wfc_undeclared_entity_unread_external_subset
) {
815 "<!DOCTYPE doc SYSTEM 'foo'>\n"
816 "<doc>&entity;</doc>";
818 if (XML_Parse(parser
, text
, strlen(text
), XML_TRUE
) == XML_STATUS_ERROR
)
823 /* Test that an error is reported for unknown entities if we don't
824 have an external subset.
826 START_TEST(test_wfc_undeclared_entity_no_external_subset
) {
827 expect_failure("<doc>&entity;</doc>",
828 XML_ERROR_UNDEFINED_ENTITY
,
829 "Parser did not report undefined entity w/out a DTD.");
833 /* Test that an error is reported for unknown entities if we don't
834 read an external subset, but have been declared standalone.
836 START_TEST(test_wfc_undeclared_entity_standalone
) {
838 "<?xml version='1.0' encoding='us-ascii' standalone='yes'?>\n"
839 "<!DOCTYPE doc SYSTEM 'foo'>\n"
840 "<doc>&entity;</doc>";
843 XML_ERROR_UNDEFINED_ENTITY
,
844 "Parser did not report undefined entity (standalone).");
849 external_entity_loader(XML_Parser parser
,
850 const XML_Char
*context
,
851 const XML_Char
*base
,
852 const XML_Char
*systemId
,
853 const XML_Char
*publicId
)
855 char *text
= (char *)XML_GetUserData(parser
);
856 XML_Parser extparser
;
858 extparser
= XML_ExternalEntityParserCreate(parser
, context
, NULL
);
859 if (extparser
== NULL
)
860 fail("Could not create external entity parser.");
861 if ( XML_Parse(extparser
, text
, strlen(text
), XML_TRUE
)
862 == XML_STATUS_ERROR
) {
864 return XML_STATUS_ERROR
;
866 return XML_STATUS_OK
;
869 /* Test that an error is reported for unknown entities if we have read
870 an external subset, and standalone is true.
872 START_TEST(test_wfc_undeclared_entity_with_external_subset_standalone
) {
874 "<?xml version='1.0' encoding='us-ascii' standalone='yes'?>\n"
875 "<!DOCTYPE doc SYSTEM 'foo'>\n"
876 "<doc>&entity;</doc>";
878 "<!ELEMENT doc (#PCDATA)*>";
880 XML_SetParamEntityParsing(parser
, XML_PARAM_ENTITY_PARSING_ALWAYS
);
881 XML_SetUserData(parser
, foo_text
);
882 XML_SetExternalEntityRefHandler(parser
, external_entity_loader
);
884 XML_ERROR_UNDEFINED_ENTITY
,
885 "Parser did not report undefined entity (external DTD).");
889 /* Test that no error is reported for unknown entities if we have read
890 an external subset, and standalone is false.
892 START_TEST(test_wfc_undeclared_entity_with_external_subset
) {
894 "<?xml version='1.0' encoding='us-ascii'?>\n"
895 "<!DOCTYPE doc SYSTEM 'foo'>\n"
896 "<doc>&entity;</doc>";
898 "<!ELEMENT doc (#PCDATA)*>";
900 XML_SetParamEntityParsing(parser
, XML_PARAM_ENTITY_PARSING_ALWAYS
);
901 XML_SetUserData(parser
, foo_text
);
902 XML_SetExternalEntityRefHandler(parser
, external_entity_loader
);
903 if (XML_Parse(parser
, text
, strlen(text
), XML_TRUE
) == XML_STATUS_ERROR
)
908 START_TEST(test_wfc_no_recursive_entity_refs
)
912 " <!ENTITY entity '&entity;'>\n"
914 "<doc>&entity;</doc>";
917 XML_ERROR_RECURSIVE_ENTITY_REF
,
918 "Parser did not report recursive entity reference.");
922 /* Regression test for SF bug #483514. */
923 START_TEST(test_dtd_default_handling
)
927 "<!ENTITY e SYSTEM 'http://xml.libexpat.org/e'>\n"
928 "<!NOTATION n SYSTEM 'http://xml.libexpat.org/n'>\n"
929 "<!ELEMENT doc EMPTY>\n"
930 "<!ATTLIST doc a CDATA #IMPLIED>\n"
932 "<!--comment in dtd-->\n"
935 XML_SetDefaultHandler(parser
, accumulate_characters
);
936 XML_SetDoctypeDeclHandler(parser
,
937 dummy_start_doctype_handler
,
938 dummy_end_doctype_handler
);
939 XML_SetEntityDeclHandler(parser
, dummy_entity_decl_handler
);
940 XML_SetNotationDeclHandler(parser
, dummy_notation_decl_handler
);
941 XML_SetElementDeclHandler(parser
, dummy_element_decl_handler
);
942 XML_SetAttlistDeclHandler(parser
, dummy_attlist_decl_handler
);
943 XML_SetProcessingInstructionHandler(parser
, dummy_pi_handler
);
944 XML_SetCommentHandler(parser
, dummy_comment_handler
);
945 run_character_check(text
, "\n\n\n\n\n\n\n<doc/>");
949 /* See related SF bug #673791.
950 When namespace processing is enabled, setting the namespace URI for
951 a prefix is not allowed; this test ensures that it *is* allowed
952 when namespace processing is not enabled.
953 (See Namespaces in XML, section 2.)
955 START_TEST(test_empty_ns_without_namespaces
)
958 "<doc xmlns:prefix='http://www.example.com/'>\n"
959 " <e xmlns:prefix=''/>\n"
962 if (XML_Parse(parser
, text
, strlen(text
), XML_TRUE
) == XML_STATUS_ERROR
)
967 /* Regression test for SF bug #824420.
968 Checks that an xmlns:prefix attribute set in an attribute's default
969 value isn't misinterpreted.
971 START_TEST(test_ns_in_attribute_default_without_namespaces
)
974 "<!DOCTYPE e:element [\n"
975 " <!ATTLIST e:element\n"
976 " xmlns:e CDATA 'http://example.com/'>\n"
980 if (XML_Parse(parser
, text
, strlen(text
), XML_TRUE
) == XML_STATUS_ERROR
)
991 namespace_setup(void)
993 parser
= XML_ParserCreateNS(NULL
, ' ');
995 fail("Parser not created.");
999 namespace_teardown(void)
1004 /* Check that an element name and attribute name match the expected values.
1005 The expected values are passed as an array reference of string pointers
1006 provided as the userData argument; the first is the expected
1007 element name, and the second is the expected attribute name.
1010 triplet_start_checker(void *userData
, const XML_Char
*name
,
1011 const XML_Char
**atts
)
1013 char **elemstr
= (char **)userData
;
1015 if (strcmp(elemstr
[0], name
) != 0) {
1016 sprintf(buffer
, "unexpected start string: '%s'", name
);
1019 if (strcmp(elemstr
[1], atts
[0]) != 0) {
1020 sprintf(buffer
, "unexpected attribute string: '%s'", atts
[0]);
1025 /* Check that the element name passed to the end-element handler matches
1026 the expected value. The expected value is passed as the first element
1027 in an array of strings passed as the userData argument.
1030 triplet_end_checker(void *userData
, const XML_Char
*name
)
1032 char **elemstr
= (char **)userData
;
1033 if (strcmp(elemstr
[0], name
) != 0) {
1035 sprintf(buffer
, "unexpected end string: '%s'", name
);
1040 START_TEST(test_return_ns_triplet
)
1043 "<foo:e xmlns:foo='http://expat.sf.net/' bar:a='12'\n"
1044 " xmlns:bar='http://expat.sf.net/'></foo:e>";
1046 "http://expat.sf.net/ e foo",
1047 "http://expat.sf.net/ a bar"
1049 XML_SetReturnNSTriplet(parser
, XML_TRUE
);
1050 XML_SetUserData(parser
, elemstr
);
1051 XML_SetElementHandler(parser
, triplet_start_checker
, triplet_end_checker
);
1052 if (XML_Parse(parser
, text
, strlen(text
), XML_TRUE
) == XML_STATUS_ERROR
)
1053 xml_failure(parser
);
1058 overwrite_start_checker(void *userData
, const XML_Char
*name
,
1059 const XML_Char
**atts
)
1061 CharData
*storage
= (CharData
*) userData
;
1062 CharData_AppendString(storage
, "start ");
1063 CharData_AppendXMLChars(storage
, name
, -1);
1064 while (*atts
!= NULL
) {
1065 CharData_AppendString(storage
, "\nattribute ");
1066 CharData_AppendXMLChars(storage
, *atts
, -1);
1069 CharData_AppendString(storage
, "\n");
1073 overwrite_end_checker(void *userData
, const XML_Char
*name
)
1075 CharData
*storage
= (CharData
*) userData
;
1076 CharData_AppendString(storage
, "end ");
1077 CharData_AppendXMLChars(storage
, name
, -1);
1078 CharData_AppendString(storage
, "\n");
1082 run_ns_tagname_overwrite_test(char *text
, char *result
)
1085 CharData_Init(&storage
);
1086 XML_SetUserData(parser
, &storage
);
1087 XML_SetElementHandler(parser
,
1088 overwrite_start_checker
, overwrite_end_checker
);
1089 if (XML_Parse(parser
, text
, strlen(text
), XML_TRUE
) == XML_STATUS_ERROR
)
1090 xml_failure(parser
);
1091 CharData_CheckString(&storage
, result
);
1094 /* Regression test for SF bug #566334. */
1095 START_TEST(test_ns_tagname_overwrite
)
1098 "<n:e xmlns:n='http://xml.libexpat.org/'>\n"
1099 " <n:f n:attr='foo'/>\n"
1100 " <n:g n:attr2='bar'/>\n"
1103 "start http://xml.libexpat.org/ e\n"
1104 "start http://xml.libexpat.org/ f\n"
1105 "attribute http://xml.libexpat.org/ attr\n"
1106 "end http://xml.libexpat.org/ f\n"
1107 "start http://xml.libexpat.org/ g\n"
1108 "attribute http://xml.libexpat.org/ attr2\n"
1109 "end http://xml.libexpat.org/ g\n"
1110 "end http://xml.libexpat.org/ e\n";
1111 run_ns_tagname_overwrite_test(text
, result
);
1115 /* Regression test for SF bug #566334. */
1116 START_TEST(test_ns_tagname_overwrite_triplet
)
1119 "<n:e xmlns:n='http://xml.libexpat.org/'>\n"
1120 " <n:f n:attr='foo'/>\n"
1121 " <n:g n:attr2='bar'/>\n"
1124 "start http://xml.libexpat.org/ e n\n"
1125 "start http://xml.libexpat.org/ f n\n"
1126 "attribute http://xml.libexpat.org/ attr n\n"
1127 "end http://xml.libexpat.org/ f n\n"
1128 "start http://xml.libexpat.org/ g n\n"
1129 "attribute http://xml.libexpat.org/ attr2 n\n"
1130 "end http://xml.libexpat.org/ g n\n"
1131 "end http://xml.libexpat.org/ e n\n";
1132 XML_SetReturnNSTriplet(parser
, XML_TRUE
);
1133 run_ns_tagname_overwrite_test(text
, result
);
1138 /* Regression test for SF bug #620343. */
1140 start_element_fail(void *userData
,
1141 const XML_Char
*name
, const XML_Char
**atts
)
1143 /* We should never get here. */
1144 fail("should never reach start_element_fail()");
1148 start_ns_clearing_start_element(void *userData
,
1149 const XML_Char
*prefix
,
1150 const XML_Char
*uri
)
1152 XML_SetStartElementHandler((XML_Parser
) userData
, NULL
);
1155 START_TEST(test_start_ns_clears_start_element
)
1157 /* This needs to use separate start/end tags; using the empty tag
1158 syntax doesn't cause the problematic path through Expat to be
1161 char *text
= "<e xmlns='http://xml.libexpat.org/'></e>";
1163 XML_SetStartElementHandler(parser
, start_element_fail
);
1164 XML_SetStartNamespaceDeclHandler(parser
, start_ns_clearing_start_element
);
1165 XML_UseParserAsHandlerArg(parser
);
1166 if (XML_Parse(parser
, text
, strlen(text
), XML_TRUE
) == XML_STATUS_ERROR
)
1167 xml_failure(parser
);
1171 /* Regression test for SF bug #616863. */
1173 external_entity_handler(XML_Parser parser
,
1174 const XML_Char
*context
,
1175 const XML_Char
*base
,
1176 const XML_Char
*systemId
,
1177 const XML_Char
*publicId
)
1179 long callno
= 1 + (long)XML_GetUserData(parser
);
1184 text
= ("<!ELEMENT doc (e+)>\n"
1185 "<!ATTLIST doc xmlns CDATA #IMPLIED>\n"
1186 "<!ELEMENT e EMPTY>\n");
1188 text
= ("<?xml version='1.0' encoding='us-ascii'?>"
1191 XML_SetUserData(parser
, (void *) callno
);
1192 p2
= XML_ExternalEntityParserCreate(parser
, context
, NULL
);
1193 if (XML_Parse(p2
, text
, strlen(text
), XML_TRUE
) == XML_STATUS_ERROR
) {
1201 START_TEST(test_default_ns_from_ext_subset_and_ext_ge
)
1204 "<?xml version='1.0'?>\n"
1205 "<!DOCTYPE doc SYSTEM 'http://xml.libexpat.org/doc.dtd' [\n"
1206 " <!ENTITY en SYSTEM 'http://xml.libexpat.org/entity.ent'>\n"
1208 "<doc xmlns='http://xml.libexpat.org/ns1'>\n"
1212 XML_SetParamEntityParsing(parser
, XML_PARAM_ENTITY_PARSING_ALWAYS
);
1213 XML_SetExternalEntityRefHandler(parser
, external_entity_handler
);
1214 /* We actually need to set this handler to tickle this bug. */
1215 XML_SetStartElementHandler(parser
, dummy_start_element
);
1216 XML_SetUserData(parser
, NULL
);
1217 if (XML_Parse(parser
, text
, strlen(text
), XML_TRUE
) == XML_STATUS_ERROR
)
1218 xml_failure(parser
);
1222 /* Regression test #1 for SF bug #673791. */
1223 START_TEST(test_ns_prefix_with_empty_uri_1
)
1226 "<doc xmlns:prefix='http://xml.libexpat.org/'>\n"
1227 " <e xmlns:prefix=''/>\n"
1230 expect_failure(text
,
1231 XML_ERROR_UNDECLARING_PREFIX
,
1232 "Did not report re-setting namespace"
1233 " URI with prefix to ''.");
1237 /* Regression test #2 for SF bug #673791. */
1238 START_TEST(test_ns_prefix_with_empty_uri_2
)
1241 "<?xml version='1.0'?>\n"
1242 "<docelem xmlns:pre=''/>";
1244 expect_failure(text
,
1245 XML_ERROR_UNDECLARING_PREFIX
,
1246 "Did not report setting namespace URI with prefix to ''.");
1250 /* Regression test #3 for SF bug #673791. */
1251 START_TEST(test_ns_prefix_with_empty_uri_3
)
1255 " <!ELEMENT doc EMPTY>\n"
1257 " xmlns:prefix CDATA ''>\n"
1261 expect_failure(text
,
1262 XML_ERROR_UNDECLARING_PREFIX
,
1263 "Didn't report attr default setting NS w/ prefix to ''.");
1267 /* Regression test #4 for SF bug #673791. */
1268 START_TEST(test_ns_prefix_with_empty_uri_4
)
1272 " <!ELEMENT prefix:doc EMPTY>\n"
1273 " <!ATTLIST prefix:doc\n"
1274 " xmlns:prefix CDATA 'http://xml.libexpat.org/'>\n"
1277 /* Packaged info expected by the end element handler;
1278 the weird structuring lets us re-use the triplet_end_checker()
1279 function also used for another test. */
1281 "http://xml.libexpat.org/ doc prefix"
1283 XML_SetReturnNSTriplet(parser
, XML_TRUE
);
1284 XML_SetUserData(parser
, elemstr
);
1285 XML_SetEndElementHandler(parser
, triplet_end_checker
);
1286 if (XML_Parse(parser
, text
, strlen(text
), XML_TRUE
) == XML_STATUS_ERROR
)
1287 xml_failure(parser
);
1291 START_TEST(test_ns_default_with_empty_uri
)
1294 "<doc xmlns='http://xml.libexpat.org/'>\n"
1297 if (XML_Parse(parser
, text
, strlen(text
), XML_TRUE
) == XML_STATUS_ERROR
)
1298 xml_failure(parser
);
1302 /* Regression test for SF bug #692964: two prefixes for one namespace. */
1303 START_TEST(test_ns_duplicate_attrs_diff_prefixes
)
1306 "<doc xmlns:a='http://xml.libexpat.org/a'\n"
1307 " xmlns:b='http://xml.libexpat.org/a'\n"
1308 " a:a='v' b:a='v' />";
1309 expect_failure(text
,
1310 XML_ERROR_DUPLICATE_ATTRIBUTE
,
1311 "did not report multiple attributes with same URI+name");
1315 /* Regression test for SF bug #695401: unbound prefix. */
1316 START_TEST(test_ns_unbound_prefix_on_attribute
)
1318 char *text
= "<doc a:attr=''/>";
1319 expect_failure(text
,
1320 XML_ERROR_UNBOUND_PREFIX
,
1321 "did not report unbound prefix on attribute");
1325 /* Regression test for SF bug #695401: unbound prefix. */
1326 START_TEST(test_ns_unbound_prefix_on_element
)
1328 char *text
= "<a:doc/>";
1329 expect_failure(text
,
1330 XML_ERROR_UNBOUND_PREFIX
,
1331 "did not report unbound prefix on element");
1338 Suite
*s
= suite_create("basic");
1339 TCase
*tc_basic
= tcase_create("basic tests");
1340 TCase
*tc_namespace
= tcase_create("XML namespaces");
1342 suite_add_tcase(s
, tc_basic
);
1343 tcase_add_checked_fixture(tc_basic
, basic_setup
, basic_teardown
);
1344 tcase_add_test(tc_basic
, test_nul_byte
);
1345 tcase_add_test(tc_basic
, test_u0000_char
);
1346 tcase_add_test(tc_basic
, test_bom_utf8
);
1347 tcase_add_test(tc_basic
, test_bom_utf16_be
);
1348 tcase_add_test(tc_basic
, test_bom_utf16_le
);
1349 tcase_add_test(tc_basic
, test_illegal_utf8
);
1350 tcase_add_test(tc_basic
, test_utf16
);
1351 tcase_add_test(tc_basic
, test_utf16_le_epilog_newline
);
1352 tcase_add_test(tc_basic
, test_latin1_umlauts
);
1353 /* Regression test for SF bug #491986. */
1354 tcase_add_test(tc_basic
, test_danish_latin1
);
1355 /* Regression test for SF bug #514281. */
1356 tcase_add_test(tc_basic
, test_french_charref_hexidecimal
);
1357 tcase_add_test(tc_basic
, test_french_charref_decimal
);
1358 tcase_add_test(tc_basic
, test_french_latin1
);
1359 tcase_add_test(tc_basic
, test_french_utf8
);
1360 tcase_add_test(tc_basic
, test_utf8_false_rejection
);
1361 tcase_add_test(tc_basic
, test_line_number_after_parse
);
1362 tcase_add_test(tc_basic
, test_column_number_after_parse
);
1363 tcase_add_test(tc_basic
, test_line_and_column_numbers_inside_handlers
);
1364 tcase_add_test(tc_basic
, test_line_number_after_error
);
1365 tcase_add_test(tc_basic
, test_column_number_after_error
);
1366 tcase_add_test(tc_basic
, test_really_long_lines
);
1367 tcase_add_test(tc_basic
, test_end_element_events
);
1368 tcase_add_test(tc_basic
, test_attr_whitespace_normalization
);
1369 tcase_add_test(tc_basic
, test_xmldecl_misplaced
);
1370 tcase_add_test(tc_basic
, test_unknown_encoding_internal_entity
);
1371 tcase_add_test(tc_basic
,
1372 test_wfc_undeclared_entity_unread_external_subset
);
1373 tcase_add_test(tc_basic
, test_wfc_undeclared_entity_no_external_subset
);
1374 tcase_add_test(tc_basic
, test_wfc_undeclared_entity_standalone
);
1375 tcase_add_test(tc_basic
, test_wfc_undeclared_entity_with_external_subset
);
1376 tcase_add_test(tc_basic
,
1377 test_wfc_undeclared_entity_with_external_subset_standalone
);
1378 tcase_add_test(tc_basic
, test_wfc_no_recursive_entity_refs
);
1379 tcase_add_test(tc_basic
, test_ext_entity_set_encoding
);
1380 tcase_add_test(tc_basic
, test_dtd_default_handling
);
1381 tcase_add_test(tc_basic
, test_empty_ns_without_namespaces
);
1382 tcase_add_test(tc_basic
, test_ns_in_attribute_default_without_namespaces
);
1384 suite_add_tcase(s
, tc_namespace
);
1385 tcase_add_checked_fixture(tc_namespace
,
1386 namespace_setup
, namespace_teardown
);
1387 tcase_add_test(tc_namespace
, test_return_ns_triplet
);
1388 tcase_add_test(tc_namespace
, test_ns_tagname_overwrite
);
1389 tcase_add_test(tc_namespace
, test_ns_tagname_overwrite_triplet
);
1390 tcase_add_test(tc_namespace
, test_start_ns_clears_start_element
);
1391 tcase_add_test(tc_namespace
, test_default_ns_from_ext_subset_and_ext_ge
);
1392 tcase_add_test(tc_namespace
, test_ns_prefix_with_empty_uri_1
);
1393 tcase_add_test(tc_namespace
, test_ns_prefix_with_empty_uri_2
);
1394 tcase_add_test(tc_namespace
, test_ns_prefix_with_empty_uri_3
);
1395 tcase_add_test(tc_namespace
, test_ns_prefix_with_empty_uri_4
);
1396 tcase_add_test(tc_namespace
, test_ns_default_with_empty_uri
);
1397 tcase_add_test(tc_namespace
, test_ns_duplicate_attrs_diff_prefixes
);
1398 tcase_add_test(tc_namespace
, test_ns_unbound_prefix_on_attribute
);
1399 tcase_add_test(tc_namespace
, test_ns_unbound_prefix_on_element
);
1405 #ifdef AMIGA_SHARED_LIB
1407 amiga_main(int argc
, char *argv
[])
1410 main(int argc
, char *argv
[])
1414 int forking
= 0, forking_set
= 0;
1415 int verbosity
= CK_NORMAL
;
1416 Suite
*s
= make_suite();
1417 SRunner
*sr
= srunner_create(s
);
1419 /* run the tests for internal helper functions */
1420 testhelper_is_whitespace_normalized();
1422 for (i
= 1; i
< argc
; ++i
) {
1423 char *opt
= argv
[i
];
1424 if (strcmp(opt
, "-v") == 0 || strcmp(opt
, "--verbose") == 0)
1425 verbosity
= CK_VERBOSE
;
1426 else if (strcmp(opt
, "-q") == 0 || strcmp(opt
, "--quiet") == 0)
1427 verbosity
= CK_SILENT
;
1428 else if (strcmp(opt
, "-f") == 0 || strcmp(opt
, "--fork") == 0) {
1432 else if (strcmp(opt
, "-n") == 0 || strcmp(opt
, "--no-fork") == 0) {
1437 fprintf(stderr
, "runtests: unknown option '%s'\n", opt
);
1442 srunner_set_fork_status(sr
, forking
? CK_FORK
: CK_NOFORK
);
1443 if (verbosity
!= CK_SILENT
)
1444 printf("Expat version: %s\n", XML_ExpatVersion());
1445 srunner_run_all(sr
, verbosity
);
1446 nf
= srunner_ntests_failed(sr
);
1449 return (nf
== 0) ? EXIT_SUCCESS
: EXIT_FAILURE
;