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