source: trunk/poppler/expat-1.95.8/tests/runtests.c @ 2

Last change on this file since 2 was 2, checked in by Eugene Romanenko, 16 years ago

First import

File size: 44.5 KB
Line 
1/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
2   See the file COPYING for copying permission.
3
4   runtest.c : run the Expat test suite
5*/
6
7#ifdef HAVE_EXPAT_CONFIG_H
8#include <expat_config.h>
9#endif
10
11#ifdef HAVE_CHECK_H
12#include <check.h>
13#else
14#include "minicheck.h"
15#endif
16
17#include <assert.h>
18#include <stdlib.h>
19#include <stdio.h>
20#include <string.h>
21
22#include "expat.h"
23#include "chardata.h"
24
25
26static XML_Parser parser;
27
28
29static void
30basic_setup(void)
31{
32    parser = XML_ParserCreate(NULL);
33    if (parser == NULL)
34        fail("Parser not created.");
35}
36
37static void
38basic_teardown(void)
39{
40    if (parser != NULL)
41        XML_ParserFree(parser);
42}
43
44/* Generate a failure using the parser state to create an error message;
45   this should be used when the parser reports an error we weren't
46   expecting.
47*/
48static void
49_xml_failure(XML_Parser parser, const char *file, int line)
50{
51    char buffer[1024];
52    sprintf(buffer,
53            "\n    %s (line %d, offset %d)\n    reported from %s, line %d",
54            XML_ErrorString(XML_GetErrorCode(parser)),
55            XML_GetCurrentLineNumber(parser),
56            XML_GetCurrentColumnNumber(parser),
57            file, line);
58    _fail_unless(0, file, line, buffer);
59}
60
61#define xml_failure(parser) _xml_failure((parser), __FILE__, __LINE__)
62
63static void
64_expect_failure(char *text, enum XML_Error errorCode, char *errorMessage,
65                char *file, int lineno)
66{
67    if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_OK)
68        /* Hackish use of _fail_unless() macro, but let's us report
69           the right filename and line number. */
70        _fail_unless(0, file, lineno, errorMessage);
71    if (XML_GetErrorCode(parser) != errorCode)
72        _xml_failure(parser, file, lineno);
73}
74
75#define expect_failure(text, errorCode, errorMessage) \
76        _expect_failure((text), (errorCode), (errorMessage), \
77                        __FILE__, __LINE__)
78
79/* Dummy handlers for when we need to set a handler to tickle a bug,
80   but it doesn't need to do anything.
81*/
82
83static void XMLCALL
84dummy_start_doctype_handler(void           *userData,
85                            const XML_Char *doctypeName,
86                            const XML_Char *sysid,
87                            const XML_Char *pubid,
88                            int            has_internal_subset)
89{}
90
91static void XMLCALL
92dummy_end_doctype_handler(void *userData)
93{}
94
95static void XMLCALL
96dummy_entity_decl_handler(void           *userData,
97                          const XML_Char *entityName,
98                          int            is_parameter_entity,
99                          const XML_Char *value,
100                          int            value_length,
101                          const XML_Char *base,
102                          const XML_Char *systemId,
103                          const XML_Char *publicId,
104                          const XML_Char *notationName)
105{}
106
107static void XMLCALL
108dummy_notation_decl_handler(void *userData,
109                            const XML_Char *notationName,
110                            const XML_Char *base,
111                            const XML_Char *systemId,
112                            const XML_Char *publicId)
113{}
114
115static void XMLCALL
116dummy_element_decl_handler(void *userData,
117                           const XML_Char *name,
118                           XML_Content *model)
119{}
120
121static void XMLCALL
122dummy_attlist_decl_handler(void           *userData,
123                           const XML_Char *elname,
124                           const XML_Char *attname,
125                           const XML_Char *att_type,
126                           const XML_Char *dflt,
127                           int            isrequired)
128{}
129
130static void XMLCALL
131dummy_comment_handler(void *userData, const XML_Char *data)
132{}
133
134static void XMLCALL
135dummy_pi_handler(void *userData, const XML_Char *target, const XML_Char *data)
136{}
137
138static void XMLCALL
139dummy_start_element(void *userData,
140                    const XML_Char *name, const XML_Char **atts)
141{}
142
143
144/*
145 * Character & encoding tests.
146 */
147
148START_TEST(test_nul_byte)
149{
150    char text[] = "<doc>\0</doc>";
151
152    /* test that a NUL byte (in US-ASCII data) is an error */
153    if (XML_Parse(parser, text, sizeof(text) - 1, XML_TRUE) == XML_STATUS_OK)
154        fail("Parser did not report error on NUL-byte.");
155    if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_TOKEN)
156        xml_failure(parser);
157}
158END_TEST
159
160
161START_TEST(test_u0000_char)
162{
163    /* test that a NUL byte (in US-ASCII data) is an error */
164    expect_failure("<doc>&#0;</doc>",
165                   XML_ERROR_BAD_CHAR_REF,
166                   "Parser did not report error on NUL-byte.");
167}
168END_TEST
169
170START_TEST(test_bom_utf8)
171{
172    /* This test is really just making sure we don't core on a UTF-8 BOM. */
173    char *text = "\357\273\277<e/>";
174
175    if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
176        xml_failure(parser);
177}
178END_TEST
179
180START_TEST(test_bom_utf16_be)
181{
182    char text[] = "\376\377\0<\0e\0/\0>";
183
184    if (XML_Parse(parser, text, sizeof(text)-1, XML_TRUE) == XML_STATUS_ERROR)
185        xml_failure(parser);
186}
187END_TEST
188
189START_TEST(test_bom_utf16_le)
190{
191    char text[] = "\377\376<\0e\0/\0>\0";
192
193    if (XML_Parse(parser, text, sizeof(text)-1, XML_TRUE) == XML_STATUS_ERROR)
194        xml_failure(parser);
195}
196END_TEST
197
198static void XMLCALL
199accumulate_characters(void *userData, const XML_Char *s, int len)
200{
201    CharData_AppendXMLChars((CharData *)userData, s, len);
202}
203
204static void XMLCALL
205accumulate_attribute(void *userData, const XML_Char *name,
206                     const XML_Char **atts)
207{
208    CharData *storage = (CharData *)userData;
209    if (storage->count < 0 && atts != NULL && atts[0] != NULL) {
210        /* "accumulate" the value of the first attribute we see */
211        CharData_AppendXMLChars(storage, atts[1], -1);
212    }
213}
214
215
216static void
217_run_character_check(XML_Char *text, XML_Char *expected,
218                     const char *file, int line)
219{
220    CharData storage;
221
222    CharData_Init(&storage);
223    XML_SetUserData(parser, &storage);
224    XML_SetCharacterDataHandler(parser, accumulate_characters);
225    if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
226        _xml_failure(parser, file, line);
227    CharData_CheckXMLChars(&storage, expected);
228}
229
230#define run_character_check(text, expected) \
231        _run_character_check(text, expected, __FILE__, __LINE__)
232
233static void
234_run_attribute_check(XML_Char *text, XML_Char *expected,
235                     const char *file, int line)
236{
237    CharData storage;
238
239    CharData_Init(&storage);
240    XML_SetUserData(parser, &storage);
241    XML_SetStartElementHandler(parser, accumulate_attribute);
242    if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
243        _xml_failure(parser, file, line);
244    CharData_CheckXMLChars(&storage, expected);
245}
246
247#define run_attribute_check(text, expected) \
248        _run_attribute_check(text, expected, __FILE__, __LINE__)
249
250/* Regression test for SF bug #491986. */
251START_TEST(test_danish_latin1)
252{
253    char *text =
254        "<?xml version='1.0' encoding='iso-8859-1'?>\n"
255        "<e>Jørgen æøåÆØÅ</e>";
256    run_character_check(text,
257             "J\xC3\xB8rgen \xC3\xA6\xC3\xB8\xC3\xA5\xC3\x86\xC3\x98\xC3\x85");
258}
259END_TEST
260
261
262/* Regression test for SF bug #514281. */
263START_TEST(test_french_charref_hexidecimal)
264{
265    char *text =
266        "<?xml version='1.0' encoding='iso-8859-1'?>\n"
267        "<doc>&#xE9;&#xE8;&#xE0;&#xE7;&#xEA;&#xC8;</doc>";
268    run_character_check(text,
269                        "\xC3\xA9\xC3\xA8\xC3\xA0\xC3\xA7\xC3\xAA\xC3\x88");
270}
271END_TEST
272
273START_TEST(test_french_charref_decimal)
274{
275    char *text =
276        "<?xml version='1.0' encoding='iso-8859-1'?>\n"
277        "<doc>&#233;&#232;&#224;&#231;&#234;&#200;</doc>";
278    run_character_check(text,
279                        "\xC3\xA9\xC3\xA8\xC3\xA0\xC3\xA7\xC3\xAA\xC3\x88");
280}
281END_TEST
282
283START_TEST(test_french_latin1)
284{
285    char *text =
286        "<?xml version='1.0' encoding='iso-8859-1'?>\n"
287        "<doc>\xE9\xE8\xE0\xE7\xEa\xC8</doc>";
288    run_character_check(text,
289                        "\xC3\xA9\xC3\xA8\xC3\xA0\xC3\xA7\xC3\xAA\xC3\x88");
290}
291END_TEST
292
293START_TEST(test_french_utf8)
294{
295    char *text =
296        "<?xml version='1.0' encoding='utf-8'?>\n"
297        "<doc>\xC3\xA9</doc>";
298    run_character_check(text, "\xC3\xA9");
299}
300END_TEST
301
302/* Regression test for SF bug #600479.
303   XXX There should be a test that exercises all legal XML Unicode
304   characters as PCDATA and attribute value content, and XML Name
305   characters as part of element and attribute names.
306*/
307START_TEST(test_utf8_false_rejection)
308{
309    char *text = "<doc>\xEF\xBA\xBF</doc>";
310    run_character_check(text, "\xEF\xBA\xBF");
311}
312END_TEST
313
314/* Regression test for SF bug #477667.
315   This test assures that any 8-bit character followed by a 7-bit
316   character will not be mistakenly interpreted as a valid UTF-8
317   sequence.
318*/
319START_TEST(test_illegal_utf8)
320{
321    char text[100];
322    int i;
323
324    for (i = 128; i <= 255; ++i) {
325        sprintf(text, "<e>%ccd</e>", i);
326        if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_OK) {
327            sprintf(text,
328                    "expected token error for '%c' (ordinal %d) in UTF-8 text",
329                    i, i);
330            fail(text);
331        }
332        else if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_TOKEN)
333            xml_failure(parser);
334        /* Reset the parser since we use the same parser repeatedly. */
335        XML_ParserReset(parser, NULL);
336    }
337}
338END_TEST
339
340START_TEST(test_utf16)
341{
342    /* <?xml version="1.0" encoding="UTF-16"?>
343       <doc a='123'>some text</doc>
344    */
345    char text[] =
346        "\000<\000?\000x\000m\000\154\000 \000v\000e\000r\000s\000i\000o"
347        "\000n\000=\000'\0001\000.\000\060\000'\000 \000e\000n\000c\000o"
348        "\000d\000i\000n\000g\000=\000'\000U\000T\000F\000-\0001\000\066"
349        "\000'\000?\000>\000\n"
350        "\000<\000d\000o\000c\000 \000a\000=\000'\0001\0002\0003\000'"
351        "\000>\000s\000o\000m\000e\000 \000t\000e\000x\000t\000<\000/"
352        "\000d\000o\000c\000>";
353    if (XML_Parse(parser, text, sizeof(text)-1, XML_TRUE) == XML_STATUS_ERROR)
354        xml_failure(parser);
355}
356END_TEST
357
358START_TEST(test_utf16_le_epilog_newline)
359{
360    int first_chunk_bytes = 17;
361    char text[] = 
362        "\xFF\xFE"                      /* BOM */
363        "<\000e\000/\000>\000"          /* document element */
364        "\r\000\n\000\r\000\n\000";     /* epilog */
365
366    if (first_chunk_bytes >= sizeof(text) - 1)
367        fail("bad value of first_chunk_bytes");
368    if (  XML_Parse(parser, text, first_chunk_bytes, XML_FALSE)
369          == XML_STATUS_ERROR)
370        xml_failure(parser);
371    else {
372        enum XML_Status rc;
373        rc = XML_Parse(parser, text + first_chunk_bytes,
374                       sizeof(text) - first_chunk_bytes - 1, XML_TRUE);
375        if (rc == XML_STATUS_ERROR)
376            xml_failure(parser);
377    }
378}
379END_TEST
380
381/* Regression test for SF bug #481609, #774028. */
382START_TEST(test_latin1_umlauts)
383{
384    char *text =
385        "<?xml version='1.0' encoding='iso-8859-1'?>\n"
386        "<e a='ä ö ü &#228; &#246; &#252; &#x00E4; &#x0F6; &#xFC; >'\n"
387        "  >ä ö ü &#228; &#246; &#252; &#x00E4; &#x0F6; &#xFC; ></e>";
388    char *utf8 =
389        "\xC3\xA4 \xC3\xB6 \xC3\xBC "
390        "\xC3\xA4 \xC3\xB6 \xC3\xBC "
391        "\xC3\xA4 \xC3\xB6 \xC3\xBC >";
392    run_character_check(text, utf8);
393    XML_ParserReset(parser, NULL);
394    run_attribute_check(text, utf8);
395}
396END_TEST
397
398/* Regression test #1 for SF bug #653180. */
399START_TEST(test_line_number_after_parse)
400{ 
401    char *text =
402        "<tag>\n"
403        "\n"
404        "\n</tag>";
405    int lineno;
406
407    if (XML_Parse(parser, text, strlen(text), XML_FALSE) == XML_STATUS_ERROR)
408        xml_failure(parser);
409    lineno = XML_GetCurrentLineNumber(parser);
410    if (lineno != 4) {
411        char buffer[100];
412        sprintf(buffer, "expected 4 lines, saw %d", lineno);
413        fail(buffer);
414    }
415}
416END_TEST
417
418/* Regression test #2 for SF bug #653180. */
419START_TEST(test_column_number_after_parse)
420{
421    char *text = "<tag></tag>";
422    int colno;
423
424    if (XML_Parse(parser, text, strlen(text), XML_FALSE) == XML_STATUS_ERROR)
425        xml_failure(parser);
426    colno = XML_GetCurrentColumnNumber(parser);
427    if (colno != 11) {
428        char buffer[100];
429        sprintf(buffer, "expected 11 columns, saw %d", colno);
430        fail(buffer);
431    }
432}
433END_TEST
434
435static void XMLCALL
436start_element_event_handler2(void *userData, const XML_Char *name,
437                             const XML_Char **attr)
438{
439    CharData *storage = (CharData *) userData;
440    char buffer[100];
441
442    sprintf(buffer, "<%s> at col:%d line:%d\n", name,
443            XML_GetCurrentColumnNumber(parser),
444            XML_GetCurrentLineNumber(parser));
445    CharData_AppendString(storage, buffer);
446}
447
448static void XMLCALL
449end_element_event_handler2(void *userData, const XML_Char *name)
450{
451    CharData *storage = (CharData *) userData;
452    char buffer[100];
453
454    sprintf(buffer, "</%s> at col:%d line:%d\n", name,
455            XML_GetCurrentColumnNumber(parser),
456            XML_GetCurrentLineNumber(parser));
457    CharData_AppendString(storage, buffer);
458}
459
460/* Regression test #3 for SF bug #653180. */
461START_TEST(test_line_and_column_numbers_inside_handlers)
462{
463    char *text =
464        "<a>\n"        /* Unix end-of-line */
465        "  <b>\r\n"    /* Windows end-of-line */
466        "    <c/>\r"   /* Mac OS end-of-line */
467        "  </b>\n"
468        "  <d>\n"
469        "    <f/>\n"
470        "  </d>\n"
471        "</a>";
472    char *expected =
473        "<a> at col:0 line:1\n"
474        "<b> at col:2 line:2\n"
475        "<c> at col:4 line:3\n"
476        "</c> at col:8 line:3\n"
477        "</b> at col:2 line:4\n"
478        "<d> at col:2 line:5\n"
479        "<f> at col:4 line:6\n"
480        "</f> at col:8 line:6\n"
481        "</d> at col:2 line:7\n"
482        "</a> at col:0 line:8\n";
483    CharData storage;
484
485    CharData_Init(&storage);
486    XML_SetUserData(parser, &storage);
487    XML_SetStartElementHandler(parser, start_element_event_handler2);
488    XML_SetEndElementHandler(parser, end_element_event_handler2);
489    if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
490        xml_failure(parser);
491
492    CharData_CheckString(&storage, expected); 
493}
494END_TEST
495
496/* Regression test #4 for SF bug #653180. */
497START_TEST(test_line_number_after_error)
498{
499    char *text =
500        "<a>\n"
501        "  <b>\n"
502        "  </a>";  /* missing </b> */
503    int lineno;
504    if (XML_Parse(parser, text, strlen(text), XML_FALSE) != XML_STATUS_ERROR)
505        fail("Expected a parse error");
506
507    lineno = XML_GetCurrentLineNumber(parser);
508    if (lineno != 3) {
509        char buffer[100];
510        sprintf(buffer, "expected 3 lines, saw %d", lineno);
511        fail(buffer);
512    }
513}
514END_TEST
515   
516/* Regression test #5 for SF bug #653180. */
517START_TEST(test_column_number_after_error)
518{
519    char *text =
520        "<a>\n"
521        "  <b>\n"
522        "  </a>";  /* missing </b> */
523    int colno;
524    if (XML_Parse(parser, text, strlen(text), XML_FALSE) != XML_STATUS_ERROR)
525        fail("Expected a parse error");
526
527    colno = XML_GetCurrentColumnNumber(parser);
528    if (colno != 4) { 
529        char buffer[100];
530        sprintf(buffer, "expected 4 columns, saw %d", colno);
531        fail(buffer);
532    }
533}
534END_TEST
535
536/* Regression test for SF bug #478332. */
537START_TEST(test_really_long_lines)
538{
539    /* This parses an input line longer than INIT_DATA_BUF_SIZE
540       characters long (defined to be 1024 in xmlparse.c).  We take a
541       really cheesy approach to building the input buffer, because
542       this avoids writing bugs in buffer-filling code.
543    */
544    char *text =
545        "<e>"
546        /* 64 chars */
547        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
548        /* until we have at least 1024 characters on the line: */
549        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
550        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
551        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
552        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
553        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
554        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
555        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
556        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
557        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
558        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
559        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
560        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
561        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
562        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
563        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
564        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
565        "</e>";
566    if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
567        xml_failure(parser);
568}
569END_TEST
570
571
572/*
573 * Element event tests.
574 */
575
576static void XMLCALL
577end_element_event_handler(void *userData, const XML_Char *name)
578{
579    CharData *storage = (CharData *) userData;
580    CharData_AppendString(storage, "/");
581    CharData_AppendXMLChars(storage, name, -1);
582}
583
584START_TEST(test_end_element_events)
585{
586    char *text = "<a><b><c/></b><d><f/></d></a>";
587    char *expected = "/c/b/f/d/a";
588    CharData storage;
589
590    CharData_Init(&storage);
591    XML_SetUserData(parser, &storage);
592    XML_SetEndElementHandler(parser, end_element_event_handler);
593    if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
594        xml_failure(parser);
595    CharData_CheckString(&storage, expected);
596}
597END_TEST
598
599
600/*
601 * Attribute tests.
602 */
603
604/* Helpers used by the following test; this checks any "attr" and "refs"
605   attributes to make sure whitespace has been normalized.
606
607   Return true if whitespace has been normalized in a string, using
608   the rules for attribute value normalization.  The 'is_cdata' flag
609   is needed since CDATA attributes don't need to have multiple
610   whitespace characters collapsed to a single space, while other
611   attribute data types do.  (Section 3.3.3 of the recommendation.)
612*/
613static int
614is_whitespace_normalized(const XML_Char *s, int is_cdata)
615{
616    int blanks = 0;
617    int at_start = 1;
618    while (*s) {
619        if (*s == ' ')
620            ++blanks;
621        else if (*s == '\t' || *s == '\n' || *s == '\r')
622            return 0;
623        else {
624            if (at_start) {
625                at_start = 0;
626                if (blanks && !is_cdata)
627                    /* illegal leading blanks */
628                    return 0;
629            }
630            else if (blanks > 1 && !is_cdata)
631                return 0;
632            blanks = 0;
633        }
634        ++s;
635    }
636    if (blanks && !is_cdata)
637        return 0;
638    return 1;
639}
640
641/* Check the attribute whitespace checker: */
642static void
643testhelper_is_whitespace_normalized(void)
644{
645    assert(is_whitespace_normalized("abc", 0));
646    assert(is_whitespace_normalized("abc", 1));
647    assert(is_whitespace_normalized("abc def ghi", 0));
648    assert(is_whitespace_normalized("abc def ghi", 1));
649    assert(!is_whitespace_normalized(" abc def ghi", 0));
650    assert(is_whitespace_normalized(" abc def ghi", 1));
651    assert(!is_whitespace_normalized("abc  def ghi", 0));
652    assert(is_whitespace_normalized("abc  def ghi", 1));
653    assert(!is_whitespace_normalized("abc def ghi ", 0));
654    assert(is_whitespace_normalized("abc def ghi ", 1));
655    assert(!is_whitespace_normalized(" ", 0));
656    assert(is_whitespace_normalized(" ", 1));
657    assert(!is_whitespace_normalized("\t", 0));
658    assert(!is_whitespace_normalized("\t", 1));
659    assert(!is_whitespace_normalized("\n", 0));
660    assert(!is_whitespace_normalized("\n", 1));
661    assert(!is_whitespace_normalized("\r", 0));
662    assert(!is_whitespace_normalized("\r", 1));
663    assert(!is_whitespace_normalized("abc\t def", 1));
664}
665
666static void XMLCALL
667check_attr_contains_normalized_whitespace(void *userData,
668                                          const XML_Char *name,
669                                          const XML_Char **atts)
670{
671    int i;
672    for (i = 0; atts[i] != NULL; i += 2) {
673        const XML_Char *attrname = atts[i];
674        const XML_Char *value = atts[i + 1];
675        if (strcmp("attr", attrname) == 0
676            || strcmp("ents", attrname) == 0
677            || strcmp("refs", attrname) == 0) {
678            if (!is_whitespace_normalized(value, 0)) {
679                char buffer[256];
680                sprintf(buffer, "attribute value not normalized: %s='%s'",
681                        attrname, value);
682                fail(buffer);
683            }
684        }
685    }
686}
687
688START_TEST(test_attr_whitespace_normalization)
689{
690    char *text =
691        "<!DOCTYPE doc [\n"
692        "  <!ATTLIST doc\n"
693        "            attr NMTOKENS #REQUIRED\n"
694        "            ents ENTITIES #REQUIRED\n"
695        "            refs IDREFS   #REQUIRED>\n"
696        "]>\n"
697        "<doc attr='    a  b c\t\td\te\t' refs=' id-1   \t  id-2\t\t\n"
698        "     ents=' ent-1   \t\r\n"
699        "            ent-2  ' >\n"
700        "  <e id='id-1'/>\n"
701        "  <e id='id-2'/>\n"
702        "</doc>";
703
704    XML_SetStartElementHandler(parser,
705                               check_attr_contains_normalized_whitespace);
706    if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
707        xml_failure(parser);
708}
709END_TEST
710
711
712/*
713 * XML declaration tests.
714 */
715
716START_TEST(test_xmldecl_misplaced)
717{
718    expect_failure("\n"
719                   "<?xml version='1.0'?>\n"
720                   "<a/>",
721                   XML_ERROR_MISPLACED_XML_PI,
722                   "failed to report misplaced XML declaration");
723}
724END_TEST
725
726/* Regression test for SF bug #584832. */
727static int XMLCALL
728UnknownEncodingHandler(void *data,const XML_Char *encoding,XML_Encoding *info)
729{
730    if (strcmp(encoding,"unsupported-encoding") == 0) {
731        int i;
732        for (i = 0; i < 256; ++i)
733            info->map[i] = i;
734        info->data = NULL;
735        info->convert = NULL;
736        info->release = NULL;
737        return XML_STATUS_OK;
738    }
739    return XML_STATUS_ERROR;
740}
741
742START_TEST(test_unknown_encoding_internal_entity)
743{
744    char *text =
745        "<?xml version='1.0' encoding='unsupported-encoding'?>\n"
746        "<!DOCTYPE test [<!ENTITY foo 'bar'>]>\n"
747        "<test a='&foo;'/>";
748
749    XML_SetUnknownEncodingHandler(parser, UnknownEncodingHandler, NULL);
750    if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
751        xml_failure(parser);
752}
753END_TEST
754
755/* Regression test for SF bug #620106. */
756static int XMLCALL
757external_entity_loader_set_encoding(XML_Parser parser,
758                                    const XML_Char *context,
759                                    const XML_Char *base,
760                                    const XML_Char *systemId,
761                                    const XML_Char *publicId)
762{
763    /* This text says it's an unsupported encoding, but it's really
764       UTF-8, which we tell Expat using XML_SetEncoding().
765    */
766    char *text =
767        "<?xml encoding='iso-8859-3'?>"
768        "\xC3\xA9";
769    XML_Parser extparser;
770
771    extparser = XML_ExternalEntityParserCreate(parser, context, NULL);
772    if (extparser == NULL)
773        fail("Could not create external entity parser.");
774    if (!XML_SetEncoding(extparser, "utf-8"))
775        fail("XML_SetEncoding() ignored for external entity");
776    if (  XML_Parse(extparser, text, strlen(text), XML_TRUE)
777          == XML_STATUS_ERROR) {
778        xml_failure(parser);
779        return 0;
780    }
781    return 1;
782}
783
784START_TEST(test_ext_entity_set_encoding)
785{
786    char *text =
787        "<!DOCTYPE doc [\n"
788        "  <!ENTITY en SYSTEM 'http://xml.libexpat.org/dummy.ent'>\n"
789        "]>\n"
790        "<doc>&en;</doc>";
791
792    XML_SetExternalEntityRefHandler(parser,
793                                    external_entity_loader_set_encoding);
794    run_character_check(text, "\xC3\xA9");
795}
796END_TEST
797
798/* Test that no error is reported for unknown entities if we don't
799   read an external subset.  This was fixed in Expat 1.95.5.
800*/
801START_TEST(test_wfc_undeclared_entity_unread_external_subset) {
802    char *text =
803        "<!DOCTYPE doc SYSTEM 'foo'>\n"
804        "<doc>&entity;</doc>";
805
806    if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
807        xml_failure(parser);
808}
809END_TEST
810
811/* Test that an error is reported for unknown entities if we don't
812   have an external subset.
813*/
814START_TEST(test_wfc_undeclared_entity_no_external_subset) {
815    expect_failure("<doc>&entity;</doc>",
816                   XML_ERROR_UNDEFINED_ENTITY,
817                   "Parser did not report undefined entity w/out a DTD.");
818}
819END_TEST
820
821/* Test that an error is reported for unknown entities if we don't
822   read an external subset, but have been declared standalone.
823*/
824START_TEST(test_wfc_undeclared_entity_standalone) {
825    char *text =
826        "<?xml version='1.0' encoding='us-ascii' standalone='yes'?>\n"
827        "<!DOCTYPE doc SYSTEM 'foo'>\n"
828        "<doc>&entity;</doc>";
829
830    expect_failure(text,
831                   XML_ERROR_UNDEFINED_ENTITY,
832                   "Parser did not report undefined entity (standalone).");
833}
834END_TEST
835
836static int XMLCALL
837external_entity_loader(XML_Parser parser,
838                       const XML_Char *context,
839                       const XML_Char *base,
840                       const XML_Char *systemId,
841                       const XML_Char *publicId)
842{
843    char *text = (char *)XML_GetUserData(parser);
844    XML_Parser extparser;
845
846    extparser = XML_ExternalEntityParserCreate(parser, context, NULL);
847    if (extparser == NULL)
848        fail("Could not create external entity parser.");
849    if (  XML_Parse(extparser, text, strlen(text), XML_TRUE)
850          == XML_STATUS_ERROR) {
851        xml_failure(parser);
852        return XML_STATUS_ERROR;
853    }
854    return XML_STATUS_OK;
855}
856
857/* Test that an error is reported for unknown entities if we have read
858   an external subset, and standalone is true.
859*/
860START_TEST(test_wfc_undeclared_entity_with_external_subset_standalone) {
861    char *text =
862        "<?xml version='1.0' encoding='us-ascii' standalone='yes'?>\n"
863        "<!DOCTYPE doc SYSTEM 'foo'>\n"
864        "<doc>&entity;</doc>";
865    char *foo_text =
866        "<!ELEMENT doc (#PCDATA)*>";
867
868    XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
869    XML_SetUserData(parser, foo_text);
870    XML_SetExternalEntityRefHandler(parser, external_entity_loader);
871    expect_failure(text,
872                   XML_ERROR_UNDEFINED_ENTITY,
873                   "Parser did not report undefined entity (external DTD).");
874}
875END_TEST
876
877/* Test that no error is reported for unknown entities if we have read
878   an external subset, and standalone is false.
879*/
880START_TEST(test_wfc_undeclared_entity_with_external_subset) {
881    char *text =
882        "<?xml version='1.0' encoding='us-ascii'?>\n"
883        "<!DOCTYPE doc SYSTEM 'foo'>\n"
884        "<doc>&entity;</doc>";
885    char *foo_text =
886        "<!ELEMENT doc (#PCDATA)*>";
887
888    XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
889    XML_SetUserData(parser, foo_text);
890    XML_SetExternalEntityRefHandler(parser, external_entity_loader);
891    if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
892        xml_failure(parser);
893}
894END_TEST
895
896START_TEST(test_wfc_no_recursive_entity_refs)
897{
898    char *text =
899        "<!DOCTYPE doc [\n"
900        "  <!ENTITY entity '&#38;entity;'>\n"
901        "]>\n"
902        "<doc>&entity;</doc>";
903
904    expect_failure(text,
905                   XML_ERROR_RECURSIVE_ENTITY_REF,
906                   "Parser did not report recursive entity reference.");
907}
908END_TEST
909
910/* Regression test for SF bug #483514. */
911START_TEST(test_dtd_default_handling)
912{
913    char *text =
914        "<!DOCTYPE doc [\n"
915        "<!ENTITY e SYSTEM 'http://xml.libexpat.org/e'>\n"
916        "<!NOTATION n SYSTEM 'http://xml.libexpat.org/n'>\n"
917        "<!ELEMENT doc EMPTY>\n"
918        "<!ATTLIST doc a CDATA #IMPLIED>\n"
919        "<?pi in dtd?>\n"
920        "<!--comment in dtd-->\n"
921        "]><doc/>";
922
923    XML_SetDefaultHandler(parser, accumulate_characters);
924    XML_SetDoctypeDeclHandler(parser,
925                              dummy_start_doctype_handler,
926                              dummy_end_doctype_handler);
927    XML_SetEntityDeclHandler(parser, dummy_entity_decl_handler);
928    XML_SetNotationDeclHandler(parser, dummy_notation_decl_handler);
929    XML_SetElementDeclHandler(parser, dummy_element_decl_handler);
930    XML_SetAttlistDeclHandler(parser, dummy_attlist_decl_handler);
931    XML_SetProcessingInstructionHandler(parser, dummy_pi_handler);
932    XML_SetCommentHandler(parser, dummy_comment_handler);
933    run_character_check(text, "\n\n\n\n\n\n\n<doc/>");
934}
935END_TEST
936
937/* See related SF bug #673791.
938   When namespace processing is enabled, setting the namespace URI for
939   a prefix is not allowed; this test ensures that it *is* allowed
940   when namespace processing is not enabled.
941   (See Namespaces in XML, section 2.)
942*/
943START_TEST(test_empty_ns_without_namespaces)
944{
945    char *text =
946        "<doc xmlns:prefix='http://www.example.com/'>\n"
947        "  <e xmlns:prefix=''/>\n"
948        "</doc>";
949
950    if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
951        xml_failure(parser);
952}
953END_TEST
954
955/* Regression test for SF bug #824420.
956   Checks that an xmlns:prefix attribute set in an attribute's default
957   value isn't misinterpreted.
958*/
959START_TEST(test_ns_in_attribute_default_without_namespaces)
960{
961    char *text =
962        "<!DOCTYPE e:element [\n"
963        "  <!ATTLIST e:element\n"
964        "    xmlns:e CDATA 'http://example.com/'>\n"
965        "      ]>\n"
966        "<e:element/>";
967
968    if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
969        xml_failure(parser);
970}
971END_TEST
972
973
974/*
975 * Namespaces tests.
976 */
977
978static void
979namespace_setup(void)
980{
981    parser = XML_ParserCreateNS(NULL, ' ');
982    if (parser == NULL)
983        fail("Parser not created.");
984}
985
986static void
987namespace_teardown(void)
988{
989    basic_teardown();
990}
991
992/* Check that an element name and attribute name match the expected values.
993   The expected values are passed as an array reference of string pointers
994   provided as the userData argument; the first is the expected
995   element name, and the second is the expected attribute name.
996*/
997static void XMLCALL
998triplet_start_checker(void *userData, const XML_Char *name,
999                      const XML_Char **atts)
1000{
1001    char **elemstr = (char **)userData;
1002    char buffer[1024];
1003    if (strcmp(elemstr[0], name) != 0) {
1004        sprintf(buffer, "unexpected start string: '%s'", name);
1005        fail(buffer);
1006    }
1007    if (strcmp(elemstr[1], atts[0]) != 0) {
1008        sprintf(buffer, "unexpected attribute string: '%s'", atts[0]);
1009        fail(buffer);
1010    }
1011}
1012
1013/* Check that the element name passed to the end-element handler matches
1014   the expected value.  The expected value is passed as the first element
1015   in an array of strings passed as the userData argument.
1016*/
1017static void XMLCALL
1018triplet_end_checker(void *userData, const XML_Char *name)
1019{
1020    char **elemstr = (char **)userData;
1021    if (strcmp(elemstr[0], name) != 0) {
1022        char buffer[1024];
1023        sprintf(buffer, "unexpected end string: '%s'", name);
1024        fail(buffer);
1025    }
1026}
1027
1028START_TEST(test_return_ns_triplet)
1029{
1030    char *text =
1031        "<foo:e xmlns:foo='http://expat.sf.net/' bar:a='12'\n"
1032        "       xmlns:bar='http://expat.sf.net/'></foo:e>";
1033    char *elemstr[] = {
1034        "http://expat.sf.net/ e foo",
1035        "http://expat.sf.net/ a bar"
1036    };
1037    XML_SetReturnNSTriplet(parser, XML_TRUE);
1038    XML_SetUserData(parser, elemstr);
1039    XML_SetElementHandler(parser, triplet_start_checker, triplet_end_checker);
1040    if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
1041        xml_failure(parser);
1042}
1043END_TEST
1044
1045static void XMLCALL
1046overwrite_start_checker(void *userData, const XML_Char *name,
1047                        const XML_Char **atts)
1048{
1049    CharData *storage = (CharData *) userData;
1050    CharData_AppendString(storage, "start ");
1051    CharData_AppendXMLChars(storage, name, -1);
1052    while (*atts != NULL) {
1053        CharData_AppendString(storage, "\nattribute ");
1054        CharData_AppendXMLChars(storage, *atts, -1);
1055        atts += 2;
1056    }
1057    CharData_AppendString(storage, "\n");
1058}
1059
1060static void XMLCALL
1061overwrite_end_checker(void *userData, const XML_Char *name)
1062{
1063    CharData *storage = (CharData *) userData;
1064    CharData_AppendString(storage, "end ");
1065    CharData_AppendXMLChars(storage, name, -1);
1066    CharData_AppendString(storage, "\n");
1067}
1068
1069static void
1070run_ns_tagname_overwrite_test(char *text, char *result)
1071{
1072    CharData storage;
1073    CharData_Init(&storage);
1074    XML_SetUserData(parser, &storage);
1075    XML_SetElementHandler(parser,
1076                          overwrite_start_checker, overwrite_end_checker);
1077    if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
1078        xml_failure(parser);
1079    CharData_CheckString(&storage, result);
1080}
1081
1082/* Regression test for SF bug #566334. */
1083START_TEST(test_ns_tagname_overwrite)
1084{
1085    char *text =
1086        "<n:e xmlns:n='http://xml.libexpat.org/'>\n"
1087        "  <n:f n:attr='foo'/>\n"
1088        "  <n:g n:attr2='bar'/>\n"
1089        "</n:e>";
1090    char *result =
1091        "start http://xml.libexpat.org/ e\n"
1092        "start http://xml.libexpat.org/ f\n"
1093        "attribute http://xml.libexpat.org/ attr\n"
1094        "end http://xml.libexpat.org/ f\n"
1095        "start http://xml.libexpat.org/ g\n"
1096        "attribute http://xml.libexpat.org/ attr2\n"
1097        "end http://xml.libexpat.org/ g\n"
1098        "end http://xml.libexpat.org/ e\n";
1099    run_ns_tagname_overwrite_test(text, result);
1100}
1101END_TEST
1102
1103/* Regression test for SF bug #566334. */
1104START_TEST(test_ns_tagname_overwrite_triplet)
1105{
1106    char *text =
1107        "<n:e xmlns:n='http://xml.libexpat.org/'>\n"
1108        "  <n:f n:attr='foo'/>\n"
1109        "  <n:g n:attr2='bar'/>\n"
1110        "</n:e>";
1111    char *result =
1112        "start http://xml.libexpat.org/ e n\n"
1113        "start http://xml.libexpat.org/ f n\n"
1114        "attribute http://xml.libexpat.org/ attr n\n"
1115        "end http://xml.libexpat.org/ f n\n"
1116        "start http://xml.libexpat.org/ g n\n"
1117        "attribute http://xml.libexpat.org/ attr2 n\n"
1118        "end http://xml.libexpat.org/ g n\n"
1119        "end http://xml.libexpat.org/ e n\n";
1120    XML_SetReturnNSTriplet(parser, XML_TRUE);
1121    run_ns_tagname_overwrite_test(text, result);
1122}
1123END_TEST
1124
1125
1126/* Regression test for SF bug #620343. */
1127static void XMLCALL
1128start_element_fail(void *userData,
1129                   const XML_Char *name, const XML_Char **atts)
1130{
1131    /* We should never get here. */
1132    fail("should never reach start_element_fail()");
1133}
1134
1135static void XMLCALL
1136start_ns_clearing_start_element(void *userData,
1137                                const XML_Char *prefix,
1138                                const XML_Char *uri)
1139{
1140    XML_SetStartElementHandler((XML_Parser) userData, NULL);
1141}
1142
1143START_TEST(test_start_ns_clears_start_element)
1144{
1145    /* This needs to use separate start/end tags; using the empty tag
1146       syntax doesn't cause the problematic path through Expat to be
1147       taken.
1148    */
1149    char *text = "<e xmlns='http://xml.libexpat.org/'></e>";
1150
1151    XML_SetStartElementHandler(parser, start_element_fail);
1152    XML_SetStartNamespaceDeclHandler(parser, start_ns_clearing_start_element);
1153    XML_UseParserAsHandlerArg(parser);
1154    if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
1155        xml_failure(parser);
1156}
1157END_TEST
1158
1159/* Regression test for SF bug #616863. */
1160static int XMLCALL
1161external_entity_handler(XML_Parser parser,
1162                        const XML_Char *context,
1163                        const XML_Char *base,
1164                        const XML_Char *systemId,
1165                        const XML_Char *publicId) 
1166{
1167    int callno = 1 + (int)XML_GetUserData(parser);
1168    char *text;
1169    XML_Parser p2;
1170
1171    if (callno == 1)
1172        text = ("<!ELEMENT doc (e+)>\n"
1173                "<!ATTLIST doc xmlns CDATA #IMPLIED>\n"
1174                "<!ELEMENT e EMPTY>\n");
1175    else
1176        text = ("<?xml version='1.0' encoding='us-ascii'?>"
1177                "<e/>");
1178
1179    XML_SetUserData(parser, (void *) callno);
1180    p2 = XML_ExternalEntityParserCreate(parser, context, NULL);
1181    if (XML_Parse(p2, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) {
1182        xml_failure(p2);
1183        return 0;
1184    }
1185    XML_ParserFree(p2);
1186    return 1;
1187}
1188
1189START_TEST(test_default_ns_from_ext_subset_and_ext_ge)
1190{
1191    char *text =
1192        "<?xml version='1.0'?>\n"
1193        "<!DOCTYPE doc SYSTEM 'http://xml.libexpat.org/doc.dtd' [\n"
1194        "  <!ENTITY en SYSTEM 'http://xml.libexpat.org/entity.ent'>\n"
1195        "]>\n"
1196        "<doc xmlns='http://xml.libexpat.org/ns1'>\n"
1197        "&en;\n"
1198        "</doc>";
1199
1200    XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
1201    XML_SetExternalEntityRefHandler(parser, external_entity_handler);
1202    /* We actually need to set this handler to tickle this bug. */
1203    XML_SetStartElementHandler(parser, dummy_start_element);
1204    XML_SetUserData(parser, NULL);
1205    if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
1206        xml_failure(parser);
1207}
1208END_TEST
1209
1210/* Regression test #1 for SF bug #673791. */
1211START_TEST(test_ns_prefix_with_empty_uri_1)
1212{
1213    char *text =
1214        "<doc xmlns:prefix='http://xml.libexpat.org/'>\n"
1215        "  <e xmlns:prefix=''/>\n"
1216        "</doc>";
1217
1218    expect_failure(text,
1219                   XML_ERROR_UNDECLARING_PREFIX,
1220                   "Did not report re-setting namespace"
1221                   " URI with prefix to ''.");
1222}
1223END_TEST
1224
1225/* Regression test #2 for SF bug #673791. */
1226START_TEST(test_ns_prefix_with_empty_uri_2)
1227{
1228    char *text =
1229        "<?xml version='1.0'?>\n"
1230        "<docelem xmlns:pre=''/>";
1231
1232    expect_failure(text,
1233                   XML_ERROR_UNDECLARING_PREFIX,
1234                   "Did not report setting namespace URI with prefix to ''.");
1235}
1236END_TEST
1237
1238/* Regression test #3 for SF bug #673791. */
1239START_TEST(test_ns_prefix_with_empty_uri_3)
1240{
1241    char *text =
1242        "<!DOCTYPE doc [\n"
1243        "  <!ELEMENT doc EMPTY>\n"
1244        "  <!ATTLIST doc\n"
1245        "    xmlns:prefix CDATA ''>\n"
1246        "]>\n"
1247        "<doc/>";
1248
1249    expect_failure(text,
1250                   XML_ERROR_UNDECLARING_PREFIX,
1251                   "Didn't report attr default setting NS w/ prefix to ''.");
1252}
1253END_TEST
1254
1255/* Regression test #4 for SF bug #673791. */
1256START_TEST(test_ns_prefix_with_empty_uri_4)
1257{
1258    char *text =
1259        "<!DOCTYPE doc [\n"
1260        "  <!ELEMENT prefix:doc EMPTY>\n"
1261        "  <!ATTLIST prefix:doc\n"
1262        "    xmlns:prefix CDATA 'http://xml.libexpat.org/'>\n"
1263        "]>\n"
1264        "<prefix:doc/>";
1265    /* Packaged info expected by the end element handler;
1266       the weird structuring lets us re-use the triplet_end_checker()
1267       function also used for another test. */
1268    char *elemstr[] = {
1269        "http://xml.libexpat.org/ doc prefix"
1270    };
1271    XML_SetReturnNSTriplet(parser, XML_TRUE);
1272    XML_SetUserData(parser, elemstr);
1273    XML_SetEndElementHandler(parser, triplet_end_checker);
1274    if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
1275        xml_failure(parser);
1276}
1277END_TEST
1278
1279START_TEST(test_ns_default_with_empty_uri)
1280{
1281    char *text =
1282        "<doc xmlns='http://xml.libexpat.org/'>\n"
1283        "  <e xmlns=''/>\n"
1284        "</doc>";
1285    if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
1286        xml_failure(parser);
1287}
1288END_TEST
1289
1290/* Regression test for SF bug #692964: two prefixes for one namespace. */
1291START_TEST(test_ns_duplicate_attrs_diff_prefixes)
1292{
1293    char *text =
1294        "<doc xmlns:a='http://xml.libexpat.org/a'\n"
1295        "     xmlns:b='http://xml.libexpat.org/a'\n"
1296        "     a:a='v' b:a='v' />";
1297    expect_failure(text,
1298                   XML_ERROR_DUPLICATE_ATTRIBUTE,
1299                   "did not report multiple attributes with same URI+name");
1300}
1301END_TEST
1302
1303/* Regression test for SF bug #695401: unbound prefix. */
1304START_TEST(test_ns_unbound_prefix_on_attribute)
1305{
1306    char *text = "<doc a:attr=''/>";
1307    expect_failure(text,
1308                   XML_ERROR_UNBOUND_PREFIX,
1309                   "did not report unbound prefix on attribute");
1310}
1311END_TEST
1312
1313/* Regression test for SF bug #695401: unbound prefix. */
1314START_TEST(test_ns_unbound_prefix_on_element)
1315{
1316    char *text = "<a:doc/>";
1317    expect_failure(text,
1318                   XML_ERROR_UNBOUND_PREFIX,
1319                   "did not report unbound prefix on element");
1320}
1321END_TEST
1322
1323static Suite *
1324make_suite(void)
1325{
1326    Suite *s = suite_create("basic");
1327    TCase *tc_basic = tcase_create("basic tests");
1328    TCase *tc_namespace = tcase_create("XML namespaces");
1329
1330    suite_add_tcase(s, tc_basic);
1331    tcase_add_checked_fixture(tc_basic, basic_setup, basic_teardown);
1332    tcase_add_test(tc_basic, test_nul_byte);
1333    tcase_add_test(tc_basic, test_u0000_char);
1334    tcase_add_test(tc_basic, test_bom_utf8);
1335    tcase_add_test(tc_basic, test_bom_utf16_be);
1336    tcase_add_test(tc_basic, test_bom_utf16_le);
1337    tcase_add_test(tc_basic, test_illegal_utf8);
1338    tcase_add_test(tc_basic, test_utf16);
1339    tcase_add_test(tc_basic, test_utf16_le_epilog_newline);
1340    tcase_add_test(tc_basic, test_latin1_umlauts);
1341    /* Regression test for SF bug #491986. */
1342    tcase_add_test(tc_basic, test_danish_latin1);
1343    /* Regression test for SF bug #514281. */
1344    tcase_add_test(tc_basic, test_french_charref_hexidecimal);
1345    tcase_add_test(tc_basic, test_french_charref_decimal);
1346    tcase_add_test(tc_basic, test_french_latin1);
1347    tcase_add_test(tc_basic, test_french_utf8);
1348    tcase_add_test(tc_basic, test_utf8_false_rejection);
1349    tcase_add_test(tc_basic, test_line_number_after_parse);
1350    tcase_add_test(tc_basic, test_column_number_after_parse);
1351    tcase_add_test(tc_basic, test_line_and_column_numbers_inside_handlers);
1352    tcase_add_test(tc_basic, test_line_number_after_error);
1353    tcase_add_test(tc_basic, test_column_number_after_error);
1354    tcase_add_test(tc_basic, test_really_long_lines);
1355    tcase_add_test(tc_basic, test_end_element_events);
1356    tcase_add_test(tc_basic, test_attr_whitespace_normalization);
1357    tcase_add_test(tc_basic, test_xmldecl_misplaced);
1358    tcase_add_test(tc_basic, test_unknown_encoding_internal_entity);
1359    tcase_add_test(tc_basic,
1360                   test_wfc_undeclared_entity_unread_external_subset);
1361    tcase_add_test(tc_basic, test_wfc_undeclared_entity_no_external_subset);
1362    tcase_add_test(tc_basic, test_wfc_undeclared_entity_standalone);
1363    tcase_add_test(tc_basic, test_wfc_undeclared_entity_with_external_subset);
1364    tcase_add_test(tc_basic,
1365                   test_wfc_undeclared_entity_with_external_subset_standalone);
1366    tcase_add_test(tc_basic, test_wfc_no_recursive_entity_refs);
1367    tcase_add_test(tc_basic, test_ext_entity_set_encoding);
1368    tcase_add_test(tc_basic, test_dtd_default_handling);
1369    tcase_add_test(tc_basic, test_empty_ns_without_namespaces);
1370    tcase_add_test(tc_basic, test_ns_in_attribute_default_without_namespaces);
1371
1372    suite_add_tcase(s, tc_namespace);
1373    tcase_add_checked_fixture(tc_namespace,
1374                              namespace_setup, namespace_teardown);
1375    tcase_add_test(tc_namespace, test_return_ns_triplet);
1376    tcase_add_test(tc_namespace, test_ns_tagname_overwrite);
1377    tcase_add_test(tc_namespace, test_ns_tagname_overwrite_triplet);
1378    tcase_add_test(tc_namespace, test_start_ns_clears_start_element);
1379    tcase_add_test(tc_namespace, test_default_ns_from_ext_subset_and_ext_ge);
1380    tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_1);
1381    tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_2);
1382    tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_3);
1383    tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_4);
1384    tcase_add_test(tc_namespace, test_ns_default_with_empty_uri);
1385    tcase_add_test(tc_namespace, test_ns_duplicate_attrs_diff_prefixes);
1386    tcase_add_test(tc_namespace, test_ns_unbound_prefix_on_attribute);
1387    tcase_add_test(tc_namespace, test_ns_unbound_prefix_on_element);
1388
1389    return s;
1390}
1391
1392
1393int
1394main(int argc, char *argv[])
1395{
1396    int i, nf;
1397    int forking = 0, forking_set = 0;
1398    int verbosity = CK_NORMAL;
1399    Suite *s = make_suite();
1400    SRunner *sr = srunner_create(s);
1401
1402    /* run the tests for internal helper functions */
1403    testhelper_is_whitespace_normalized();
1404
1405    for (i = 1; i < argc; ++i) {
1406        char *opt = argv[i];
1407        if (strcmp(opt, "-v") == 0 || strcmp(opt, "--verbose") == 0)
1408            verbosity = CK_VERBOSE;
1409        else if (strcmp(opt, "-q") == 0 || strcmp(opt, "--quiet") == 0)
1410            verbosity = CK_SILENT;
1411        else if (strcmp(opt, "-f") == 0 || strcmp(opt, "--fork") == 0) {
1412            forking = 1;
1413            forking_set = 1;
1414        }
1415        else if (strcmp(opt, "-n") == 0 || strcmp(opt, "--no-fork") == 0) {
1416            forking = 0;
1417            forking_set = 1;
1418        }
1419        else {
1420            fprintf(stderr, "runtests: unknown option '%s'\n", opt);
1421            return 2;
1422        }
1423    }
1424    if (forking_set)
1425        srunner_set_fork_status(sr, forking ? CK_FORK : CK_NOFORK);
1426    if (verbosity != CK_SILENT)
1427        printf("Expat version: %s\n", XML_ExpatVersion());
1428    srunner_run_all(sr, verbosity);
1429    nf = srunner_ntests_failed(sr);
1430    srunner_free(sr);
1431
1432    return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
1433}
Note: See TracBrowser for help on using the repository browser.