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
#if defined(__amigaos__) && defined(__USE_INLINE__)
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)
56
enum XML_Error err = XML_GetErrorCode(parser);
58
" %d: %s (line %" XML_FMT_INT_MOD "u, offset %"\
59
XML_FMT_INT_MOD "u)\n reported from %s, line %d\n",
62
XML_GetCurrentLineNumber(parser),
63
XML_GetCurrentColumnNumber(parser),
65
_fail_unless(0, file, line, buffer);
68
#define xml_failure(parser) _xml_failure((parser), __FILE__, __LINE__)
71
_expect_failure(char *text, enum XML_Error errorCode, char *errorMessage,
72
char *file, int lineno)
74
if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_OK)
75
/* Hackish use of _fail_unless() macro, but let's us report
76
the right filename and line number. */
77
_fail_unless(0, file, lineno, errorMessage);
78
if (XML_GetErrorCode(parser) != errorCode)
79
_xml_failure(parser, file, lineno);
82
#define expect_failure(text, errorCode, errorMessage) \
83
_expect_failure((text), (errorCode), (errorMessage), \
86
/* Dummy handlers for when we need to set a handler to tickle a bug,
87
but it doesn't need to do anything.
91
dummy_start_doctype_handler(void *userData,
92
const XML_Char *doctypeName,
93
const XML_Char *sysid,
94
const XML_Char *pubid,
95
int has_internal_subset)
99
dummy_end_doctype_handler(void *userData)
103
dummy_entity_decl_handler(void *userData,
104
const XML_Char *entityName,
105
int is_parameter_entity,
106
const XML_Char *value,
108
const XML_Char *base,
109
const XML_Char *systemId,
110
const XML_Char *publicId,
111
const XML_Char *notationName)
115
dummy_notation_decl_handler(void *userData,
116
const XML_Char *notationName,
117
const XML_Char *base,
118
const XML_Char *systemId,
119
const XML_Char *publicId)
123
dummy_element_decl_handler(void *userData,
124
const XML_Char *name,
129
dummy_attlist_decl_handler(void *userData,
130
const XML_Char *elname,
131
const XML_Char *attname,
132
const XML_Char *att_type,
133
const XML_Char *dflt,
138
dummy_comment_handler(void *userData, const XML_Char *data)
142
dummy_pi_handler(void *userData, const XML_Char *target, const XML_Char *data)
146
dummy_start_element(void *userData,
147
const XML_Char *name, const XML_Char **atts)
152
* Character & encoding tests.
155
START_TEST(test_nul_byte)
157
char text[] = "<doc>\0</doc>";
159
/* test that a NUL byte (in US-ASCII data) is an error */
160
if (XML_Parse(parser, text, sizeof(text) - 1, XML_TRUE) == XML_STATUS_OK)
161
fail("Parser did not report error on NUL-byte.");
162
if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_TOKEN)
168
START_TEST(test_u0000_char)
170
/* test that a NUL byte (in US-ASCII data) is an error */
171
expect_failure("<doc>�</doc>",
172
XML_ERROR_BAD_CHAR_REF,
173
"Parser did not report error on NUL-byte.");
177
START_TEST(test_bom_utf8)
179
/* This test is really just making sure we don't core on a UTF-8 BOM. */
180
char *text = "\357\273\277<e/>";
182
if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
187
START_TEST(test_bom_utf16_be)
189
char text[] = "\376\377\0<\0e\0/\0>";
191
if (XML_Parse(parser, text, sizeof(text)-1, XML_TRUE) == XML_STATUS_ERROR)
196
START_TEST(test_bom_utf16_le)
198
char text[] = "\377\376<\0e\0/\0>\0";
200
if (XML_Parse(parser, text, sizeof(text)-1, XML_TRUE) == XML_STATUS_ERROR)
206
accumulate_characters(void *userData, const XML_Char *s, int len)
208
CharData_AppendXMLChars((CharData *)userData, s, len);
212
accumulate_attribute(void *userData, const XML_Char *name,
213
const XML_Char **atts)
215
CharData *storage = (CharData *)userData;
216
if (storage->count < 0 && atts != NULL && atts[0] != NULL) {
217
/* "accumulate" the value of the first attribute we see */
218
CharData_AppendXMLChars(storage, atts[1], -1);
224
_run_character_check(XML_Char *text, XML_Char *expected,
225
const char *file, int line)
229
CharData_Init(&storage);
230
XML_SetUserData(parser, &storage);
231
XML_SetCharacterDataHandler(parser, accumulate_characters);
232
if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
233
_xml_failure(parser, file, line);
234
CharData_CheckXMLChars(&storage, expected);
237
#define run_character_check(text, expected) \
238
_run_character_check(text, expected, __FILE__, __LINE__)
241
_run_attribute_check(XML_Char *text, XML_Char *expected,
242
const char *file, int line)
246
CharData_Init(&storage);
247
XML_SetUserData(parser, &storage);
248
XML_SetStartElementHandler(parser, accumulate_attribute);
249
if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
250
_xml_failure(parser, file, line);
251
CharData_CheckXMLChars(&storage, expected);
254
#define run_attribute_check(text, expected) \
255
_run_attribute_check(text, expected, __FILE__, __LINE__)
257
/* Regression test for SF bug #491986. */
258
START_TEST(test_danish_latin1)
261
"<?xml version='1.0' encoding='iso-8859-1'?>\n"
262
"<e>J\xF8rgen \xE6\xF8\xE5\xC6\xD8\xC5</e>";
263
run_character_check(text,
264
"J\xC3\xB8rgen \xC3\xA6\xC3\xB8\xC3\xA5\xC3\x86\xC3\x98\xC3\x85");
269
/* Regression test for SF bug #514281. */
270
START_TEST(test_french_charref_hexidecimal)
273
"<?xml version='1.0' encoding='iso-8859-1'?>\n"
274
"<doc>éèàçêÈ</doc>";
275
run_character_check(text,
276
"\xC3\xA9\xC3\xA8\xC3\xA0\xC3\xA7\xC3\xAA\xC3\x88");
280
START_TEST(test_french_charref_decimal)
283
"<?xml version='1.0' encoding='iso-8859-1'?>\n"
284
"<doc>éèàçêÈ</doc>";
285
run_character_check(text,
286
"\xC3\xA9\xC3\xA8\xC3\xA0\xC3\xA7\xC3\xAA\xC3\x88");
290
START_TEST(test_french_latin1)
293
"<?xml version='1.0' encoding='iso-8859-1'?>\n"
294
"<doc>\xE9\xE8\xE0\xE7\xEa\xC8</doc>";
295
run_character_check(text,
296
"\xC3\xA9\xC3\xA8\xC3\xA0\xC3\xA7\xC3\xAA\xC3\x88");
300
START_TEST(test_french_utf8)
303
"<?xml version='1.0' encoding='utf-8'?>\n"
304
"<doc>\xC3\xA9</doc>";
305
run_character_check(text, "\xC3\xA9");
309
/* Regression test for SF bug #600479.
310
XXX There should be a test that exercises all legal XML Unicode
311
characters as PCDATA and attribute value content, and XML Name
312
characters as part of element and attribute names.
314
START_TEST(test_utf8_false_rejection)
316
char *text = "<doc>\xEF\xBA\xBF</doc>";
317
run_character_check(text, "\xEF\xBA\xBF");
321
/* Regression test for SF bug #477667.
322
This test assures that any 8-bit character followed by a 7-bit
323
character will not be mistakenly interpreted as a valid UTF-8
326
START_TEST(test_illegal_utf8)
331
for (i = 128; i <= 255; ++i) {
332
sprintf(text, "<e>%ccd</e>", i);
333
if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_OK) {
335
"expected token error for '%c' (ordinal %d) in UTF-8 text",
339
else if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_TOKEN)
341
/* Reset the parser since we use the same parser repeatedly. */
342
XML_ParserReset(parser, NULL);
347
START_TEST(test_utf16)
349
/* <?xml version="1.0" encoding="UTF-16"?>
350
<doc a='123'>some text</doc>
353
"\000<\000?\000x\000m\000\154\000 \000v\000e\000r\000s\000i\000o"
354
"\000n\000=\000'\0001\000.\000\060\000'\000 \000e\000n\000c\000o"
355
"\000d\000i\000n\000g\000=\000'\000U\000T\000F\000-\0001\000\066"
356
"\000'\000?\000>\000\n"
357
"\000<\000d\000o\000c\000 \000a\000=\000'\0001\0002\0003\000'"
358
"\000>\000s\000o\000m\000e\000 \000t\000e\000x\000t\000<\000/"
359
"\000d\000o\000c\000>";
360
if (XML_Parse(parser, text, sizeof(text)-1, XML_TRUE) == XML_STATUS_ERROR)
365
START_TEST(test_utf16_le_epilog_newline)
367
unsigned int first_chunk_bytes = 17;
370
"<\000e\000/\000>\000" /* document element */
371
"\r\000\n\000\r\000\n\000"; /* epilog */
373
if (first_chunk_bytes >= sizeof(text) - 1)
374
fail("bad value of first_chunk_bytes");
375
if ( XML_Parse(parser, text, first_chunk_bytes, XML_FALSE)
380
rc = XML_Parse(parser, text + first_chunk_bytes,
381
sizeof(text) - first_chunk_bytes - 1, XML_TRUE);
382
if (rc == XML_STATUS_ERROR)
388
/* Regression test for SF bug #481609, #774028. */
389
START_TEST(test_latin1_umlauts)
392
"<?xml version='1.0' encoding='iso-8859-1'?>\n"
393
"<e a='\xE4 \xF6 \xFC ä ö ü ä ö ü >'\n"
394
" >\xE4 \xF6 \xFC ä ö ü ä ö ü ></e>";
396
"\xC3\xA4 \xC3\xB6 \xC3\xBC "
397
"\xC3\xA4 \xC3\xB6 \xC3\xBC "
398
"\xC3\xA4 \xC3\xB6 \xC3\xBC >";
399
run_character_check(text, utf8);
400
XML_ParserReset(parser, NULL);
401
run_attribute_check(text, utf8);
405
/* Regression test #1 for SF bug #653180. */
406
START_TEST(test_line_number_after_parse)
414
if (XML_Parse(parser, text, strlen(text), XML_FALSE) == XML_STATUS_ERROR)
416
lineno = XML_GetCurrentLineNumber(parser);
420
"expected 4 lines, saw %" XML_FMT_INT_MOD "u", lineno);
426
/* Regression test #2 for SF bug #653180. */
427
START_TEST(test_column_number_after_parse)
429
char *text = "<tag></tag>";
432
if (XML_Parse(parser, text, strlen(text), XML_FALSE) == XML_STATUS_ERROR)
434
colno = XML_GetCurrentColumnNumber(parser);
438
"expected 11 columns, saw %" XML_FMT_INT_MOD "u", colno);
445
start_element_event_handler2(void *userData, const XML_Char *name,
446
const XML_Char **attr)
448
CharData *storage = (CharData *) userData;
452
"<%s> at col:%" XML_FMT_INT_MOD "u line:%"\
453
XML_FMT_INT_MOD "u\n", name,
454
XML_GetCurrentColumnNumber(parser),
455
XML_GetCurrentLineNumber(parser));
456
CharData_AppendString(storage, buffer);
460
end_element_event_handler2(void *userData, const XML_Char *name)
462
CharData *storage = (CharData *) userData;
466
"</%s> at col:%" XML_FMT_INT_MOD "u line:%"\
467
XML_FMT_INT_MOD "u\n", name,
468
XML_GetCurrentColumnNumber(parser),
469
XML_GetCurrentLineNumber(parser));
470
CharData_AppendString(storage, buffer);
473
/* Regression test #3 for SF bug #653180. */
474
START_TEST(test_line_and_column_numbers_inside_handlers)
477
"<a>\n" /* Unix end-of-line */
478
" <b>\r\n" /* Windows end-of-line */
479
" <c/>\r" /* Mac OS end-of-line */
486
"<a> at col:0 line:1\n"
487
"<b> at col:2 line:2\n"
488
"<c> at col:4 line:3\n"
489
"</c> at col:8 line:3\n"
490
"</b> at col:2 line:4\n"
491
"<d> at col:2 line:5\n"
492
"<f> at col:4 line:6\n"
493
"</f> at col:8 line:6\n"
494
"</d> at col:2 line:7\n"
495
"</a> at col:0 line:8\n";
498
CharData_Init(&storage);
499
XML_SetUserData(parser, &storage);
500
XML_SetStartElementHandler(parser, start_element_event_handler2);
501
XML_SetEndElementHandler(parser, end_element_event_handler2);
502
if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
505
CharData_CheckString(&storage, expected);
509
/* Regression test #4 for SF bug #653180. */
510
START_TEST(test_line_number_after_error)
515
" </a>"; /* missing </b> */
517
if (XML_Parse(parser, text, strlen(text), XML_FALSE) != XML_STATUS_ERROR)
518
fail("Expected a parse error");
520
lineno = XML_GetCurrentLineNumber(parser);
523
sprintf(buffer, "expected 3 lines, saw %" XML_FMT_INT_MOD "u", lineno);
529
/* Regression test #5 for SF bug #653180. */
530
START_TEST(test_column_number_after_error)
535
" </a>"; /* missing </b> */
537
if (XML_Parse(parser, text, strlen(text), XML_FALSE) != XML_STATUS_ERROR)
538
fail("Expected a parse error");
540
colno = XML_GetCurrentColumnNumber(parser);
544
"expected 4 columns, saw %" XML_FMT_INT_MOD "u", colno);
550
/* Regression test for SF bug #478332. */
551
START_TEST(test_really_long_lines)
553
/* This parses an input line longer than INIT_DATA_BUF_SIZE
554
characters long (defined to be 1024 in xmlparse.c). We take a
555
really cheesy approach to building the input buffer, because
556
this avoids writing bugs in buffer-filling code.
561
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
562
/* until we have at least 1024 characters on the line: */
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-+"
577
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
578
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
580
if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
587
* Element event tests.
591
end_element_event_handler(void *userData, const XML_Char *name)
593
CharData *storage = (CharData *) userData;
594
CharData_AppendString(storage, "/");
595
CharData_AppendXMLChars(storage, name, -1);
598
START_TEST(test_end_element_events)
600
char *text = "<a><b><c/></b><d><f/></d></a>";
601
char *expected = "/c/b/f/d/a";
604
CharData_Init(&storage);
605
XML_SetUserData(parser, &storage);
606
XML_SetEndElementHandler(parser, end_element_event_handler);
607
if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
609
CharData_CheckString(&storage, expected);
618
/* Helpers used by the following test; this checks any "attr" and "refs"
619
attributes to make sure whitespace has been normalized.
621
Return true if whitespace has been normalized in a string, using
622
the rules for attribute value normalization. The 'is_cdata' flag
623
is needed since CDATA attributes don't need to have multiple
624
whitespace characters collapsed to a single space, while other
625
attribute data types do. (Section 3.3.3 of the recommendation.)
628
is_whitespace_normalized(const XML_Char *s, int is_cdata)
635
else if (*s == '\t' || *s == '\n' || *s == '\r')
640
if (blanks && !is_cdata)
641
/* illegal leading blanks */
644
else if (blanks > 1 && !is_cdata)
650
if (blanks && !is_cdata)
655
/* Check the attribute whitespace checker: */
657
testhelper_is_whitespace_normalized(void)
659
assert(is_whitespace_normalized("abc", 0));
660
assert(is_whitespace_normalized("abc", 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("abc def ghi ", 0));
668
assert(is_whitespace_normalized("abc def ghi ", 1));
669
assert(!is_whitespace_normalized(" ", 0));
670
assert(is_whitespace_normalized(" ", 1));
671
assert(!is_whitespace_normalized("\t", 0));
672
assert(!is_whitespace_normalized("\t", 1));
673
assert(!is_whitespace_normalized("\n", 0));
674
assert(!is_whitespace_normalized("\n", 1));
675
assert(!is_whitespace_normalized("\r", 0));
676
assert(!is_whitespace_normalized("\r", 1));
677
assert(!is_whitespace_normalized("abc\t def", 1));
681
check_attr_contains_normalized_whitespace(void *userData,
682
const XML_Char *name,
683
const XML_Char **atts)
686
for (i = 0; atts[i] != NULL; i += 2) {
687
const XML_Char *attrname = atts[i];
688
const XML_Char *value = atts[i + 1];
689
if (strcmp("attr", attrname) == 0
690
|| strcmp("ents", attrname) == 0
691
|| strcmp("refs", attrname) == 0) {
692
if (!is_whitespace_normalized(value, 0)) {
694
sprintf(buffer, "attribute value not normalized: %s='%s'",
702
START_TEST(test_attr_whitespace_normalization)
707
" attr NMTOKENS #REQUIRED\n"
708
" ents ENTITIES #REQUIRED\n"
709
" refs IDREFS #REQUIRED>\n"
711
"<doc attr=' a b c\t\td\te\t' refs=' id-1 \t id-2\t\t' \n"
712
" ents=' ent-1 \t\r\n"
718
XML_SetStartElementHandler(parser,
719
check_attr_contains_normalized_whitespace);
720
if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
727
* XML declaration tests.
730
START_TEST(test_xmldecl_misplaced)
733
"<?xml version='1.0'?>\n"
735
XML_ERROR_MISPLACED_XML_PI,
736
"failed to report misplaced XML declaration");
740
/* Regression test for SF bug #584832. */
742
UnknownEncodingHandler(void *data,const XML_Char *encoding,XML_Encoding *info)
744
if (strcmp(encoding,"unsupported-encoding") == 0) {
746
for (i = 0; i < 256; ++i)
749
info->convert = NULL;
750
info->release = NULL;
751
return XML_STATUS_OK;
753
return XML_STATUS_ERROR;
756
START_TEST(test_unknown_encoding_internal_entity)
759
"<?xml version='1.0' encoding='unsupported-encoding'?>\n"
760
"<!DOCTYPE test [<!ENTITY foo 'bar'>]>\n"
763
XML_SetUnknownEncodingHandler(parser, UnknownEncodingHandler, NULL);
764
if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
769
/* Regression test for SF bug #620106. */
771
external_entity_loader_set_encoding(XML_Parser parser,
772
const XML_Char *context,
773
const XML_Char *base,
774
const XML_Char *systemId,
775
const XML_Char *publicId)
777
/* This text says it's an unsupported encoding, but it's really
778
UTF-8, which we tell Expat using XML_SetEncoding().
781
"<?xml encoding='iso-8859-3'?>"
783
XML_Parser extparser;
785
extparser = XML_ExternalEntityParserCreate(parser, context, NULL);
786
if (extparser == NULL)
787
fail("Could not create external entity parser.");
788
if (!XML_SetEncoding(extparser, "utf-8"))
789
fail("XML_SetEncoding() ignored for external entity");
790
if ( XML_Parse(extparser, text, strlen(text), XML_TRUE)
791
== XML_STATUS_ERROR) {
798
START_TEST(test_ext_entity_set_encoding)
802
" <!ENTITY en SYSTEM 'http://xml.libexpat.org/dummy.ent'>\n"
806
XML_SetExternalEntityRefHandler(parser,
807
external_entity_loader_set_encoding);
808
run_character_check(text, "\xC3\xA9");
812
/* Test that no error is reported for unknown entities if we don't
813
read an external subset. This was fixed in Expat 1.95.5.
815
START_TEST(test_wfc_undeclared_entity_unread_external_subset) {
817
"<!DOCTYPE doc SYSTEM 'foo'>\n"
818
"<doc>&entity;</doc>";
820
if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
825
/* Test that an error is reported for unknown entities if we don't
826
have an external subset.
828
START_TEST(test_wfc_undeclared_entity_no_external_subset) {
829
expect_failure("<doc>&entity;</doc>",
830
XML_ERROR_UNDEFINED_ENTITY,
831
"Parser did not report undefined entity w/out a DTD.");
835
/* Test that an error is reported for unknown entities if we don't
836
read an external subset, but have been declared standalone.
838
START_TEST(test_wfc_undeclared_entity_standalone) {
840
"<?xml version='1.0' encoding='us-ascii' standalone='yes'?>\n"
841
"<!DOCTYPE doc SYSTEM 'foo'>\n"
842
"<doc>&entity;</doc>";
845
XML_ERROR_UNDEFINED_ENTITY,
846
"Parser did not report undefined entity (standalone).");
851
external_entity_loader(XML_Parser parser,
852
const XML_Char *context,
853
const XML_Char *base,
854
const XML_Char *systemId,
855
const XML_Char *publicId)
857
char *text = (char *)XML_GetUserData(parser);
858
XML_Parser extparser;
860
extparser = XML_ExternalEntityParserCreate(parser, context, NULL);
861
if (extparser == NULL)
862
fail("Could not create external entity parser.");
863
if ( XML_Parse(extparser, text, strlen(text), XML_TRUE)
864
== XML_STATUS_ERROR) {
866
return XML_STATUS_ERROR;
868
return XML_STATUS_OK;
871
/* Test that an error is reported for unknown entities if we have read
872
an external subset, and standalone is true.
874
START_TEST(test_wfc_undeclared_entity_with_external_subset_standalone) {
876
"<?xml version='1.0' encoding='us-ascii' standalone='yes'?>\n"
877
"<!DOCTYPE doc SYSTEM 'foo'>\n"
878
"<doc>&entity;</doc>";
880
"<!ELEMENT doc (#PCDATA)*>";
882
XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
883
XML_SetUserData(parser, foo_text);
884
XML_SetExternalEntityRefHandler(parser, external_entity_loader);
886
XML_ERROR_UNDEFINED_ENTITY,
887
"Parser did not report undefined entity (external DTD).");
891
/* Test that no error is reported for unknown entities if we have read
892
an external subset, and standalone is false.
894
START_TEST(test_wfc_undeclared_entity_with_external_subset) {
896
"<?xml version='1.0' encoding='us-ascii'?>\n"
897
"<!DOCTYPE doc SYSTEM 'foo'>\n"
898
"<doc>&entity;</doc>";
900
"<!ELEMENT doc (#PCDATA)*>";
902
XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
903
XML_SetUserData(parser, foo_text);
904
XML_SetExternalEntityRefHandler(parser, external_entity_loader);
905
if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
910
START_TEST(test_wfc_no_recursive_entity_refs)
914
" <!ENTITY entity '&entity;'>\n"
916
"<doc>&entity;</doc>";
919
XML_ERROR_RECURSIVE_ENTITY_REF,
920
"Parser did not report recursive entity reference.");
924
/* Regression test for SF bug #483514. */
925
START_TEST(test_dtd_default_handling)
929
"<!ENTITY e SYSTEM 'http://xml.libexpat.org/e'>\n"
930
"<!NOTATION n SYSTEM 'http://xml.libexpat.org/n'>\n"
931
"<!ELEMENT doc EMPTY>\n"
932
"<!ATTLIST doc a CDATA #IMPLIED>\n"
934
"<!--comment in dtd-->\n"
937
XML_SetDefaultHandler(parser, accumulate_characters);
938
XML_SetDoctypeDeclHandler(parser,
939
dummy_start_doctype_handler,
940
dummy_end_doctype_handler);
941
XML_SetEntityDeclHandler(parser, dummy_entity_decl_handler);
942
XML_SetNotationDeclHandler(parser, dummy_notation_decl_handler);
943
XML_SetElementDeclHandler(parser, dummy_element_decl_handler);
944
XML_SetAttlistDeclHandler(parser, dummy_attlist_decl_handler);
945
XML_SetProcessingInstructionHandler(parser, dummy_pi_handler);
946
XML_SetCommentHandler(parser, dummy_comment_handler);
947
run_character_check(text, "\n\n\n\n\n\n\n<doc/>");
951
/* See related SF bug #673791.
952
When namespace processing is enabled, setting the namespace URI for
953
a prefix is not allowed; this test ensures that it *is* allowed
954
when namespace processing is not enabled.
955
(See Namespaces in XML, section 2.)
957
START_TEST(test_empty_ns_without_namespaces)
960
"<doc xmlns:prefix='http://www.example.com/'>\n"
961
" <e xmlns:prefix=''/>\n"
964
if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
969
/* Regression test for SF bug #824420.
970
Checks that an xmlns:prefix attribute set in an attribute's default
971
value isn't misinterpreted.
973
START_TEST(test_ns_in_attribute_default_without_namespaces)
976
"<!DOCTYPE e:element [\n"
977
" <!ATTLIST e:element\n"
978
" xmlns:e CDATA 'http://example.com/'>\n"
982
if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
987
static char *long_character_data_text =
988
"<?xml version='1.0' encoding='iso-8859-1'?><s>"
989
"012345678901234567890123456789012345678901234567890123456789"
990
"012345678901234567890123456789012345678901234567890123456789"
991
"012345678901234567890123456789012345678901234567890123456789"
992
"012345678901234567890123456789012345678901234567890123456789"
993
"012345678901234567890123456789012345678901234567890123456789"
994
"012345678901234567890123456789012345678901234567890123456789"
995
"012345678901234567890123456789012345678901234567890123456789"
996
"012345678901234567890123456789012345678901234567890123456789"
997
"012345678901234567890123456789012345678901234567890123456789"
998
"012345678901234567890123456789012345678901234567890123456789"
999
"012345678901234567890123456789012345678901234567890123456789"
1000
"012345678901234567890123456789012345678901234567890123456789"
1001
"012345678901234567890123456789012345678901234567890123456789"
1002
"012345678901234567890123456789012345678901234567890123456789"
1003
"012345678901234567890123456789012345678901234567890123456789"
1004
"012345678901234567890123456789012345678901234567890123456789"
1005
"012345678901234567890123456789012345678901234567890123456789"
1006
"012345678901234567890123456789012345678901234567890123456789"
1007
"012345678901234567890123456789012345678901234567890123456789"
1008
"012345678901234567890123456789012345678901234567890123456789"
1011
static XML_Bool resumable = XML_FALSE;
1014
clearing_aborting_character_handler(void *userData,
1015
const XML_Char *s, int len)
1017
XML_StopParser(parser, resumable);
1018
XML_SetCharacterDataHandler(parser, NULL);
1021
/* Regression test for SF bug #1515266: missing check of stopped
1022
parser in doContext() 'for' loop. */
1023
START_TEST(test_stop_parser_between_char_data_calls)
1025
/* The sample data must be big enough that there are two calls to
1026
the character data handler from within the inner "for" loop of
1027
the XML_TOK_DATA_CHARS case in doContent(), and the character
1028
handler must stop the parser and clear the character data
1031
char *text = long_character_data_text;
1033
XML_SetCharacterDataHandler(parser, clearing_aborting_character_handler);
1034
resumable = XML_FALSE;
1035
if (XML_Parse(parser, text, strlen(text), XML_TRUE) != XML_STATUS_ERROR)
1036
xml_failure(parser);
1037
if (XML_GetErrorCode(parser) != XML_ERROR_ABORTED)
1038
xml_failure(parser);
1042
/* Regression test for SF bug #1515266: missing check of stopped
1043
parser in doContext() 'for' loop. */
1044
START_TEST(test_suspend_parser_between_char_data_calls)
1046
/* The sample data must be big enough that there are two calls to
1047
the character data handler from within the inner "for" loop of
1048
the XML_TOK_DATA_CHARS case in doContent(), and the character
1049
handler must stop the parser and clear the character data
1052
char *text = long_character_data_text;
1054
XML_SetCharacterDataHandler(parser, clearing_aborting_character_handler);
1055
resumable = XML_TRUE;
1056
if (XML_Parse(parser, text, strlen(text), XML_TRUE) != XML_STATUS_SUSPENDED)
1057
xml_failure(parser);
1058
if (XML_GetErrorCode(parser) != XML_ERROR_NONE)
1059
xml_failure(parser);
1069
namespace_setup(void)
1071
parser = XML_ParserCreateNS(NULL, ' ');
1073
fail("Parser not created.");
1077
namespace_teardown(void)
1082
/* Check that an element name and attribute name match the expected values.
1083
The expected values are passed as an array reference of string pointers
1084
provided as the userData argument; the first is the expected
1085
element name, and the second is the expected attribute name.
1088
triplet_start_checker(void *userData, const XML_Char *name,
1089
const XML_Char **atts)
1091
char **elemstr = (char **)userData;
1093
if (strcmp(elemstr[0], name) != 0) {
1094
sprintf(buffer, "unexpected start string: '%s'", name);
1097
if (strcmp(elemstr[1], atts[0]) != 0) {
1098
sprintf(buffer, "unexpected attribute string: '%s'", atts[0]);
1103
/* Check that the element name passed to the end-element handler matches
1104
the expected value. The expected value is passed as the first element
1105
in an array of strings passed as the userData argument.
1108
triplet_end_checker(void *userData, const XML_Char *name)
1110
char **elemstr = (char **)userData;
1111
if (strcmp(elemstr[0], name) != 0) {
1113
sprintf(buffer, "unexpected end string: '%s'", name);
1118
START_TEST(test_return_ns_triplet)
1121
"<foo:e xmlns:foo='http://expat.sf.net/' bar:a='12'\n"
1122
" xmlns:bar='http://expat.sf.net/'></foo:e>";
1124
"http://expat.sf.net/ e foo",
1125
"http://expat.sf.net/ a bar"
1127
XML_SetReturnNSTriplet(parser, XML_TRUE);
1128
XML_SetUserData(parser, elemstr);
1129
XML_SetElementHandler(parser, triplet_start_checker, triplet_end_checker);
1130
if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
1131
xml_failure(parser);
1136
overwrite_start_checker(void *userData, const XML_Char *name,
1137
const XML_Char **atts)
1139
CharData *storage = (CharData *) userData;
1140
CharData_AppendString(storage, "start ");
1141
CharData_AppendXMLChars(storage, name, -1);
1142
while (*atts != NULL) {
1143
CharData_AppendString(storage, "\nattribute ");
1144
CharData_AppendXMLChars(storage, *atts, -1);
1147
CharData_AppendString(storage, "\n");
1151
overwrite_end_checker(void *userData, const XML_Char *name)
1153
CharData *storage = (CharData *) userData;
1154
CharData_AppendString(storage, "end ");
1155
CharData_AppendXMLChars(storage, name, -1);
1156
CharData_AppendString(storage, "\n");
1160
run_ns_tagname_overwrite_test(char *text, char *result)
1163
CharData_Init(&storage);
1164
XML_SetUserData(parser, &storage);
1165
XML_SetElementHandler(parser,
1166
overwrite_start_checker, overwrite_end_checker);
1167
if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
1168
xml_failure(parser);
1169
CharData_CheckString(&storage, result);
1172
/* Regression test for SF bug #566334. */
1173
START_TEST(test_ns_tagname_overwrite)
1176
"<n:e xmlns:n='http://xml.libexpat.org/'>\n"
1177
" <n:f n:attr='foo'/>\n"
1178
" <n:g n:attr2='bar'/>\n"
1181
"start http://xml.libexpat.org/ e\n"
1182
"start http://xml.libexpat.org/ f\n"
1183
"attribute http://xml.libexpat.org/ attr\n"
1184
"end http://xml.libexpat.org/ f\n"
1185
"start http://xml.libexpat.org/ g\n"
1186
"attribute http://xml.libexpat.org/ attr2\n"
1187
"end http://xml.libexpat.org/ g\n"
1188
"end http://xml.libexpat.org/ e\n";
1189
run_ns_tagname_overwrite_test(text, result);
1193
/* Regression test for SF bug #566334. */
1194
START_TEST(test_ns_tagname_overwrite_triplet)
1197
"<n:e xmlns:n='http://xml.libexpat.org/'>\n"
1198
" <n:f n:attr='foo'/>\n"
1199
" <n:g n:attr2='bar'/>\n"
1202
"start http://xml.libexpat.org/ e n\n"
1203
"start http://xml.libexpat.org/ f n\n"
1204
"attribute http://xml.libexpat.org/ attr n\n"
1205
"end http://xml.libexpat.org/ f n\n"
1206
"start http://xml.libexpat.org/ g n\n"
1207
"attribute http://xml.libexpat.org/ attr2 n\n"
1208
"end http://xml.libexpat.org/ g n\n"
1209
"end http://xml.libexpat.org/ e n\n";
1210
XML_SetReturnNSTriplet(parser, XML_TRUE);
1211
run_ns_tagname_overwrite_test(text, result);
1216
/* Regression test for SF bug #620343. */
1218
start_element_fail(void *userData,
1219
const XML_Char *name, const XML_Char **atts)
1221
/* We should never get here. */
1222
fail("should never reach start_element_fail()");
1226
start_ns_clearing_start_element(void *userData,
1227
const XML_Char *prefix,
1228
const XML_Char *uri)
1230
XML_SetStartElementHandler((XML_Parser) userData, NULL);
1233
START_TEST(test_start_ns_clears_start_element)
1235
/* This needs to use separate start/end tags; using the empty tag
1236
syntax doesn't cause the problematic path through Expat to be
1239
char *text = "<e xmlns='http://xml.libexpat.org/'></e>";
1241
XML_SetStartElementHandler(parser, start_element_fail);
1242
XML_SetStartNamespaceDeclHandler(parser, start_ns_clearing_start_element);
1243
XML_UseParserAsHandlerArg(parser);
1244
if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
1245
xml_failure(parser);
1249
/* Regression test for SF bug #616863. */
1251
external_entity_handler(XML_Parser parser,
1252
const XML_Char *context,
1253
const XML_Char *base,
1254
const XML_Char *systemId,
1255
const XML_Char *publicId)
1257
long callno = 1 + (long)XML_GetUserData(parser);
1262
text = ("<!ELEMENT doc (e+)>\n"
1263
"<!ATTLIST doc xmlns CDATA #IMPLIED>\n"
1264
"<!ELEMENT e EMPTY>\n");
1266
text = ("<?xml version='1.0' encoding='us-ascii'?>"
1269
XML_SetUserData(parser, (void *) callno);
1270
p2 = XML_ExternalEntityParserCreate(parser, context, NULL);
1271
if (XML_Parse(p2, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) {
1279
START_TEST(test_default_ns_from_ext_subset_and_ext_ge)
1282
"<?xml version='1.0'?>\n"
1283
"<!DOCTYPE doc SYSTEM 'http://xml.libexpat.org/doc.dtd' [\n"
1284
" <!ENTITY en SYSTEM 'http://xml.libexpat.org/entity.ent'>\n"
1286
"<doc xmlns='http://xml.libexpat.org/ns1'>\n"
1290
XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
1291
XML_SetExternalEntityRefHandler(parser, external_entity_handler);
1292
/* We actually need to set this handler to tickle this bug. */
1293
XML_SetStartElementHandler(parser, dummy_start_element);
1294
XML_SetUserData(parser, NULL);
1295
if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
1296
xml_failure(parser);
1300
/* Regression test #1 for SF bug #673791. */
1301
START_TEST(test_ns_prefix_with_empty_uri_1)
1304
"<doc xmlns:prefix='http://xml.libexpat.org/'>\n"
1305
" <e xmlns:prefix=''/>\n"
1308
expect_failure(text,
1309
XML_ERROR_UNDECLARING_PREFIX,
1310
"Did not report re-setting namespace"
1311
" URI with prefix to ''.");
1315
/* Regression test #2 for SF bug #673791. */
1316
START_TEST(test_ns_prefix_with_empty_uri_2)
1319
"<?xml version='1.0'?>\n"
1320
"<docelem xmlns:pre=''/>";
1322
expect_failure(text,
1323
XML_ERROR_UNDECLARING_PREFIX,
1324
"Did not report setting namespace URI with prefix to ''.");
1328
/* Regression test #3 for SF bug #673791. */
1329
START_TEST(test_ns_prefix_with_empty_uri_3)
1333
" <!ELEMENT doc EMPTY>\n"
1335
" xmlns:prefix CDATA ''>\n"
1339
expect_failure(text,
1340
XML_ERROR_UNDECLARING_PREFIX,
1341
"Didn't report attr default setting NS w/ prefix to ''.");
1345
/* Regression test #4 for SF bug #673791. */
1346
START_TEST(test_ns_prefix_with_empty_uri_4)
1350
" <!ELEMENT prefix:doc EMPTY>\n"
1351
" <!ATTLIST prefix:doc\n"
1352
" xmlns:prefix CDATA 'http://xml.libexpat.org/'>\n"
1355
/* Packaged info expected by the end element handler;
1356
the weird structuring lets us re-use the triplet_end_checker()
1357
function also used for another test. */
1359
"http://xml.libexpat.org/ doc prefix"
1361
XML_SetReturnNSTriplet(parser, XML_TRUE);
1362
XML_SetUserData(parser, elemstr);
1363
XML_SetEndElementHandler(parser, triplet_end_checker);
1364
if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
1365
xml_failure(parser);
1369
START_TEST(test_ns_default_with_empty_uri)
1372
"<doc xmlns='http://xml.libexpat.org/'>\n"
1375
if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
1376
xml_failure(parser);
1380
/* Regression test for SF bug #692964: two prefixes for one namespace. */
1381
START_TEST(test_ns_duplicate_attrs_diff_prefixes)
1384
"<doc xmlns:a='http://xml.libexpat.org/a'\n"
1385
" xmlns:b='http://xml.libexpat.org/a'\n"
1386
" a:a='v' b:a='v' />";
1387
expect_failure(text,
1388
XML_ERROR_DUPLICATE_ATTRIBUTE,
1389
"did not report multiple attributes with same URI+name");
1393
/* Regression test for SF bug #695401: unbound prefix. */
1394
START_TEST(test_ns_unbound_prefix_on_attribute)
1396
char *text = "<doc a:attr=''/>";
1397
expect_failure(text,
1398
XML_ERROR_UNBOUND_PREFIX,
1399
"did not report unbound prefix on attribute");
1403
/* Regression test for SF bug #695401: unbound prefix. */
1404
START_TEST(test_ns_unbound_prefix_on_element)
1406
char *text = "<a:doc/>";
1407
expect_failure(text,
1408
XML_ERROR_UNBOUND_PREFIX,
1409
"did not report unbound prefix on element");
1416
Suite *s = suite_create("basic");
1417
TCase *tc_basic = tcase_create("basic tests");
1418
TCase *tc_namespace = tcase_create("XML namespaces");
1420
suite_add_tcase(s, tc_basic);
1421
tcase_add_checked_fixture(tc_basic, basic_setup, basic_teardown);
1422
tcase_add_test(tc_basic, test_nul_byte);
1423
tcase_add_test(tc_basic, test_u0000_char);
1424
tcase_add_test(tc_basic, test_bom_utf8);
1425
tcase_add_test(tc_basic, test_bom_utf16_be);
1426
tcase_add_test(tc_basic, test_bom_utf16_le);
1427
tcase_add_test(tc_basic, test_illegal_utf8);
1428
tcase_add_test(tc_basic, test_utf16);
1429
tcase_add_test(tc_basic, test_utf16_le_epilog_newline);
1430
tcase_add_test(tc_basic, test_latin1_umlauts);
1431
/* Regression test for SF bug #491986. */
1432
tcase_add_test(tc_basic, test_danish_latin1);
1433
/* Regression test for SF bug #514281. */
1434
tcase_add_test(tc_basic, test_french_charref_hexidecimal);
1435
tcase_add_test(tc_basic, test_french_charref_decimal);
1436
tcase_add_test(tc_basic, test_french_latin1);
1437
tcase_add_test(tc_basic, test_french_utf8);
1438
tcase_add_test(tc_basic, test_utf8_false_rejection);
1439
tcase_add_test(tc_basic, test_line_number_after_parse);
1440
tcase_add_test(tc_basic, test_column_number_after_parse);
1441
tcase_add_test(tc_basic, test_line_and_column_numbers_inside_handlers);
1442
tcase_add_test(tc_basic, test_line_number_after_error);
1443
tcase_add_test(tc_basic, test_column_number_after_error);
1444
tcase_add_test(tc_basic, test_really_long_lines);
1445
tcase_add_test(tc_basic, test_end_element_events);
1446
tcase_add_test(tc_basic, test_attr_whitespace_normalization);
1447
tcase_add_test(tc_basic, test_xmldecl_misplaced);
1448
tcase_add_test(tc_basic, test_unknown_encoding_internal_entity);
1449
tcase_add_test(tc_basic,
1450
test_wfc_undeclared_entity_unread_external_subset);
1451
tcase_add_test(tc_basic, test_wfc_undeclared_entity_no_external_subset);
1452
tcase_add_test(tc_basic, test_wfc_undeclared_entity_standalone);
1453
tcase_add_test(tc_basic, test_wfc_undeclared_entity_with_external_subset);
1454
tcase_add_test(tc_basic,
1455
test_wfc_undeclared_entity_with_external_subset_standalone);
1456
tcase_add_test(tc_basic, test_wfc_no_recursive_entity_refs);
1457
tcase_add_test(tc_basic, test_ext_entity_set_encoding);
1458
tcase_add_test(tc_basic, test_dtd_default_handling);
1459
tcase_add_test(tc_basic, test_empty_ns_without_namespaces);
1460
tcase_add_test(tc_basic, test_ns_in_attribute_default_without_namespaces);
1461
tcase_add_test(tc_basic, test_stop_parser_between_char_data_calls);
1462
tcase_add_test(tc_basic, test_suspend_parser_between_char_data_calls);
1464
suite_add_tcase(s, tc_namespace);
1465
tcase_add_checked_fixture(tc_namespace,
1466
namespace_setup, namespace_teardown);
1467
tcase_add_test(tc_namespace, test_return_ns_triplet);
1468
tcase_add_test(tc_namespace, test_ns_tagname_overwrite);
1469
tcase_add_test(tc_namespace, test_ns_tagname_overwrite_triplet);
1470
tcase_add_test(tc_namespace, test_start_ns_clears_start_element);
1471
tcase_add_test(tc_namespace, test_default_ns_from_ext_subset_and_ext_ge);
1472
tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_1);
1473
tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_2);
1474
tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_3);
1475
tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_4);
1476
tcase_add_test(tc_namespace, test_ns_default_with_empty_uri);
1477
tcase_add_test(tc_namespace, test_ns_duplicate_attrs_diff_prefixes);
1478
tcase_add_test(tc_namespace, test_ns_unbound_prefix_on_attribute);
1479
tcase_add_test(tc_namespace, test_ns_unbound_prefix_on_element);
1486
main(int argc, char *argv[])
1489
int verbosity = CK_NORMAL;
1490
Suite *s = make_suite();
1491
SRunner *sr = srunner_create(s);
1493
/* run the tests for internal helper functions */
1494
testhelper_is_whitespace_normalized();
1496
for (i = 1; i < argc; ++i) {
1497
char *opt = argv[i];
1498
if (strcmp(opt, "-v") == 0 || strcmp(opt, "--verbose") == 0)
1499
verbosity = CK_VERBOSE;
1500
else if (strcmp(opt, "-q") == 0 || strcmp(opt, "--quiet") == 0)
1501
verbosity = CK_SILENT;
1503
fprintf(stderr, "runtests: unknown option '%s'\n", opt);
1507
if (verbosity != CK_SILENT)
1508
printf("Expat version: %s\n", XML_ExpatVersion());
1509
srunner_run_all(sr, verbosity);
1510
nf = srunner_ntests_failed(sr);
1513
return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;