Annotation of embedaddon/expat/tests/runtests.c, revision 1.1.1.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>