Re-introducing the old "indef..endif" logic, but using "?=", as ifndef is only
[mirror-ossqm-expat.git] / tests / runtests.c
blobfdb33c29eb1cd2561a03356708c77576dff2507e
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
5 */
7 #ifdef HAVE_EXPAT_CONFIG_H
8 #include <expat_config.h>
9 #endif
11 #include <assert.h>
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <string.h>
16 #include "expat.h"
17 #include "chardata.h"
18 #include "minicheck.h"
20 #ifdef AMIGA_SHARED_LIB
21 #include <proto/expat.h>
22 #endif
24 #ifdef XML_LARGE_SIZE
25 #define XML_FMT_INT_MOD "ll"
26 #else
27 #define XML_FMT_INT_MOD "l"
28 #endif
30 static XML_Parser parser;
33 static void
34 basic_setup(void)
36 parser = XML_ParserCreate(NULL);
37 if (parser == NULL)
38 fail("Parser not created.");
41 static void
42 basic_teardown(void)
44 if (parser != NULL)
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
50 expecting.
52 static void
53 _xml_failure(XML_Parser parser, const char *file, int line)
55 char buffer[1024];
56 enum XML_Error err = XML_GetErrorCode(parser);
57 sprintf(buffer,
58 " %d: %s (line %" XML_FMT_INT_MOD "u, offset %"\
59 XML_FMT_INT_MOD "u)\n reported from %s, line %d\n",
60 err,
61 XML_ErrorString(err),
62 XML_GetCurrentLineNumber(parser),
63 XML_GetCurrentColumnNumber(parser),
64 file, line);
65 _fail_unless(0, file, line, buffer);
68 #define xml_failure(parser) _xml_failure((parser), __FILE__, __LINE__)
70 static void
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), \
84 __FILE__, __LINE__)
86 /* Dummy handlers for when we need to set a handler to tickle a bug,
87 but it doesn't need to do anything.
90 static void XMLCALL
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)
98 static void XMLCALL
99 dummy_end_doctype_handler(void *userData)
102 static void XMLCALL
103 dummy_entity_decl_handler(void *userData,
104 const XML_Char *entityName,
105 int is_parameter_entity,
106 const XML_Char *value,
107 int value_length,
108 const XML_Char *base,
109 const XML_Char *systemId,
110 const XML_Char *publicId,
111 const XML_Char *notationName)
114 static void XMLCALL
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)
122 static void XMLCALL
123 dummy_element_decl_handler(void *userData,
124 const XML_Char *name,
125 XML_Content *model)
128 static void XMLCALL
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,
134 int isrequired)
137 static void XMLCALL
138 dummy_comment_handler(void *userData, const XML_Char *data)
141 static void XMLCALL
142 dummy_pi_handler(void *userData, const XML_Char *target, const XML_Char *data)
145 static void XMLCALL
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)
163 xml_failure(parser);
165 END_TEST
168 START_TEST(test_u0000_char)
170 /* test that a NUL byte (in US-ASCII data) is an error */
171 expect_failure("<doc>&#0;</doc>",
172 XML_ERROR_BAD_CHAR_REF,
173 "Parser did not report error on NUL-byte.");
175 END_TEST
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)
183 xml_failure(parser);
185 END_TEST
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)
192 xml_failure(parser);
194 END_TEST
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)
201 xml_failure(parser);
203 END_TEST
205 static void XMLCALL
206 accumulate_characters(void *userData, const XML_Char *s, int len)
208 CharData_AppendXMLChars((CharData *)userData, s, len);
211 static void XMLCALL
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);
223 static void
224 _run_character_check(XML_Char *text, XML_Char *expected,
225 const char *file, int line)
227 CharData storage;
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__)
240 static void
241 _run_attribute_check(XML_Char *text, XML_Char *expected,
242 const char *file, int line)
244 CharData storage;
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)
260 char *text =
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");
266 END_TEST
269 /* Regression test for SF bug #514281. */
270 START_TEST(test_french_charref_hexidecimal)
272 char *text =
273 "<?xml version='1.0' encoding='iso-8859-1'?>\n"
274 "<doc>&#xE9;&#xE8;&#xE0;&#xE7;&#xEA;&#xC8;</doc>";
275 run_character_check(text,
276 "\xC3\xA9\xC3\xA8\xC3\xA0\xC3\xA7\xC3\xAA\xC3\x88");
278 END_TEST
280 START_TEST(test_french_charref_decimal)
282 char *text =
283 "<?xml version='1.0' encoding='iso-8859-1'?>\n"
284 "<doc>&#233;&#232;&#224;&#231;&#234;&#200;</doc>";
285 run_character_check(text,
286 "\xC3\xA9\xC3\xA8\xC3\xA0\xC3\xA7\xC3\xAA\xC3\x88");
288 END_TEST
290 START_TEST(test_french_latin1)
292 char *text =
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");
298 END_TEST
300 START_TEST(test_french_utf8)
302 char *text =
303 "<?xml version='1.0' encoding='utf-8'?>\n"
304 "<doc>\xC3\xA9</doc>";
305 run_character_check(text, "\xC3\xA9");
307 END_TEST
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");
319 END_TEST
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
324 sequence.
326 START_TEST(test_illegal_utf8)
328 char text[100];
329 int i;
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) {
334 sprintf(text,
335 "expected token error for '%c' (ordinal %d) in UTF-8 text",
336 i, i);
337 fail(text);
339 else if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_TOKEN)
340 xml_failure(parser);
341 /* Reset the parser since we use the same parser repeatedly. */
342 XML_ParserReset(parser, NULL);
345 END_TEST
347 START_TEST(test_utf16)
349 /* <?xml version="1.0" encoding="UTF-16"?>
350 <doc a='123'>some text</doc>
352 char text[] =
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)
361 xml_failure(parser);
363 END_TEST
365 START_TEST(test_utf16_le_epilog_newline)
367 unsigned int first_chunk_bytes = 17;
368 char text[] =
369 "\xFF\xFE" /* BOM */
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)
376 == XML_STATUS_ERROR)
377 xml_failure(parser);
378 else {
379 enum XML_Status rc;
380 rc = XML_Parse(parser, text + first_chunk_bytes,
381 sizeof(text) - first_chunk_bytes - 1, XML_TRUE);
382 if (rc == XML_STATUS_ERROR)
383 xml_failure(parser);
386 END_TEST
388 /* Regression test for SF bug #481609, #774028. */
389 START_TEST(test_latin1_umlauts)
391 char *text =
392 "<?xml version='1.0' encoding='iso-8859-1'?>\n"
393 "<e a='\xE4 \xF6 \xFC &#228; &#246; &#252; &#x00E4; &#x0F6; &#xFC; >'\n"
394 " >\xE4 \xF6 \xFC &#228; &#246; &#252; &#x00E4; &#x0F6; &#xFC; ></e>";
395 char *utf8 =
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);
403 END_TEST
405 /* Regression test #1 for SF bug #653180. */
406 START_TEST(test_line_number_after_parse)
408 char *text =
409 "<tag>\n"
410 "\n"
411 "\n</tag>";
412 XML_Size lineno;
414 if (XML_Parse(parser, text, strlen(text), XML_FALSE) == XML_STATUS_ERROR)
415 xml_failure(parser);
416 lineno = XML_GetCurrentLineNumber(parser);
417 if (lineno != 4) {
418 char buffer[100];
419 sprintf(buffer,
420 "expected 4 lines, saw %" XML_FMT_INT_MOD "u", lineno);
421 fail(buffer);
424 END_TEST
426 /* Regression test #2 for SF bug #653180. */
427 START_TEST(test_column_number_after_parse)
429 char *text = "<tag></tag>";
430 XML_Size colno;
432 if (XML_Parse(parser, text, strlen(text), XML_FALSE) == XML_STATUS_ERROR)
433 xml_failure(parser);
434 colno = XML_GetCurrentColumnNumber(parser);
435 if (colno != 11) {
436 char buffer[100];
437 sprintf(buffer,
438 "expected 11 columns, saw %" XML_FMT_INT_MOD "u", colno);
439 fail(buffer);
442 END_TEST
444 static void XMLCALL
445 start_element_event_handler2(void *userData, const XML_Char *name,
446 const XML_Char **attr)
448 CharData *storage = (CharData *) userData;
449 char buffer[100];
451 sprintf(buffer,
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);
459 static void XMLCALL
460 end_element_event_handler2(void *userData, const XML_Char *name)
462 CharData *storage = (CharData *) userData;
463 char buffer[100];
465 sprintf(buffer,
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)
476 char *text =
477 "<a>\n" /* Unix end-of-line */
478 " <b>\r\n" /* Windows end-of-line */
479 " <c/>\r" /* Mac OS end-of-line */
480 " </b>\n"
481 " <d>\n"
482 " <f/>\n"
483 " </d>\n"
484 "</a>";
485 char *expected =
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";
496 CharData storage;
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)
503 xml_failure(parser);
505 CharData_CheckString(&storage, expected);
507 END_TEST
509 /* Regression test #4 for SF bug #653180. */
510 START_TEST(test_line_number_after_error)
512 char *text =
513 "<a>\n"
514 " <b>\n"
515 " </a>"; /* missing </b> */
516 XML_Size lineno;
517 if (XML_Parse(parser, text, strlen(text), XML_FALSE) != XML_STATUS_ERROR)
518 fail("Expected a parse error");
520 lineno = XML_GetCurrentLineNumber(parser);
521 if (lineno != 3) {
522 char buffer[100];
523 sprintf(buffer, "expected 3 lines, saw %" XML_FMT_INT_MOD "u", lineno);
524 fail(buffer);
527 END_TEST
529 /* Regression test #5 for SF bug #653180. */
530 START_TEST(test_column_number_after_error)
532 char *text =
533 "<a>\n"
534 " <b>\n"
535 " </a>"; /* missing </b> */
536 XML_Size colno;
537 if (XML_Parse(parser, text, strlen(text), XML_FALSE) != XML_STATUS_ERROR)
538 fail("Expected a parse error");
540 colno = XML_GetCurrentColumnNumber(parser);
541 if (colno != 4) {
542 char buffer[100];
543 sprintf(buffer,
544 "expected 4 columns, saw %" XML_FMT_INT_MOD "u", colno);
545 fail(buffer);
548 END_TEST
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.
558 char *text =
559 "<e>"
560 /* 64 chars */
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-+"
579 "</e>";
580 if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
581 xml_failure(parser);
583 END_TEST
587 * Element event tests.
590 static void XMLCALL
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";
602 CharData storage;
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)
608 xml_failure(parser);
609 CharData_CheckString(&storage, expected);
611 END_TEST
615 * Attribute tests.
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.)
627 static int
628 is_whitespace_normalized(const XML_Char *s, int is_cdata)
630 int blanks = 0;
631 int at_start = 1;
632 while (*s) {
633 if (*s == ' ')
634 ++blanks;
635 else if (*s == '\t' || *s == '\n' || *s == '\r')
636 return 0;
637 else {
638 if (at_start) {
639 at_start = 0;
640 if (blanks && !is_cdata)
641 /* illegal leading blanks */
642 return 0;
644 else if (blanks > 1 && !is_cdata)
645 return 0;
646 blanks = 0;
648 ++s;
650 if (blanks && !is_cdata)
651 return 0;
652 return 1;
655 /* Check the attribute whitespace checker: */
656 static void
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));
680 static void XMLCALL
681 check_attr_contains_normalized_whitespace(void *userData,
682 const XML_Char *name,
683 const XML_Char **atts)
685 int i;
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)) {
693 char buffer[256];
694 sprintf(buffer, "attribute value not normalized: %s='%s'",
695 attrname, value);
696 fail(buffer);
702 START_TEST(test_attr_whitespace_normalization)
704 char *text =
705 "<!DOCTYPE doc [\n"
706 " <!ATTLIST doc\n"
707 " attr NMTOKENS #REQUIRED\n"
708 " ents ENTITIES #REQUIRED\n"
709 " refs IDREFS #REQUIRED>\n"
710 "]>\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"
713 " ent-2 ' >\n"
714 " <e id='id-1'/>\n"
715 " <e id='id-2'/>\n"
716 "</doc>";
718 XML_SetStartElementHandler(parser,
719 check_attr_contains_normalized_whitespace);
720 if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
721 xml_failure(parser);
723 END_TEST
727 * XML declaration tests.
730 START_TEST(test_xmldecl_misplaced)
732 expect_failure("\n"
733 "<?xml version='1.0'?>\n"
734 "<a/>",
735 XML_ERROR_MISPLACED_XML_PI,
736 "failed to report misplaced XML declaration");
738 END_TEST
740 /* Regression test for SF bug #584832. */
741 static int XMLCALL
742 UnknownEncodingHandler(void *data,const XML_Char *encoding,XML_Encoding *info)
744 if (strcmp(encoding,"unsupported-encoding") == 0) {
745 int i;
746 for (i = 0; i < 256; ++i)
747 info->map[i] = i;
748 info->data = NULL;
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)
758 char *text =
759 "<?xml version='1.0' encoding='unsupported-encoding'?>\n"
760 "<!DOCTYPE test [<!ENTITY foo 'bar'>]>\n"
761 "<test a='&foo;'/>";
763 XML_SetUnknownEncodingHandler(parser, UnknownEncodingHandler, NULL);
764 if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
765 xml_failure(parser);
767 END_TEST
769 /* Regression test for SF bug #620106. */
770 static int XMLCALL
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().
780 char *text =
781 "<?xml encoding='iso-8859-3'?>"
782 "\xC3\xA9";
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) {
792 xml_failure(parser);
793 return 0;
795 return 1;
798 START_TEST(test_ext_entity_set_encoding)
800 char *text =
801 "<!DOCTYPE doc [\n"
802 " <!ENTITY en SYSTEM 'http://xml.libexpat.org/dummy.ent'>\n"
803 "]>\n"
804 "<doc>&en;</doc>";
806 XML_SetExternalEntityRefHandler(parser,
807 external_entity_loader_set_encoding);
808 run_character_check(text, "\xC3\xA9");
810 END_TEST
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) {
816 char *text =
817 "<!DOCTYPE doc SYSTEM 'foo'>\n"
818 "<doc>&entity;</doc>";
820 if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
821 xml_failure(parser);
823 END_TEST
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.");
833 END_TEST
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) {
839 char *text =
840 "<?xml version='1.0' encoding='us-ascii' standalone='yes'?>\n"
841 "<!DOCTYPE doc SYSTEM 'foo'>\n"
842 "<doc>&entity;</doc>";
844 expect_failure(text,
845 XML_ERROR_UNDEFINED_ENTITY,
846 "Parser did not report undefined entity (standalone).");
848 END_TEST
850 static int XMLCALL
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) {
865 xml_failure(parser);
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) {
875 char *text =
876 "<?xml version='1.0' encoding='us-ascii' standalone='yes'?>\n"
877 "<!DOCTYPE doc SYSTEM 'foo'>\n"
878 "<doc>&entity;</doc>";
879 char *foo_text =
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);
885 expect_failure(text,
886 XML_ERROR_UNDEFINED_ENTITY,
887 "Parser did not report undefined entity (external DTD).");
889 END_TEST
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) {
895 char *text =
896 "<?xml version='1.0' encoding='us-ascii'?>\n"
897 "<!DOCTYPE doc SYSTEM 'foo'>\n"
898 "<doc>&entity;</doc>";
899 char *foo_text =
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)
906 xml_failure(parser);
908 END_TEST
910 START_TEST(test_wfc_no_recursive_entity_refs)
912 char *text =
913 "<!DOCTYPE doc [\n"
914 " <!ENTITY entity '&#38;entity;'>\n"
915 "]>\n"
916 "<doc>&entity;</doc>";
918 expect_failure(text,
919 XML_ERROR_RECURSIVE_ENTITY_REF,
920 "Parser did not report recursive entity reference.");
922 END_TEST
924 /* Regression test for SF bug #483514. */
925 START_TEST(test_dtd_default_handling)
927 char *text =
928 "<!DOCTYPE doc [\n"
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"
933 "<?pi in dtd?>\n"
934 "<!--comment in dtd-->\n"
935 "]><doc/>";
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/>");
949 END_TEST
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)
959 char *text =
960 "<doc xmlns:prefix='http://www.example.com/'>\n"
961 " <e xmlns:prefix=''/>\n"
962 "</doc>";
964 if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
965 xml_failure(parser);
967 END_TEST
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)
975 char *text =
976 "<!DOCTYPE e:element [\n"
977 " <!ATTLIST e:element\n"
978 " xmlns:e CDATA 'http://example.com/'>\n"
979 " ]>\n"
980 "<e:element/>";
982 if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
983 xml_failure(parser);
985 END_TEST
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"
1009 "</s>";
1011 static XML_Bool resumable = XML_FALSE;
1013 static void
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
1029 handler.
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);
1040 END_TEST
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
1050 handler.
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);
1061 END_TEST
1065 * Namespaces tests.
1068 static void
1069 namespace_setup(void)
1071 parser = XML_ParserCreateNS(NULL, ' ');
1072 if (parser == NULL)
1073 fail("Parser not created.");
1076 static void
1077 namespace_teardown(void)
1079 basic_teardown();
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.
1087 static void XMLCALL
1088 triplet_start_checker(void *userData, const XML_Char *name,
1089 const XML_Char **atts)
1091 char **elemstr = (char **)userData;
1092 char buffer[1024];
1093 if (strcmp(elemstr[0], name) != 0) {
1094 sprintf(buffer, "unexpected start string: '%s'", name);
1095 fail(buffer);
1097 if (strcmp(elemstr[1], atts[0]) != 0) {
1098 sprintf(buffer, "unexpected attribute string: '%s'", atts[0]);
1099 fail(buffer);
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.
1107 static void XMLCALL
1108 triplet_end_checker(void *userData, const XML_Char *name)
1110 char **elemstr = (char **)userData;
1111 if (strcmp(elemstr[0], name) != 0) {
1112 char buffer[1024];
1113 sprintf(buffer, "unexpected end string: '%s'", name);
1114 fail(buffer);
1118 START_TEST(test_return_ns_triplet)
1120 char *text =
1121 "<foo:e xmlns:foo='http://expat.sf.net/' bar:a='12'\n"
1122 " xmlns:bar='http://expat.sf.net/'></foo:e>";
1123 char *elemstr[] = {
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);
1133 END_TEST
1135 static void XMLCALL
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);
1145 atts += 2;
1147 CharData_AppendString(storage, "\n");
1150 static void XMLCALL
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");
1159 static void
1160 run_ns_tagname_overwrite_test(char *text, char *result)
1162 CharData storage;
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)
1175 char *text =
1176 "<n:e xmlns:n='http://xml.libexpat.org/'>\n"
1177 " <n:f n:attr='foo'/>\n"
1178 " <n:g n:attr2='bar'/>\n"
1179 "</n:e>";
1180 char *result =
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);
1191 END_TEST
1193 /* Regression test for SF bug #566334. */
1194 START_TEST(test_ns_tagname_overwrite_triplet)
1196 char *text =
1197 "<n:e xmlns:n='http://xml.libexpat.org/'>\n"
1198 " <n:f n:attr='foo'/>\n"
1199 " <n:g n:attr2='bar'/>\n"
1200 "</n:e>";
1201 char *result =
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);
1213 END_TEST
1216 /* Regression test for SF bug #620343. */
1217 static void XMLCALL
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()");
1225 static void XMLCALL
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
1237 taken.
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);
1247 END_TEST
1249 /* Regression test for SF bug #616863. */
1250 static int XMLCALL
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);
1258 char *text;
1259 XML_Parser p2;
1261 if (callno == 1)
1262 text = ("<!ELEMENT doc (e+)>\n"
1263 "<!ATTLIST doc xmlns CDATA #IMPLIED>\n"
1264 "<!ELEMENT e EMPTY>\n");
1265 else
1266 text = ("<?xml version='1.0' encoding='us-ascii'?>"
1267 "<e/>");
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) {
1272 xml_failure(p2);
1273 return 0;
1275 XML_ParserFree(p2);
1276 return 1;
1279 START_TEST(test_default_ns_from_ext_subset_and_ext_ge)
1281 char *text =
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"
1285 "]>\n"
1286 "<doc xmlns='http://xml.libexpat.org/ns1'>\n"
1287 "&en;\n"
1288 "</doc>";
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);
1298 END_TEST
1300 /* Regression test #1 for SF bug #673791. */
1301 START_TEST(test_ns_prefix_with_empty_uri_1)
1303 char *text =
1304 "<doc xmlns:prefix='http://xml.libexpat.org/'>\n"
1305 " <e xmlns:prefix=''/>\n"
1306 "</doc>";
1308 expect_failure(text,
1309 XML_ERROR_UNDECLARING_PREFIX,
1310 "Did not report re-setting namespace"
1311 " URI with prefix to ''.");
1313 END_TEST
1315 /* Regression test #2 for SF bug #673791. */
1316 START_TEST(test_ns_prefix_with_empty_uri_2)
1318 char *text =
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 ''.");
1326 END_TEST
1328 /* Regression test #3 for SF bug #673791. */
1329 START_TEST(test_ns_prefix_with_empty_uri_3)
1331 char *text =
1332 "<!DOCTYPE doc [\n"
1333 " <!ELEMENT doc EMPTY>\n"
1334 " <!ATTLIST doc\n"
1335 " xmlns:prefix CDATA ''>\n"
1336 "]>\n"
1337 "<doc/>";
1339 expect_failure(text,
1340 XML_ERROR_UNDECLARING_PREFIX,
1341 "Didn't report attr default setting NS w/ prefix to ''.");
1343 END_TEST
1345 /* Regression test #4 for SF bug #673791. */
1346 START_TEST(test_ns_prefix_with_empty_uri_4)
1348 char *text =
1349 "<!DOCTYPE doc [\n"
1350 " <!ELEMENT prefix:doc EMPTY>\n"
1351 " <!ATTLIST prefix:doc\n"
1352 " xmlns:prefix CDATA 'http://xml.libexpat.org/'>\n"
1353 "]>\n"
1354 "<prefix:doc/>";
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. */
1358 char *elemstr[] = {
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);
1367 END_TEST
1369 START_TEST(test_ns_default_with_empty_uri)
1371 char *text =
1372 "<doc xmlns='http://xml.libexpat.org/'>\n"
1373 " <e xmlns=''/>\n"
1374 "</doc>";
1375 if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
1376 xml_failure(parser);
1378 END_TEST
1380 /* Regression test for SF bug #692964: two prefixes for one namespace. */
1381 START_TEST(test_ns_duplicate_attrs_diff_prefixes)
1383 char *text =
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");
1391 END_TEST
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");
1401 END_TEST
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");
1411 END_TEST
1413 static Suite *
1414 make_suite(void)
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);
1481 return s;
1485 #ifdef AMIGA_SHARED_LIB
1487 amiga_main(int argc, char *argv[])
1488 #else
1490 main(int argc, char *argv[])
1491 #endif
1493 int i, nf;
1494 int verbosity = CK_NORMAL;
1495 Suite *s = make_suite();
1496 SRunner *sr = srunner_create(s);
1498 /* run the tests for internal helper functions */
1499 testhelper_is_whitespace_normalized();
1501 for (i = 1; i < argc; ++i) {
1502 char *opt = argv[i];
1503 if (strcmp(opt, "-v") == 0 || strcmp(opt, "--verbose") == 0)
1504 verbosity = CK_VERBOSE;
1505 else if (strcmp(opt, "-q") == 0 || strcmp(opt, "--quiet") == 0)
1506 verbosity = CK_SILENT;
1507 else {
1508 fprintf(stderr, "runtests: unknown option '%s'\n", opt);
1509 return 2;
1512 if (verbosity != CK_SILENT)
1513 printf("Expat version: %s\n", XML_ExpatVersion());
1514 srunner_run_all(sr, verbosity);
1515 nf = srunner_ntests_failed(sr);
1516 srunner_free(sr);
1518 return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;