1178848Scokane/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd 2178848Scokane See the file COPYING for copying permission. 3178848Scokane 4178848Scokane runtest.c : run the Expat test suite 5178848Scokane*/ 6178848Scokane 7178848Scokane#ifdef HAVE_EXPAT_CONFIG_H 8178848Scokane#include <expat_config.h> 9178848Scokane#endif 10178848Scokane 11104349Sphk#include <assert.h> 12104349Sphk#include <stdlib.h> 13104349Sphk#include <stdio.h> 14104349Sphk#include <string.h> 15247513Sdelphij#include <stdint.h> 16104349Sphk 17104349Sphk#include "expat.h" 18104349Sphk#include "chardata.h" 19178848Scokane#include "minicheck.h" 20104349Sphk 21178848Scokane#if defined(__amigaos__) && defined(__USE_INLINE__) 22178848Scokane#include <proto/expat.h> 23178848Scokane#endif 24104349Sphk 25178848Scokane#ifdef XML_LARGE_SIZE 26178848Scokane#define XML_FMT_INT_MOD "ll" 27178848Scokane#else 28178848Scokane#define XML_FMT_INT_MOD "l" 29178848Scokane#endif 30178848Scokane 31104349Sphkstatic XML_Parser parser; 32104349Sphk 33104349Sphk 34104349Sphkstatic void 35104349Sphkbasic_setup(void) 36104349Sphk{ 37104349Sphk parser = XML_ParserCreate(NULL); 38104349Sphk if (parser == NULL) 39104349Sphk fail("Parser not created."); 40104349Sphk} 41104349Sphk 42104349Sphkstatic void 43104349Sphkbasic_teardown(void) 44104349Sphk{ 45104349Sphk if (parser != NULL) 46104349Sphk XML_ParserFree(parser); 47104349Sphk} 48104349Sphk 49104349Sphk/* Generate a failure using the parser state to create an error message; 50104349Sphk this should be used when the parser reports an error we weren't 51104349Sphk expecting. 52104349Sphk*/ 53104349Sphkstatic void 54104349Sphk_xml_failure(XML_Parser parser, const char *file, int line) 55104349Sphk{ 56104349Sphk char buffer[1024]; 57178848Scokane enum XML_Error err = XML_GetErrorCode(parser); 58104349Sphk sprintf(buffer, 59178848Scokane " %d: %s (line %" XML_FMT_INT_MOD "u, offset %"\ 60178848Scokane XML_FMT_INT_MOD "u)\n reported from %s, line %d\n", 61178848Scokane err, 62178848Scokane XML_ErrorString(err), 63104349Sphk XML_GetCurrentLineNumber(parser), 64104349Sphk XML_GetCurrentColumnNumber(parser), 65104349Sphk file, line); 66178848Scokane _fail_unless(0, file, line, buffer); 67104349Sphk} 68104349Sphk 69104349Sphk#define xml_failure(parser) _xml_failure((parser), __FILE__, __LINE__) 70104349Sphk 71104349Sphkstatic void 72104349Sphk_expect_failure(char *text, enum XML_Error errorCode, char *errorMessage, 73104349Sphk char *file, int lineno) 74104349Sphk{ 75178848Scokane if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_OK) 76178848Scokane /* Hackish use of _fail_unless() macro, but let's us report 77178848Scokane the right filename and line number. */ 78178848Scokane _fail_unless(0, file, lineno, errorMessage); 79104349Sphk if (XML_GetErrorCode(parser) != errorCode) 80104349Sphk _xml_failure(parser, file, lineno); 81104349Sphk} 82104349Sphk 83104349Sphk#define expect_failure(text, errorCode, errorMessage) \ 84104349Sphk _expect_failure((text), (errorCode), (errorMessage), \ 85104349Sphk __FILE__, __LINE__) 86104349Sphk 87178848Scokane/* Dummy handlers for when we need to set a handler to tickle a bug, 88178848Scokane but it doesn't need to do anything. 89178848Scokane*/ 90104349Sphk 91178848Scokanestatic void XMLCALL 92178848Scokanedummy_start_doctype_handler(void *userData, 93178848Scokane const XML_Char *doctypeName, 94178848Scokane const XML_Char *sysid, 95178848Scokane const XML_Char *pubid, 96178848Scokane int has_internal_subset) 97178848Scokane{} 98178848Scokane 99178848Scokanestatic void XMLCALL 100178848Scokanedummy_end_doctype_handler(void *userData) 101178848Scokane{} 102178848Scokane 103178848Scokanestatic void XMLCALL 104178848Scokanedummy_entity_decl_handler(void *userData, 105178848Scokane const XML_Char *entityName, 106178848Scokane int is_parameter_entity, 107178848Scokane const XML_Char *value, 108178848Scokane int value_length, 109178848Scokane const XML_Char *base, 110178848Scokane const XML_Char *systemId, 111178848Scokane const XML_Char *publicId, 112178848Scokane const XML_Char *notationName) 113178848Scokane{} 114178848Scokane 115178848Scokanestatic void XMLCALL 116178848Scokanedummy_notation_decl_handler(void *userData, 117178848Scokane const XML_Char *notationName, 118178848Scokane const XML_Char *base, 119178848Scokane const XML_Char *systemId, 120178848Scokane const XML_Char *publicId) 121178848Scokane{} 122178848Scokane 123178848Scokanestatic void XMLCALL 124178848Scokanedummy_element_decl_handler(void *userData, 125178848Scokane const XML_Char *name, 126178848Scokane XML_Content *model) 127178848Scokane{} 128178848Scokane 129178848Scokanestatic void XMLCALL 130178848Scokanedummy_attlist_decl_handler(void *userData, 131178848Scokane const XML_Char *elname, 132178848Scokane const XML_Char *attname, 133178848Scokane const XML_Char *att_type, 134178848Scokane const XML_Char *dflt, 135178848Scokane int isrequired) 136178848Scokane{} 137178848Scokane 138178848Scokanestatic void XMLCALL 139178848Scokanedummy_comment_handler(void *userData, const XML_Char *data) 140178848Scokane{} 141178848Scokane 142178848Scokanestatic void XMLCALL 143178848Scokanedummy_pi_handler(void *userData, const XML_Char *target, const XML_Char *data) 144178848Scokane{} 145178848Scokane 146178848Scokanestatic void XMLCALL 147178848Scokanedummy_start_element(void *userData, 148178848Scokane const XML_Char *name, const XML_Char **atts) 149178848Scokane{} 150178848Scokane 151178848Scokane 152104349Sphk/* 153104349Sphk * Character & encoding tests. 154104349Sphk */ 155104349Sphk 156104349SphkSTART_TEST(test_nul_byte) 157104349Sphk{ 158104349Sphk char text[] = "<doc>\0</doc>"; 159104349Sphk 160104349Sphk /* test that a NUL byte (in US-ASCII data) is an error */ 161178848Scokane if (XML_Parse(parser, text, sizeof(text) - 1, XML_TRUE) == XML_STATUS_OK) 162104349Sphk fail("Parser did not report error on NUL-byte."); 163104349Sphk if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_TOKEN) 164104349Sphk xml_failure(parser); 165104349Sphk} 166104349SphkEND_TEST 167104349Sphk 168104349Sphk 169104349SphkSTART_TEST(test_u0000_char) 170104349Sphk{ 171104349Sphk /* test that a NUL byte (in US-ASCII data) is an error */ 172104349Sphk expect_failure("<doc>�</doc>", 173104349Sphk XML_ERROR_BAD_CHAR_REF, 174104349Sphk "Parser did not report error on NUL-byte."); 175104349Sphk} 176104349SphkEND_TEST 177104349Sphk 178104349SphkSTART_TEST(test_bom_utf8) 179104349Sphk{ 180104349Sphk /* This test is really just making sure we don't core on a UTF-8 BOM. */ 181104349Sphk char *text = "\357\273\277<e/>"; 182104349Sphk 183178848Scokane if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) 184104349Sphk xml_failure(parser); 185104349Sphk} 186104349SphkEND_TEST 187104349Sphk 188104349SphkSTART_TEST(test_bom_utf16_be) 189104349Sphk{ 190104349Sphk char text[] = "\376\377\0<\0e\0/\0>"; 191104349Sphk 192178848Scokane if (XML_Parse(parser, text, sizeof(text)-1, XML_TRUE) == XML_STATUS_ERROR) 193104349Sphk xml_failure(parser); 194104349Sphk} 195104349SphkEND_TEST 196104349Sphk 197104349SphkSTART_TEST(test_bom_utf16_le) 198104349Sphk{ 199104349Sphk char text[] = "\377\376<\0e\0/\0>\0"; 200104349Sphk 201178848Scokane if (XML_Parse(parser, text, sizeof(text)-1, XML_TRUE) == XML_STATUS_ERROR) 202104349Sphk xml_failure(parser); 203104349Sphk} 204104349SphkEND_TEST 205104349Sphk 206178848Scokanestatic void XMLCALL 207104349Sphkaccumulate_characters(void *userData, const XML_Char *s, int len) 208104349Sphk{ 209104349Sphk CharData_AppendXMLChars((CharData *)userData, s, len); 210104349Sphk} 211104349Sphk 212178848Scokanestatic void XMLCALL 213104349Sphkaccumulate_attribute(void *userData, const XML_Char *name, 214104349Sphk const XML_Char **atts) 215104349Sphk{ 216104349Sphk CharData *storage = (CharData *)userData; 217104349Sphk if (storage->count < 0 && atts != NULL && atts[0] != NULL) { 218104349Sphk /* "accumulate" the value of the first attribute we see */ 219104349Sphk CharData_AppendXMLChars(storage, atts[1], -1); 220104349Sphk } 221104349Sphk} 222104349Sphk 223104349Sphk 224104349Sphkstatic void 225178848Scokane_run_character_check(XML_Char *text, XML_Char *expected, 226178848Scokane const char *file, int line) 227104349Sphk{ 228104349Sphk CharData storage; 229104349Sphk 230104349Sphk CharData_Init(&storage); 231104349Sphk XML_SetUserData(parser, &storage); 232104349Sphk XML_SetCharacterDataHandler(parser, accumulate_characters); 233178848Scokane if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) 234178848Scokane _xml_failure(parser, file, line); 235104349Sphk CharData_CheckXMLChars(&storage, expected); 236104349Sphk} 237104349Sphk 238178848Scokane#define run_character_check(text, expected) \ 239178848Scokane _run_character_check(text, expected, __FILE__, __LINE__) 240178848Scokane 241104349Sphkstatic void 242178848Scokane_run_attribute_check(XML_Char *text, XML_Char *expected, 243178848Scokane const char *file, int line) 244104349Sphk{ 245104349Sphk CharData storage; 246104349Sphk 247104349Sphk CharData_Init(&storage); 248104349Sphk XML_SetUserData(parser, &storage); 249104349Sphk XML_SetStartElementHandler(parser, accumulate_attribute); 250178848Scokane if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) 251178848Scokane _xml_failure(parser, file, line); 252104349Sphk CharData_CheckXMLChars(&storage, expected); 253104349Sphk} 254104349Sphk 255178848Scokane#define run_attribute_check(text, expected) \ 256178848Scokane _run_attribute_check(text, expected, __FILE__, __LINE__) 257178848Scokane 258104349Sphk/* Regression test for SF bug #491986. */ 259104349SphkSTART_TEST(test_danish_latin1) 260104349Sphk{ 261104349Sphk char *text = 262104349Sphk "<?xml version='1.0' encoding='iso-8859-1'?>\n" 263178848Scokane "<e>J\xF8rgen \xE6\xF8\xE5\xC6\xD8\xC5</e>"; 264104349Sphk run_character_check(text, 265104349Sphk "J\xC3\xB8rgen \xC3\xA6\xC3\xB8\xC3\xA5\xC3\x86\xC3\x98\xC3\x85"); 266104349Sphk} 267104349SphkEND_TEST 268104349Sphk 269104349Sphk 270104349Sphk/* Regression test for SF bug #514281. */ 271104349SphkSTART_TEST(test_french_charref_hexidecimal) 272104349Sphk{ 273104349Sphk char *text = 274104349Sphk "<?xml version='1.0' encoding='iso-8859-1'?>\n" 275104349Sphk "<doc>éèàçêÈ</doc>"; 276104349Sphk run_character_check(text, 277104349Sphk "\xC3\xA9\xC3\xA8\xC3\xA0\xC3\xA7\xC3\xAA\xC3\x88"); 278104349Sphk} 279104349SphkEND_TEST 280104349Sphk 281104349SphkSTART_TEST(test_french_charref_decimal) 282104349Sphk{ 283104349Sphk char *text = 284104349Sphk "<?xml version='1.0' encoding='iso-8859-1'?>\n" 285104349Sphk "<doc>éèàçêÈ</doc>"; 286104349Sphk run_character_check(text, 287104349Sphk "\xC3\xA9\xC3\xA8\xC3\xA0\xC3\xA7\xC3\xAA\xC3\x88"); 288104349Sphk} 289104349SphkEND_TEST 290104349Sphk 291104349SphkSTART_TEST(test_french_latin1) 292104349Sphk{ 293104349Sphk char *text = 294104349Sphk "<?xml version='1.0' encoding='iso-8859-1'?>\n" 295104349Sphk "<doc>\xE9\xE8\xE0\xE7\xEa\xC8</doc>"; 296104349Sphk run_character_check(text, 297104349Sphk "\xC3\xA9\xC3\xA8\xC3\xA0\xC3\xA7\xC3\xAA\xC3\x88"); 298104349Sphk} 299104349SphkEND_TEST 300104349Sphk 301104349SphkSTART_TEST(test_french_utf8) 302104349Sphk{ 303104349Sphk char *text = 304104349Sphk "<?xml version='1.0' encoding='utf-8'?>\n" 305104349Sphk "<doc>\xC3\xA9</doc>"; 306104349Sphk run_character_check(text, "\xC3\xA9"); 307104349Sphk} 308104349SphkEND_TEST 309104349Sphk 310104349Sphk/* Regression test for SF bug #600479. 311104349Sphk XXX There should be a test that exercises all legal XML Unicode 312104349Sphk characters as PCDATA and attribute value content, and XML Name 313104349Sphk characters as part of element and attribute names. 314104349Sphk*/ 315104349SphkSTART_TEST(test_utf8_false_rejection) 316104349Sphk{ 317104349Sphk char *text = "<doc>\xEF\xBA\xBF</doc>"; 318104349Sphk run_character_check(text, "\xEF\xBA\xBF"); 319104349Sphk} 320104349SphkEND_TEST 321104349Sphk 322104349Sphk/* Regression test for SF bug #477667. 323104349Sphk This test assures that any 8-bit character followed by a 7-bit 324104349Sphk character will not be mistakenly interpreted as a valid UTF-8 325104349Sphk sequence. 326104349Sphk*/ 327104349SphkSTART_TEST(test_illegal_utf8) 328104349Sphk{ 329104349Sphk char text[100]; 330104349Sphk int i; 331104349Sphk 332104349Sphk for (i = 128; i <= 255; ++i) { 333104349Sphk sprintf(text, "<e>%ccd</e>", i); 334178848Scokane if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_OK) { 335104349Sphk sprintf(text, 336104349Sphk "expected token error for '%c' (ordinal %d) in UTF-8 text", 337104349Sphk i, i); 338104349Sphk fail(text); 339104349Sphk } 340104349Sphk else if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_TOKEN) 341104349Sphk xml_failure(parser); 342104349Sphk /* Reset the parser since we use the same parser repeatedly. */ 343104349Sphk XML_ParserReset(parser, NULL); 344104349Sphk } 345104349Sphk} 346104349SphkEND_TEST 347104349Sphk 348104349SphkSTART_TEST(test_utf16) 349104349Sphk{ 350104349Sphk /* <?xml version="1.0" encoding="UTF-16"?> 351104349Sphk <doc a='123'>some text</doc> 352104349Sphk */ 353104349Sphk char text[] = 354104349Sphk "\000<\000?\000x\000m\000\154\000 \000v\000e\000r\000s\000i\000o" 355104349Sphk "\000n\000=\000'\0001\000.\000\060\000'\000 \000e\000n\000c\000o" 356104349Sphk "\000d\000i\000n\000g\000=\000'\000U\000T\000F\000-\0001\000\066" 357104349Sphk "\000'\000?\000>\000\n" 358104349Sphk "\000<\000d\000o\000c\000 \000a\000=\000'\0001\0002\0003\000'" 359104349Sphk "\000>\000s\000o\000m\000e\000 \000t\000e\000x\000t\000<\000/" 360104349Sphk "\000d\000o\000c\000>"; 361178848Scokane if (XML_Parse(parser, text, sizeof(text)-1, XML_TRUE) == XML_STATUS_ERROR) 362104349Sphk xml_failure(parser); 363104349Sphk} 364104349SphkEND_TEST 365104349Sphk 366104349SphkSTART_TEST(test_utf16_le_epilog_newline) 367104349Sphk{ 368178848Scokane unsigned int first_chunk_bytes = 17; 369104349Sphk char text[] = 370104349Sphk "\xFF\xFE" /* BOM */ 371104349Sphk "<\000e\000/\000>\000" /* document element */ 372104349Sphk "\r\000\n\000\r\000\n\000"; /* epilog */ 373104349Sphk 374104349Sphk if (first_chunk_bytes >= sizeof(text) - 1) 375104349Sphk fail("bad value of first_chunk_bytes"); 376178848Scokane if ( XML_Parse(parser, text, first_chunk_bytes, XML_FALSE) 377178848Scokane == XML_STATUS_ERROR) 378104349Sphk xml_failure(parser); 379104349Sphk else { 380104349Sphk enum XML_Status rc; 381104349Sphk rc = XML_Parse(parser, text + first_chunk_bytes, 382178848Scokane sizeof(text) - first_chunk_bytes - 1, XML_TRUE); 383104349Sphk if (rc == XML_STATUS_ERROR) 384104349Sphk xml_failure(parser); 385104349Sphk } 386104349Sphk} 387104349SphkEND_TEST 388104349Sphk 389178848Scokane/* Regression test for SF bug #481609, #774028. */ 390104349SphkSTART_TEST(test_latin1_umlauts) 391104349Sphk{ 392104349Sphk char *text = 393104349Sphk "<?xml version='1.0' encoding='iso-8859-1'?>\n" 394178848Scokane "<e a='\xE4 \xF6 \xFC ä ö ü ä ö ü >'\n" 395178848Scokane " >\xE4 \xF6 \xFC ä ö ü ä ö ü ></e>"; 396104349Sphk char *utf8 = 397104349Sphk "\xC3\xA4 \xC3\xB6 \xC3\xBC " 398104349Sphk "\xC3\xA4 \xC3\xB6 \xC3\xBC " 399178848Scokane "\xC3\xA4 \xC3\xB6 \xC3\xBC >"; 400104349Sphk run_character_check(text, utf8); 401104349Sphk XML_ParserReset(parser, NULL); 402104349Sphk run_attribute_check(text, utf8); 403104349Sphk} 404104349SphkEND_TEST 405104349Sphk 406178848Scokane/* Regression test #1 for SF bug #653180. */ 407178848ScokaneSTART_TEST(test_line_number_after_parse) 408178848Scokane{ 409178848Scokane char *text = 410178848Scokane "<tag>\n" 411178848Scokane "\n" 412178848Scokane "\n</tag>"; 413178848Scokane XML_Size lineno; 414178848Scokane 415178848Scokane if (XML_Parse(parser, text, strlen(text), XML_FALSE) == XML_STATUS_ERROR) 416178848Scokane xml_failure(parser); 417178848Scokane lineno = XML_GetCurrentLineNumber(parser); 418178848Scokane if (lineno != 4) { 419178848Scokane char buffer[100]; 420178848Scokane sprintf(buffer, 421178848Scokane "expected 4 lines, saw %" XML_FMT_INT_MOD "u", lineno); 422178848Scokane fail(buffer); 423178848Scokane } 424178848Scokane} 425178848ScokaneEND_TEST 426178848Scokane 427178848Scokane/* Regression test #2 for SF bug #653180. */ 428178848ScokaneSTART_TEST(test_column_number_after_parse) 429104349Sphk{ 430178848Scokane char *text = "<tag></tag>"; 431178848Scokane XML_Size colno; 432178848Scokane 433178848Scokane if (XML_Parse(parser, text, strlen(text), XML_FALSE) == XML_STATUS_ERROR) 434178848Scokane xml_failure(parser); 435178848Scokane colno = XML_GetCurrentColumnNumber(parser); 436178848Scokane if (colno != 11) { 437178848Scokane char buffer[100]; 438178848Scokane sprintf(buffer, 439178848Scokane "expected 11 columns, saw %" XML_FMT_INT_MOD "u", colno); 440178848Scokane fail(buffer); 441178848Scokane } 442178848Scokane} 443178848ScokaneEND_TEST 444178848Scokane 445178848Scokanestatic void XMLCALL 446178848Scokanestart_element_event_handler2(void *userData, const XML_Char *name, 447178848Scokane const XML_Char **attr) 448178848Scokane{ 449178848Scokane CharData *storage = (CharData *) userData; 450178848Scokane char buffer[100]; 451178848Scokane 452178848Scokane sprintf(buffer, 453178848Scokane "<%s> at col:%" XML_FMT_INT_MOD "u line:%"\ 454178848Scokane XML_FMT_INT_MOD "u\n", name, 455178848Scokane XML_GetCurrentColumnNumber(parser), 456178848Scokane XML_GetCurrentLineNumber(parser)); 457178848Scokane CharData_AppendString(storage, buffer); 458178848Scokane} 459178848Scokane 460178848Scokanestatic void XMLCALL 461178848Scokaneend_element_event_handler2(void *userData, const XML_Char *name) 462178848Scokane{ 463178848Scokane CharData *storage = (CharData *) userData; 464178848Scokane char buffer[100]; 465178848Scokane 466178848Scokane sprintf(buffer, 467178848Scokane "</%s> at col:%" XML_FMT_INT_MOD "u line:%"\ 468178848Scokane XML_FMT_INT_MOD "u\n", name, 469178848Scokane XML_GetCurrentColumnNumber(parser), 470178848Scokane XML_GetCurrentLineNumber(parser)); 471178848Scokane CharData_AppendString(storage, buffer); 472178848Scokane} 473178848Scokane 474178848Scokane/* Regression test #3 for SF bug #653180. */ 475178848ScokaneSTART_TEST(test_line_and_column_numbers_inside_handlers) 476178848Scokane{ 477104349Sphk char *text = 478178848Scokane "<a>\n" /* Unix end-of-line */ 479178848Scokane " <b>\r\n" /* Windows end-of-line */ 480178848Scokane " <c/>\r" /* Mac OS end-of-line */ 481178848Scokane " </b>\n" 482178848Scokane " <d>\n" 483178848Scokane " <f/>\n" 484178848Scokane " </d>\n" 485178848Scokane "</a>"; 486178848Scokane char *expected = 487178848Scokane "<a> at col:0 line:1\n" 488178848Scokane "<b> at col:2 line:2\n" 489178848Scokane "<c> at col:4 line:3\n" 490178848Scokane "</c> at col:8 line:3\n" 491178848Scokane "</b> at col:2 line:4\n" 492178848Scokane "<d> at col:2 line:5\n" 493178848Scokane "<f> at col:4 line:6\n" 494178848Scokane "</f> at col:8 line:6\n" 495178848Scokane "</d> at col:2 line:7\n" 496178848Scokane "</a> at col:0 line:8\n"; 497178848Scokane CharData storage; 498178848Scokane 499178848Scokane CharData_Init(&storage); 500178848Scokane XML_SetUserData(parser, &storage); 501178848Scokane XML_SetStartElementHandler(parser, start_element_event_handler2); 502178848Scokane XML_SetEndElementHandler(parser, end_element_event_handler2); 503178848Scokane if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) 504104349Sphk xml_failure(parser); 505178848Scokane 506178848Scokane CharData_CheckString(&storage, expected); 507178848Scokane} 508178848ScokaneEND_TEST 509178848Scokane 510178848Scokane/* Regression test #4 for SF bug #653180. */ 511178848ScokaneSTART_TEST(test_line_number_after_error) 512178848Scokane{ 513178848Scokane char *text = 514178848Scokane "<a>\n" 515178848Scokane " <b>\n" 516178848Scokane " </a>"; /* missing </b> */ 517178848Scokane XML_Size lineno; 518178848Scokane if (XML_Parse(parser, text, strlen(text), XML_FALSE) != XML_STATUS_ERROR) 519178848Scokane fail("Expected a parse error"); 520178848Scokane 521104349Sphk lineno = XML_GetCurrentLineNumber(parser); 522104349Sphk if (lineno != 3) { 523104349Sphk char buffer[100]; 524178848Scokane sprintf(buffer, "expected 3 lines, saw %" XML_FMT_INT_MOD "u", lineno); 525104349Sphk fail(buffer); 526104349Sphk } 527104349Sphk} 528104349SphkEND_TEST 529178848Scokane 530178848Scokane/* Regression test #5 for SF bug #653180. */ 531178848ScokaneSTART_TEST(test_column_number_after_error) 532178848Scokane{ 533178848Scokane char *text = 534178848Scokane "<a>\n" 535178848Scokane " <b>\n" 536178848Scokane " </a>"; /* missing </b> */ 537178848Scokane XML_Size colno; 538178848Scokane if (XML_Parse(parser, text, strlen(text), XML_FALSE) != XML_STATUS_ERROR) 539178848Scokane fail("Expected a parse error"); 540104349Sphk 541178848Scokane colno = XML_GetCurrentColumnNumber(parser); 542178848Scokane if (colno != 4) { 543178848Scokane char buffer[100]; 544178848Scokane sprintf(buffer, 545178848Scokane "expected 4 columns, saw %" XML_FMT_INT_MOD "u", colno); 546178848Scokane fail(buffer); 547178848Scokane } 548178848Scokane} 549178848ScokaneEND_TEST 550178848Scokane 551104349Sphk/* Regression test for SF bug #478332. */ 552104349SphkSTART_TEST(test_really_long_lines) 553104349Sphk{ 554104349Sphk /* This parses an input line longer than INIT_DATA_BUF_SIZE 555104349Sphk characters long (defined to be 1024 in xmlparse.c). We take a 556104349Sphk really cheesy approach to building the input buffer, because 557104349Sphk this avoids writing bugs in buffer-filling code. 558104349Sphk */ 559104349Sphk char *text = 560104349Sphk "<e>" 561104349Sphk /* 64 chars */ 562104349Sphk "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 563104349Sphk /* until we have at least 1024 characters on the line: */ 564104349Sphk "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 565104349Sphk "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 566104349Sphk "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 567104349Sphk "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 568104349Sphk "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 569104349Sphk "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 570104349Sphk "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 571104349Sphk "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 572104349Sphk "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 573104349Sphk "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 574104349Sphk "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 575104349Sphk "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 576104349Sphk "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 577104349Sphk "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 578104349Sphk "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 579104349Sphk "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" 580104349Sphk "</e>"; 581178848Scokane if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) 582104349Sphk xml_failure(parser); 583104349Sphk} 584104349SphkEND_TEST 585104349Sphk 586104349Sphk 587104349Sphk/* 588104349Sphk * Element event tests. 589104349Sphk */ 590104349Sphk 591178848Scokanestatic void XMLCALL 592104349Sphkend_element_event_handler(void *userData, const XML_Char *name) 593104349Sphk{ 594104349Sphk CharData *storage = (CharData *) userData; 595104349Sphk CharData_AppendString(storage, "/"); 596104349Sphk CharData_AppendXMLChars(storage, name, -1); 597104349Sphk} 598104349Sphk 599104349SphkSTART_TEST(test_end_element_events) 600104349Sphk{ 601104349Sphk char *text = "<a><b><c/></b><d><f/></d></a>"; 602104349Sphk char *expected = "/c/b/f/d/a"; 603104349Sphk CharData storage; 604104349Sphk 605104349Sphk CharData_Init(&storage); 606104349Sphk XML_SetUserData(parser, &storage); 607104349Sphk XML_SetEndElementHandler(parser, end_element_event_handler); 608178848Scokane if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) 609104349Sphk xml_failure(parser); 610104349Sphk CharData_CheckString(&storage, expected); 611104349Sphk} 612104349SphkEND_TEST 613104349Sphk 614104349Sphk 615104349Sphk/* 616104349Sphk * Attribute tests. 617104349Sphk */ 618104349Sphk 619104349Sphk/* Helpers used by the following test; this checks any "attr" and "refs" 620104349Sphk attributes to make sure whitespace has been normalized. 621104349Sphk 622104349Sphk Return true if whitespace has been normalized in a string, using 623104349Sphk the rules for attribute value normalization. The 'is_cdata' flag 624104349Sphk is needed since CDATA attributes don't need to have multiple 625104349Sphk whitespace characters collapsed to a single space, while other 626104349Sphk attribute data types do. (Section 3.3.3 of the recommendation.) 627104349Sphk*/ 628104349Sphkstatic int 629104349Sphkis_whitespace_normalized(const XML_Char *s, int is_cdata) 630104349Sphk{ 631104349Sphk int blanks = 0; 632104349Sphk int at_start = 1; 633104349Sphk while (*s) { 634104349Sphk if (*s == ' ') 635104349Sphk ++blanks; 636104349Sphk else if (*s == '\t' || *s == '\n' || *s == '\r') 637104349Sphk return 0; 638104349Sphk else { 639104349Sphk if (at_start) { 640104349Sphk at_start = 0; 641104349Sphk if (blanks && !is_cdata) 642104349Sphk /* illegal leading blanks */ 643104349Sphk return 0; 644104349Sphk } 645104349Sphk else if (blanks > 1 && !is_cdata) 646104349Sphk return 0; 647104349Sphk blanks = 0; 648104349Sphk } 649104349Sphk ++s; 650104349Sphk } 651104349Sphk if (blanks && !is_cdata) 652104349Sphk return 0; 653104349Sphk return 1; 654104349Sphk} 655104349Sphk 656104349Sphk/* Check the attribute whitespace checker: */ 657104349Sphkstatic void 658104349Sphktesthelper_is_whitespace_normalized(void) 659104349Sphk{ 660104349Sphk assert(is_whitespace_normalized("abc", 0)); 661104349Sphk assert(is_whitespace_normalized("abc", 1)); 662104349Sphk assert(is_whitespace_normalized("abc def ghi", 0)); 663104349Sphk assert(is_whitespace_normalized("abc def ghi", 1)); 664104349Sphk assert(!is_whitespace_normalized(" abc def ghi", 0)); 665104349Sphk assert(is_whitespace_normalized(" abc def ghi", 1)); 666104349Sphk assert(!is_whitespace_normalized("abc def ghi", 0)); 667104349Sphk assert(is_whitespace_normalized("abc def ghi", 1)); 668104349Sphk assert(!is_whitespace_normalized("abc def ghi ", 0)); 669104349Sphk assert(is_whitespace_normalized("abc def ghi ", 1)); 670104349Sphk assert(!is_whitespace_normalized(" ", 0)); 671104349Sphk assert(is_whitespace_normalized(" ", 1)); 672104349Sphk assert(!is_whitespace_normalized("\t", 0)); 673104349Sphk assert(!is_whitespace_normalized("\t", 1)); 674104349Sphk assert(!is_whitespace_normalized("\n", 0)); 675104349Sphk assert(!is_whitespace_normalized("\n", 1)); 676104349Sphk assert(!is_whitespace_normalized("\r", 0)); 677104349Sphk assert(!is_whitespace_normalized("\r", 1)); 678104349Sphk assert(!is_whitespace_normalized("abc\t def", 1)); 679104349Sphk} 680104349Sphk 681178848Scokanestatic void XMLCALL 682104349Sphkcheck_attr_contains_normalized_whitespace(void *userData, 683104349Sphk const XML_Char *name, 684104349Sphk const XML_Char **atts) 685104349Sphk{ 686104349Sphk int i; 687104349Sphk for (i = 0; atts[i] != NULL; i += 2) { 688104349Sphk const XML_Char *attrname = atts[i]; 689104349Sphk const XML_Char *value = atts[i + 1]; 690104349Sphk if (strcmp("attr", attrname) == 0 691104349Sphk || strcmp("ents", attrname) == 0 692104349Sphk || strcmp("refs", attrname) == 0) { 693104349Sphk if (!is_whitespace_normalized(value, 0)) { 694104349Sphk char buffer[256]; 695104349Sphk sprintf(buffer, "attribute value not normalized: %s='%s'", 696104349Sphk attrname, value); 697104349Sphk fail(buffer); 698104349Sphk } 699104349Sphk } 700104349Sphk } 701104349Sphk} 702104349Sphk 703104349SphkSTART_TEST(test_attr_whitespace_normalization) 704104349Sphk{ 705104349Sphk char *text = 706104349Sphk "<!DOCTYPE doc [\n" 707104349Sphk " <!ATTLIST doc\n" 708104349Sphk " attr NMTOKENS #REQUIRED\n" 709104349Sphk " ents ENTITIES #REQUIRED\n" 710104349Sphk " refs IDREFS #REQUIRED>\n" 711104349Sphk "]>\n" 712104349Sphk "<doc attr=' a b c\t\td\te\t' refs=' id-1 \t id-2\t\t' \n" 713104349Sphk " ents=' ent-1 \t\r\n" 714104349Sphk " ent-2 ' >\n" 715104349Sphk " <e id='id-1'/>\n" 716104349Sphk " <e id='id-2'/>\n" 717104349Sphk "</doc>"; 718104349Sphk 719104349Sphk XML_SetStartElementHandler(parser, 720104349Sphk check_attr_contains_normalized_whitespace); 721178848Scokane if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) 722104349Sphk xml_failure(parser); 723104349Sphk} 724104349SphkEND_TEST 725104349Sphk 726104349Sphk 727104349Sphk/* 728104349Sphk * XML declaration tests. 729104349Sphk */ 730104349Sphk 731104349SphkSTART_TEST(test_xmldecl_misplaced) 732104349Sphk{ 733104349Sphk expect_failure("\n" 734104349Sphk "<?xml version='1.0'?>\n" 735104349Sphk "<a/>", 736104349Sphk XML_ERROR_MISPLACED_XML_PI, 737104349Sphk "failed to report misplaced XML declaration"); 738104349Sphk} 739104349SphkEND_TEST 740104349Sphk 741104349Sphk/* Regression test for SF bug #584832. */ 742178848Scokanestatic int XMLCALL 743104349SphkUnknownEncodingHandler(void *data,const XML_Char *encoding,XML_Encoding *info) 744104349Sphk{ 745104349Sphk if (strcmp(encoding,"unsupported-encoding") == 0) { 746104349Sphk int i; 747104349Sphk for (i = 0; i < 256; ++i) 748104349Sphk info->map[i] = i; 749178848Scokane info->data = NULL; 750178848Scokane info->convert = NULL; 751178848Scokane info->release = NULL; 752178848Scokane return XML_STATUS_OK; 753104349Sphk } 754178848Scokane return XML_STATUS_ERROR; 755104349Sphk} 756104349Sphk 757104349SphkSTART_TEST(test_unknown_encoding_internal_entity) 758104349Sphk{ 759104349Sphk char *text = 760104349Sphk "<?xml version='1.0' encoding='unsupported-encoding'?>\n" 761104349Sphk "<!DOCTYPE test [<!ENTITY foo 'bar'>]>\n" 762104349Sphk "<test a='&foo;'/>"; 763104349Sphk 764104349Sphk XML_SetUnknownEncodingHandler(parser, UnknownEncodingHandler, NULL); 765178848Scokane if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) 766104349Sphk xml_failure(parser); 767104349Sphk} 768104349SphkEND_TEST 769104349Sphk 770178848Scokane/* Regression test for SF bug #620106. */ 771178848Scokanestatic int XMLCALL 772178848Scokaneexternal_entity_loader_set_encoding(XML_Parser parser, 773178848Scokane const XML_Char *context, 774178848Scokane const XML_Char *base, 775178848Scokane const XML_Char *systemId, 776178848Scokane const XML_Char *publicId) 777178848Scokane{ 778178848Scokane /* This text says it's an unsupported encoding, but it's really 779178848Scokane UTF-8, which we tell Expat using XML_SetEncoding(). 780178848Scokane */ 781178848Scokane char *text = 782178848Scokane "<?xml encoding='iso-8859-3'?>" 783178848Scokane "\xC3\xA9"; 784178848Scokane XML_Parser extparser; 785178848Scokane 786178848Scokane extparser = XML_ExternalEntityParserCreate(parser, context, NULL); 787178848Scokane if (extparser == NULL) 788178848Scokane fail("Could not create external entity parser."); 789178848Scokane if (!XML_SetEncoding(extparser, "utf-8")) 790178848Scokane fail("XML_SetEncoding() ignored for external entity"); 791178848Scokane if ( XML_Parse(extparser, text, strlen(text), XML_TRUE) 792178848Scokane == XML_STATUS_ERROR) { 793178848Scokane xml_failure(parser); 794178848Scokane return 0; 795178848Scokane } 796178848Scokane return 1; 797178848Scokane} 798178848Scokane 799178848ScokaneSTART_TEST(test_ext_entity_set_encoding) 800178848Scokane{ 801178848Scokane char *text = 802178848Scokane "<!DOCTYPE doc [\n" 803178848Scokane " <!ENTITY en SYSTEM 'http://xml.libexpat.org/dummy.ent'>\n" 804178848Scokane "]>\n" 805178848Scokane "<doc>&en;</doc>"; 806178848Scokane 807178848Scokane XML_SetExternalEntityRefHandler(parser, 808178848Scokane external_entity_loader_set_encoding); 809178848Scokane run_character_check(text, "\xC3\xA9"); 810178848Scokane} 811178848ScokaneEND_TEST 812178848Scokane 813104349Sphk/* Test that no error is reported for unknown entities if we don't 814104349Sphk read an external subset. This was fixed in Expat 1.95.5. 815104349Sphk*/ 816104349SphkSTART_TEST(test_wfc_undeclared_entity_unread_external_subset) { 817104349Sphk char *text = 818104349Sphk "<!DOCTYPE doc SYSTEM 'foo'>\n" 819104349Sphk "<doc>&entity;</doc>"; 820104349Sphk 821178848Scokane if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) 822104349Sphk xml_failure(parser); 823104349Sphk} 824104349SphkEND_TEST 825104349Sphk 826104349Sphk/* Test that an error is reported for unknown entities if we don't 827104349Sphk have an external subset. 828104349Sphk*/ 829104349SphkSTART_TEST(test_wfc_undeclared_entity_no_external_subset) { 830104349Sphk expect_failure("<doc>&entity;</doc>", 831104349Sphk XML_ERROR_UNDEFINED_ENTITY, 832104349Sphk "Parser did not report undefined entity w/out a DTD."); 833104349Sphk} 834104349SphkEND_TEST 835104349Sphk 836104349Sphk/* Test that an error is reported for unknown entities if we don't 837104349Sphk read an external subset, but have been declared standalone. 838104349Sphk*/ 839104349SphkSTART_TEST(test_wfc_undeclared_entity_standalone) { 840104349Sphk char *text = 841104349Sphk "<?xml version='1.0' encoding='us-ascii' standalone='yes'?>\n" 842104349Sphk "<!DOCTYPE doc SYSTEM 'foo'>\n" 843104349Sphk "<doc>&entity;</doc>"; 844104349Sphk 845104349Sphk expect_failure(text, 846104349Sphk XML_ERROR_UNDEFINED_ENTITY, 847104349Sphk "Parser did not report undefined entity (standalone)."); 848104349Sphk} 849104349SphkEND_TEST 850104349Sphk 851178848Scokanestatic int XMLCALL 852104349Sphkexternal_entity_loader(XML_Parser parser, 853104349Sphk const XML_Char *context, 854104349Sphk const XML_Char *base, 855104349Sphk const XML_Char *systemId, 856104349Sphk const XML_Char *publicId) 857104349Sphk{ 858104349Sphk char *text = (char *)XML_GetUserData(parser); 859104349Sphk XML_Parser extparser; 860104349Sphk 861104349Sphk extparser = XML_ExternalEntityParserCreate(parser, context, NULL); 862104349Sphk if (extparser == NULL) 863104349Sphk fail("Could not create external entity parser."); 864178848Scokane if ( XML_Parse(extparser, text, strlen(text), XML_TRUE) 865178848Scokane == XML_STATUS_ERROR) { 866104349Sphk xml_failure(parser); 867178848Scokane return XML_STATUS_ERROR; 868104349Sphk } 869178848Scokane return XML_STATUS_OK; 870104349Sphk} 871104349Sphk 872104349Sphk/* Test that an error is reported for unknown entities if we have read 873178848Scokane an external subset, and standalone is true. 874104349Sphk*/ 875178848ScokaneSTART_TEST(test_wfc_undeclared_entity_with_external_subset_standalone) { 876104349Sphk char *text = 877178848Scokane "<?xml version='1.0' encoding='us-ascii' standalone='yes'?>\n" 878104349Sphk "<!DOCTYPE doc SYSTEM 'foo'>\n" 879104349Sphk "<doc>&entity;</doc>"; 880104349Sphk char *foo_text = 881104349Sphk "<!ELEMENT doc (#PCDATA)*>"; 882104349Sphk 883104349Sphk XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 884104349Sphk XML_SetUserData(parser, foo_text); 885104349Sphk XML_SetExternalEntityRefHandler(parser, external_entity_loader); 886104349Sphk expect_failure(text, 887104349Sphk XML_ERROR_UNDEFINED_ENTITY, 888178848Scokane "Parser did not report undefined entity (external DTD)."); 889104349Sphk} 890104349SphkEND_TEST 891104349Sphk 892178848Scokane/* Test that no error is reported for unknown entities if we have read 893178848Scokane an external subset, and standalone is false. 894178848Scokane*/ 895178848ScokaneSTART_TEST(test_wfc_undeclared_entity_with_external_subset) { 896178848Scokane char *text = 897178848Scokane "<?xml version='1.0' encoding='us-ascii'?>\n" 898178848Scokane "<!DOCTYPE doc SYSTEM 'foo'>\n" 899178848Scokane "<doc>&entity;</doc>"; 900178848Scokane char *foo_text = 901178848Scokane "<!ELEMENT doc (#PCDATA)*>"; 902178848Scokane 903178848Scokane XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 904178848Scokane XML_SetUserData(parser, foo_text); 905178848Scokane XML_SetExternalEntityRefHandler(parser, external_entity_loader); 906178848Scokane if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) 907178848Scokane xml_failure(parser); 908178848Scokane} 909178848ScokaneEND_TEST 910178848Scokane 911104349SphkSTART_TEST(test_wfc_no_recursive_entity_refs) 912104349Sphk{ 913104349Sphk char *text = 914104349Sphk "<!DOCTYPE doc [\n" 915104349Sphk " <!ENTITY entity '&entity;'>\n" 916104349Sphk "]>\n" 917104349Sphk "<doc>&entity;</doc>"; 918104349Sphk 919104349Sphk expect_failure(text, 920104349Sphk XML_ERROR_RECURSIVE_ENTITY_REF, 921104349Sphk "Parser did not report recursive entity reference."); 922104349Sphk} 923104349SphkEND_TEST 924104349Sphk 925178848Scokane/* Regression test for SF bug #483514. */ 926178848ScokaneSTART_TEST(test_dtd_default_handling) 927178848Scokane{ 928178848Scokane char *text = 929178848Scokane "<!DOCTYPE doc [\n" 930178848Scokane "<!ENTITY e SYSTEM 'http://xml.libexpat.org/e'>\n" 931178848Scokane "<!NOTATION n SYSTEM 'http://xml.libexpat.org/n'>\n" 932178848Scokane "<!ELEMENT doc EMPTY>\n" 933178848Scokane "<!ATTLIST doc a CDATA #IMPLIED>\n" 934178848Scokane "<?pi in dtd?>\n" 935178848Scokane "<!--comment in dtd-->\n" 936178848Scokane "]><doc/>"; 937104349Sphk 938178848Scokane XML_SetDefaultHandler(parser, accumulate_characters); 939178848Scokane XML_SetDoctypeDeclHandler(parser, 940178848Scokane dummy_start_doctype_handler, 941178848Scokane dummy_end_doctype_handler); 942178848Scokane XML_SetEntityDeclHandler(parser, dummy_entity_decl_handler); 943178848Scokane XML_SetNotationDeclHandler(parser, dummy_notation_decl_handler); 944178848Scokane XML_SetElementDeclHandler(parser, dummy_element_decl_handler); 945178848Scokane XML_SetAttlistDeclHandler(parser, dummy_attlist_decl_handler); 946178848Scokane XML_SetProcessingInstructionHandler(parser, dummy_pi_handler); 947178848Scokane XML_SetCommentHandler(parser, dummy_comment_handler); 948178848Scokane run_character_check(text, "\n\n\n\n\n\n\n<doc/>"); 949178848Scokane} 950178848ScokaneEND_TEST 951178848Scokane 952178848Scokane/* See related SF bug #673791. 953178848Scokane When namespace processing is enabled, setting the namespace URI for 954178848Scokane a prefix is not allowed; this test ensures that it *is* allowed 955178848Scokane when namespace processing is not enabled. 956178848Scokane (See Namespaces in XML, section 2.) 957178848Scokane*/ 958178848ScokaneSTART_TEST(test_empty_ns_without_namespaces) 959178848Scokane{ 960178848Scokane char *text = 961178848Scokane "<doc xmlns:prefix='http://www.example.com/'>\n" 962178848Scokane " <e xmlns:prefix=''/>\n" 963178848Scokane "</doc>"; 964178848Scokane 965178848Scokane if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) 966178848Scokane xml_failure(parser); 967178848Scokane} 968178848ScokaneEND_TEST 969178848Scokane 970178848Scokane/* Regression test for SF bug #824420. 971178848Scokane Checks that an xmlns:prefix attribute set in an attribute's default 972178848Scokane value isn't misinterpreted. 973178848Scokane*/ 974178848ScokaneSTART_TEST(test_ns_in_attribute_default_without_namespaces) 975178848Scokane{ 976178848Scokane char *text = 977178848Scokane "<!DOCTYPE e:element [\n" 978178848Scokane " <!ATTLIST e:element\n" 979178848Scokane " xmlns:e CDATA 'http://example.com/'>\n" 980178848Scokane " ]>\n" 981178848Scokane "<e:element/>"; 982178848Scokane 983178848Scokane if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) 984178848Scokane xml_failure(parser); 985178848Scokane} 986178848ScokaneEND_TEST 987178848Scokane 988178848Scokanestatic char *long_character_data_text = 989178848Scokane "<?xml version='1.0' encoding='iso-8859-1'?><s>" 990178848Scokane "012345678901234567890123456789012345678901234567890123456789" 991178848Scokane "012345678901234567890123456789012345678901234567890123456789" 992178848Scokane "012345678901234567890123456789012345678901234567890123456789" 993178848Scokane "012345678901234567890123456789012345678901234567890123456789" 994178848Scokane "012345678901234567890123456789012345678901234567890123456789" 995178848Scokane "012345678901234567890123456789012345678901234567890123456789" 996178848Scokane "012345678901234567890123456789012345678901234567890123456789" 997178848Scokane "012345678901234567890123456789012345678901234567890123456789" 998178848Scokane "012345678901234567890123456789012345678901234567890123456789" 999178848Scokane "012345678901234567890123456789012345678901234567890123456789" 1000178848Scokane "012345678901234567890123456789012345678901234567890123456789" 1001178848Scokane "012345678901234567890123456789012345678901234567890123456789" 1002178848Scokane "012345678901234567890123456789012345678901234567890123456789" 1003178848Scokane "012345678901234567890123456789012345678901234567890123456789" 1004178848Scokane "012345678901234567890123456789012345678901234567890123456789" 1005178848Scokane "012345678901234567890123456789012345678901234567890123456789" 1006178848Scokane "012345678901234567890123456789012345678901234567890123456789" 1007178848Scokane "012345678901234567890123456789012345678901234567890123456789" 1008178848Scokane "012345678901234567890123456789012345678901234567890123456789" 1009178848Scokane "012345678901234567890123456789012345678901234567890123456789" 1010178848Scokane "</s>"; 1011178848Scokane 1012178848Scokanestatic XML_Bool resumable = XML_FALSE; 1013178848Scokane 1014178848Scokanestatic void 1015178848Scokaneclearing_aborting_character_handler(void *userData, 1016178848Scokane const XML_Char *s, int len) 1017178848Scokane{ 1018178848Scokane XML_StopParser(parser, resumable); 1019178848Scokane XML_SetCharacterDataHandler(parser, NULL); 1020178848Scokane} 1021178848Scokane 1022178848Scokane/* Regression test for SF bug #1515266: missing check of stopped 1023178848Scokane parser in doContext() 'for' loop. */ 1024178848ScokaneSTART_TEST(test_stop_parser_between_char_data_calls) 1025178848Scokane{ 1026178848Scokane /* The sample data must be big enough that there are two calls to 1027178848Scokane the character data handler from within the inner "for" loop of 1028178848Scokane the XML_TOK_DATA_CHARS case in doContent(), and the character 1029178848Scokane handler must stop the parser and clear the character data 1030178848Scokane handler. 1031178848Scokane */ 1032178848Scokane char *text = long_character_data_text; 1033178848Scokane 1034178848Scokane XML_SetCharacterDataHandler(parser, clearing_aborting_character_handler); 1035178848Scokane resumable = XML_FALSE; 1036178848Scokane if (XML_Parse(parser, text, strlen(text), XML_TRUE) != XML_STATUS_ERROR) 1037178848Scokane xml_failure(parser); 1038178848Scokane if (XML_GetErrorCode(parser) != XML_ERROR_ABORTED) 1039178848Scokane xml_failure(parser); 1040178848Scokane} 1041178848ScokaneEND_TEST 1042178848Scokane 1043178848Scokane/* Regression test for SF bug #1515266: missing check of stopped 1044178848Scokane parser in doContext() 'for' loop. */ 1045178848ScokaneSTART_TEST(test_suspend_parser_between_char_data_calls) 1046178848Scokane{ 1047178848Scokane /* The sample data must be big enough that there are two calls to 1048178848Scokane the character data handler from within the inner "for" loop of 1049178848Scokane the XML_TOK_DATA_CHARS case in doContent(), and the character 1050178848Scokane handler must stop the parser and clear the character data 1051178848Scokane handler. 1052178848Scokane */ 1053178848Scokane char *text = long_character_data_text; 1054178848Scokane 1055178848Scokane XML_SetCharacterDataHandler(parser, clearing_aborting_character_handler); 1056178848Scokane resumable = XML_TRUE; 1057178848Scokane if (XML_Parse(parser, text, strlen(text), XML_TRUE) != XML_STATUS_SUSPENDED) 1058178848Scokane xml_failure(parser); 1059178848Scokane if (XML_GetErrorCode(parser) != XML_ERROR_NONE) 1060178848Scokane xml_failure(parser); 1061178848Scokane} 1062178848ScokaneEND_TEST 1063178848Scokane 1064178848Scokane 1065104349Sphk/* 1066104349Sphk * Namespaces tests. 1067104349Sphk */ 1068104349Sphk 1069104349Sphkstatic void 1070104349Sphknamespace_setup(void) 1071104349Sphk{ 1072104349Sphk parser = XML_ParserCreateNS(NULL, ' '); 1073104349Sphk if (parser == NULL) 1074104349Sphk fail("Parser not created."); 1075104349Sphk} 1076104349Sphk 1077104349Sphkstatic void 1078104349Sphknamespace_teardown(void) 1079104349Sphk{ 1080104349Sphk basic_teardown(); 1081104349Sphk} 1082104349Sphk 1083104349Sphk/* Check that an element name and attribute name match the expected values. 1084104349Sphk The expected values are passed as an array reference of string pointers 1085104349Sphk provided as the userData argument; the first is the expected 1086104349Sphk element name, and the second is the expected attribute name. 1087104349Sphk*/ 1088178848Scokanestatic void XMLCALL 1089104349Sphktriplet_start_checker(void *userData, const XML_Char *name, 1090104349Sphk const XML_Char **atts) 1091104349Sphk{ 1092104349Sphk char **elemstr = (char **)userData; 1093104349Sphk char buffer[1024]; 1094104349Sphk if (strcmp(elemstr[0], name) != 0) { 1095104349Sphk sprintf(buffer, "unexpected start string: '%s'", name); 1096104349Sphk fail(buffer); 1097104349Sphk } 1098104349Sphk if (strcmp(elemstr[1], atts[0]) != 0) { 1099104349Sphk sprintf(buffer, "unexpected attribute string: '%s'", atts[0]); 1100104349Sphk fail(buffer); 1101104349Sphk } 1102104349Sphk} 1103104349Sphk 1104104349Sphk/* Check that the element name passed to the end-element handler matches 1105104349Sphk the expected value. The expected value is passed as the first element 1106104349Sphk in an array of strings passed as the userData argument. 1107104349Sphk*/ 1108178848Scokanestatic void XMLCALL 1109104349Sphktriplet_end_checker(void *userData, const XML_Char *name) 1110104349Sphk{ 1111104349Sphk char **elemstr = (char **)userData; 1112104349Sphk if (strcmp(elemstr[0], name) != 0) { 1113104349Sphk char buffer[1024]; 1114104349Sphk sprintf(buffer, "unexpected end string: '%s'", name); 1115104349Sphk fail(buffer); 1116104349Sphk } 1117104349Sphk} 1118104349Sphk 1119104349SphkSTART_TEST(test_return_ns_triplet) 1120104349Sphk{ 1121104349Sphk char *text = 1122104349Sphk "<foo:e xmlns:foo='http://expat.sf.net/' bar:a='12'\n" 1123104349Sphk " xmlns:bar='http://expat.sf.net/'></foo:e>"; 1124104349Sphk char *elemstr[] = { 1125104349Sphk "http://expat.sf.net/ e foo", 1126104349Sphk "http://expat.sf.net/ a bar" 1127104349Sphk }; 1128178848Scokane XML_SetReturnNSTriplet(parser, XML_TRUE); 1129104349Sphk XML_SetUserData(parser, elemstr); 1130104349Sphk XML_SetElementHandler(parser, triplet_start_checker, triplet_end_checker); 1131178848Scokane if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) 1132104349Sphk xml_failure(parser); 1133104349Sphk} 1134104349SphkEND_TEST 1135104349Sphk 1136178848Scokanestatic void XMLCALL 1137104349Sphkoverwrite_start_checker(void *userData, const XML_Char *name, 1138104349Sphk const XML_Char **atts) 1139104349Sphk{ 1140104349Sphk CharData *storage = (CharData *) userData; 1141104349Sphk CharData_AppendString(storage, "start "); 1142104349Sphk CharData_AppendXMLChars(storage, name, -1); 1143104349Sphk while (*atts != NULL) { 1144104349Sphk CharData_AppendString(storage, "\nattribute "); 1145104349Sphk CharData_AppendXMLChars(storage, *atts, -1); 1146104349Sphk atts += 2; 1147104349Sphk } 1148104349Sphk CharData_AppendString(storage, "\n"); 1149104349Sphk} 1150104349Sphk 1151178848Scokanestatic void XMLCALL 1152104349Sphkoverwrite_end_checker(void *userData, const XML_Char *name) 1153104349Sphk{ 1154104349Sphk CharData *storage = (CharData *) userData; 1155104349Sphk CharData_AppendString(storage, "end "); 1156104349Sphk CharData_AppendXMLChars(storage, name, -1); 1157104349Sphk CharData_AppendString(storage, "\n"); 1158104349Sphk} 1159104349Sphk 1160104349Sphkstatic void 1161104349Sphkrun_ns_tagname_overwrite_test(char *text, char *result) 1162104349Sphk{ 1163104349Sphk CharData storage; 1164104349Sphk CharData_Init(&storage); 1165104349Sphk XML_SetUserData(parser, &storage); 1166104349Sphk XML_SetElementHandler(parser, 1167104349Sphk overwrite_start_checker, overwrite_end_checker); 1168178848Scokane if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) 1169104349Sphk xml_failure(parser); 1170104349Sphk CharData_CheckString(&storage, result); 1171104349Sphk} 1172104349Sphk 1173104349Sphk/* Regression test for SF bug #566334. */ 1174104349SphkSTART_TEST(test_ns_tagname_overwrite) 1175104349Sphk{ 1176104349Sphk char *text = 1177104349Sphk "<n:e xmlns:n='http://xml.libexpat.org/'>\n" 1178104349Sphk " <n:f n:attr='foo'/>\n" 1179104349Sphk " <n:g n:attr2='bar'/>\n" 1180104349Sphk "</n:e>"; 1181104349Sphk char *result = 1182104349Sphk "start http://xml.libexpat.org/ e\n" 1183104349Sphk "start http://xml.libexpat.org/ f\n" 1184104349Sphk "attribute http://xml.libexpat.org/ attr\n" 1185104349Sphk "end http://xml.libexpat.org/ f\n" 1186104349Sphk "start http://xml.libexpat.org/ g\n" 1187104349Sphk "attribute http://xml.libexpat.org/ attr2\n" 1188104349Sphk "end http://xml.libexpat.org/ g\n" 1189104349Sphk "end http://xml.libexpat.org/ e\n"; 1190104349Sphk run_ns_tagname_overwrite_test(text, result); 1191104349Sphk} 1192104349SphkEND_TEST 1193104349Sphk 1194104349Sphk/* Regression test for SF bug #566334. */ 1195104349SphkSTART_TEST(test_ns_tagname_overwrite_triplet) 1196104349Sphk{ 1197104349Sphk char *text = 1198104349Sphk "<n:e xmlns:n='http://xml.libexpat.org/'>\n" 1199104349Sphk " <n:f n:attr='foo'/>\n" 1200104349Sphk " <n:g n:attr2='bar'/>\n" 1201104349Sphk "</n:e>"; 1202104349Sphk char *result = 1203104349Sphk "start http://xml.libexpat.org/ e n\n" 1204104349Sphk "start http://xml.libexpat.org/ f n\n" 1205104349Sphk "attribute http://xml.libexpat.org/ attr n\n" 1206104349Sphk "end http://xml.libexpat.org/ f n\n" 1207104349Sphk "start http://xml.libexpat.org/ g n\n" 1208104349Sphk "attribute http://xml.libexpat.org/ attr2 n\n" 1209104349Sphk "end http://xml.libexpat.org/ g n\n" 1210104349Sphk "end http://xml.libexpat.org/ e n\n"; 1211178848Scokane XML_SetReturnNSTriplet(parser, XML_TRUE); 1212104349Sphk run_ns_tagname_overwrite_test(text, result); 1213104349Sphk} 1214104349SphkEND_TEST 1215104349Sphk 1216178848Scokane 1217178848Scokane/* Regression test for SF bug #620343. */ 1218178848Scokanestatic void XMLCALL 1219178848Scokanestart_element_fail(void *userData, 1220178848Scokane const XML_Char *name, const XML_Char **atts) 1221178848Scokane{ 1222178848Scokane /* We should never get here. */ 1223178848Scokane fail("should never reach start_element_fail()"); 1224178848Scokane} 1225178848Scokane 1226178848Scokanestatic void XMLCALL 1227178848Scokanestart_ns_clearing_start_element(void *userData, 1228178848Scokane const XML_Char *prefix, 1229178848Scokane const XML_Char *uri) 1230178848Scokane{ 1231178848Scokane XML_SetStartElementHandler((XML_Parser) userData, NULL); 1232178848Scokane} 1233178848Scokane 1234178848ScokaneSTART_TEST(test_start_ns_clears_start_element) 1235178848Scokane{ 1236178848Scokane /* This needs to use separate start/end tags; using the empty tag 1237178848Scokane syntax doesn't cause the problematic path through Expat to be 1238178848Scokane taken. 1239178848Scokane */ 1240178848Scokane char *text = "<e xmlns='http://xml.libexpat.org/'></e>"; 1241178848Scokane 1242178848Scokane XML_SetStartElementHandler(parser, start_element_fail); 1243178848Scokane XML_SetStartNamespaceDeclHandler(parser, start_ns_clearing_start_element); 1244178848Scokane XML_UseParserAsHandlerArg(parser); 1245178848Scokane if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) 1246178848Scokane xml_failure(parser); 1247178848Scokane} 1248178848ScokaneEND_TEST 1249178848Scokane 1250178848Scokane/* Regression test for SF bug #616863. */ 1251178848Scokanestatic int XMLCALL 1252178848Scokaneexternal_entity_handler(XML_Parser parser, 1253178848Scokane const XML_Char *context, 1254178848Scokane const XML_Char *base, 1255178848Scokane const XML_Char *systemId, 1256178848Scokane const XML_Char *publicId) 1257178848Scokane{ 1258247513Sdelphij intptr_t callno = 1 + (intptr_t)XML_GetUserData(parser); 1259178848Scokane char *text; 1260178848Scokane XML_Parser p2; 1261178848Scokane 1262178848Scokane if (callno == 1) 1263178848Scokane text = ("<!ELEMENT doc (e+)>\n" 1264178848Scokane "<!ATTLIST doc xmlns CDATA #IMPLIED>\n" 1265178848Scokane "<!ELEMENT e EMPTY>\n"); 1266178848Scokane else 1267178848Scokane text = ("<?xml version='1.0' encoding='us-ascii'?>" 1268178848Scokane "<e/>"); 1269178848Scokane 1270178848Scokane XML_SetUserData(parser, (void *) callno); 1271178848Scokane p2 = XML_ExternalEntityParserCreate(parser, context, NULL); 1272178848Scokane if (XML_Parse(p2, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) { 1273178848Scokane xml_failure(p2); 1274178848Scokane return 0; 1275178848Scokane } 1276178848Scokane XML_ParserFree(p2); 1277178848Scokane return 1; 1278178848Scokane} 1279178848Scokane 1280178848ScokaneSTART_TEST(test_default_ns_from_ext_subset_and_ext_ge) 1281178848Scokane{ 1282178848Scokane char *text = 1283178848Scokane "<?xml version='1.0'?>\n" 1284178848Scokane "<!DOCTYPE doc SYSTEM 'http://xml.libexpat.org/doc.dtd' [\n" 1285178848Scokane " <!ENTITY en SYSTEM 'http://xml.libexpat.org/entity.ent'>\n" 1286178848Scokane "]>\n" 1287178848Scokane "<doc xmlns='http://xml.libexpat.org/ns1'>\n" 1288178848Scokane "&en;\n" 1289178848Scokane "</doc>"; 1290178848Scokane 1291178848Scokane XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); 1292178848Scokane XML_SetExternalEntityRefHandler(parser, external_entity_handler); 1293178848Scokane /* We actually need to set this handler to tickle this bug. */ 1294178848Scokane XML_SetStartElementHandler(parser, dummy_start_element); 1295178848Scokane XML_SetUserData(parser, NULL); 1296178848Scokane if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) 1297178848Scokane xml_failure(parser); 1298178848Scokane} 1299178848ScokaneEND_TEST 1300178848Scokane 1301178848Scokane/* Regression test #1 for SF bug #673791. */ 1302178848ScokaneSTART_TEST(test_ns_prefix_with_empty_uri_1) 1303178848Scokane{ 1304178848Scokane char *text = 1305178848Scokane "<doc xmlns:prefix='http://xml.libexpat.org/'>\n" 1306178848Scokane " <e xmlns:prefix=''/>\n" 1307178848Scokane "</doc>"; 1308178848Scokane 1309178848Scokane expect_failure(text, 1310178848Scokane XML_ERROR_UNDECLARING_PREFIX, 1311178848Scokane "Did not report re-setting namespace" 1312178848Scokane " URI with prefix to ''."); 1313178848Scokane} 1314178848ScokaneEND_TEST 1315178848Scokane 1316178848Scokane/* Regression test #2 for SF bug #673791. */ 1317178848ScokaneSTART_TEST(test_ns_prefix_with_empty_uri_2) 1318178848Scokane{ 1319178848Scokane char *text = 1320178848Scokane "<?xml version='1.0'?>\n" 1321178848Scokane "<docelem xmlns:pre=''/>"; 1322178848Scokane 1323178848Scokane expect_failure(text, 1324178848Scokane XML_ERROR_UNDECLARING_PREFIX, 1325178848Scokane "Did not report setting namespace URI with prefix to ''."); 1326178848Scokane} 1327178848ScokaneEND_TEST 1328178848Scokane 1329178848Scokane/* Regression test #3 for SF bug #673791. */ 1330178848ScokaneSTART_TEST(test_ns_prefix_with_empty_uri_3) 1331178848Scokane{ 1332178848Scokane char *text = 1333178848Scokane "<!DOCTYPE doc [\n" 1334178848Scokane " <!ELEMENT doc EMPTY>\n" 1335178848Scokane " <!ATTLIST doc\n" 1336178848Scokane " xmlns:prefix CDATA ''>\n" 1337178848Scokane "]>\n" 1338178848Scokane "<doc/>"; 1339178848Scokane 1340178848Scokane expect_failure(text, 1341178848Scokane XML_ERROR_UNDECLARING_PREFIX, 1342178848Scokane "Didn't report attr default setting NS w/ prefix to ''."); 1343178848Scokane} 1344178848ScokaneEND_TEST 1345178848Scokane 1346178848Scokane/* Regression test #4 for SF bug #673791. */ 1347178848ScokaneSTART_TEST(test_ns_prefix_with_empty_uri_4) 1348178848Scokane{ 1349178848Scokane char *text = 1350178848Scokane "<!DOCTYPE doc [\n" 1351178848Scokane " <!ELEMENT prefix:doc EMPTY>\n" 1352178848Scokane " <!ATTLIST prefix:doc\n" 1353178848Scokane " xmlns:prefix CDATA 'http://xml.libexpat.org/'>\n" 1354178848Scokane "]>\n" 1355178848Scokane "<prefix:doc/>"; 1356178848Scokane /* Packaged info expected by the end element handler; 1357178848Scokane the weird structuring lets us re-use the triplet_end_checker() 1358178848Scokane function also used for another test. */ 1359178848Scokane char *elemstr[] = { 1360178848Scokane "http://xml.libexpat.org/ doc prefix" 1361178848Scokane }; 1362178848Scokane XML_SetReturnNSTriplet(parser, XML_TRUE); 1363178848Scokane XML_SetUserData(parser, elemstr); 1364178848Scokane XML_SetEndElementHandler(parser, triplet_end_checker); 1365178848Scokane if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) 1366178848Scokane xml_failure(parser); 1367178848Scokane} 1368178848ScokaneEND_TEST 1369178848Scokane 1370178848ScokaneSTART_TEST(test_ns_default_with_empty_uri) 1371178848Scokane{ 1372178848Scokane char *text = 1373178848Scokane "<doc xmlns='http://xml.libexpat.org/'>\n" 1374178848Scokane " <e xmlns=''/>\n" 1375178848Scokane "</doc>"; 1376178848Scokane if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) 1377178848Scokane xml_failure(parser); 1378178848Scokane} 1379178848ScokaneEND_TEST 1380178848Scokane 1381178848Scokane/* Regression test for SF bug #692964: two prefixes for one namespace. */ 1382178848ScokaneSTART_TEST(test_ns_duplicate_attrs_diff_prefixes) 1383178848Scokane{ 1384178848Scokane char *text = 1385178848Scokane "<doc xmlns:a='http://xml.libexpat.org/a'\n" 1386178848Scokane " xmlns:b='http://xml.libexpat.org/a'\n" 1387178848Scokane " a:a='v' b:a='v' />"; 1388178848Scokane expect_failure(text, 1389178848Scokane XML_ERROR_DUPLICATE_ATTRIBUTE, 1390178848Scokane "did not report multiple attributes with same URI+name"); 1391178848Scokane} 1392178848ScokaneEND_TEST 1393178848Scokane 1394178848Scokane/* Regression test for SF bug #695401: unbound prefix. */ 1395178848ScokaneSTART_TEST(test_ns_unbound_prefix_on_attribute) 1396178848Scokane{ 1397178848Scokane char *text = "<doc a:attr=''/>"; 1398178848Scokane expect_failure(text, 1399178848Scokane XML_ERROR_UNBOUND_PREFIX, 1400178848Scokane "did not report unbound prefix on attribute"); 1401178848Scokane} 1402178848ScokaneEND_TEST 1403178848Scokane 1404178848Scokane/* Regression test for SF bug #695401: unbound prefix. */ 1405178848ScokaneSTART_TEST(test_ns_unbound_prefix_on_element) 1406178848Scokane{ 1407178848Scokane char *text = "<a:doc/>"; 1408178848Scokane expect_failure(text, 1409178848Scokane XML_ERROR_UNBOUND_PREFIX, 1410178848Scokane "did not report unbound prefix on element"); 1411178848Scokane} 1412178848ScokaneEND_TEST 1413178848Scokane 1414104349Sphkstatic Suite * 1415178848Scokanemake_suite(void) 1416104349Sphk{ 1417104349Sphk Suite *s = suite_create("basic"); 1418104349Sphk TCase *tc_basic = tcase_create("basic tests"); 1419104349Sphk TCase *tc_namespace = tcase_create("XML namespaces"); 1420104349Sphk 1421104349Sphk suite_add_tcase(s, tc_basic); 1422104349Sphk tcase_add_checked_fixture(tc_basic, basic_setup, basic_teardown); 1423104349Sphk tcase_add_test(tc_basic, test_nul_byte); 1424104349Sphk tcase_add_test(tc_basic, test_u0000_char); 1425104349Sphk tcase_add_test(tc_basic, test_bom_utf8); 1426104349Sphk tcase_add_test(tc_basic, test_bom_utf16_be); 1427104349Sphk tcase_add_test(tc_basic, test_bom_utf16_le); 1428104349Sphk tcase_add_test(tc_basic, test_illegal_utf8); 1429104349Sphk tcase_add_test(tc_basic, test_utf16); 1430104349Sphk tcase_add_test(tc_basic, test_utf16_le_epilog_newline); 1431104349Sphk tcase_add_test(tc_basic, test_latin1_umlauts); 1432104349Sphk /* Regression test for SF bug #491986. */ 1433104349Sphk tcase_add_test(tc_basic, test_danish_latin1); 1434104349Sphk /* Regression test for SF bug #514281. */ 1435104349Sphk tcase_add_test(tc_basic, test_french_charref_hexidecimal); 1436104349Sphk tcase_add_test(tc_basic, test_french_charref_decimal); 1437104349Sphk tcase_add_test(tc_basic, test_french_latin1); 1438104349Sphk tcase_add_test(tc_basic, test_french_utf8); 1439104349Sphk tcase_add_test(tc_basic, test_utf8_false_rejection); 1440178848Scokane tcase_add_test(tc_basic, test_line_number_after_parse); 1441178848Scokane tcase_add_test(tc_basic, test_column_number_after_parse); 1442178848Scokane tcase_add_test(tc_basic, test_line_and_column_numbers_inside_handlers); 1443178848Scokane tcase_add_test(tc_basic, test_line_number_after_error); 1444178848Scokane tcase_add_test(tc_basic, test_column_number_after_error); 1445104349Sphk tcase_add_test(tc_basic, test_really_long_lines); 1446104349Sphk tcase_add_test(tc_basic, test_end_element_events); 1447104349Sphk tcase_add_test(tc_basic, test_attr_whitespace_normalization); 1448104349Sphk tcase_add_test(tc_basic, test_xmldecl_misplaced); 1449104349Sphk tcase_add_test(tc_basic, test_unknown_encoding_internal_entity); 1450104349Sphk tcase_add_test(tc_basic, 1451104349Sphk test_wfc_undeclared_entity_unread_external_subset); 1452104349Sphk tcase_add_test(tc_basic, test_wfc_undeclared_entity_no_external_subset); 1453104349Sphk tcase_add_test(tc_basic, test_wfc_undeclared_entity_standalone); 1454104349Sphk tcase_add_test(tc_basic, test_wfc_undeclared_entity_with_external_subset); 1455178848Scokane tcase_add_test(tc_basic, 1456178848Scokane test_wfc_undeclared_entity_with_external_subset_standalone); 1457104349Sphk tcase_add_test(tc_basic, test_wfc_no_recursive_entity_refs); 1458178848Scokane tcase_add_test(tc_basic, test_ext_entity_set_encoding); 1459178848Scokane tcase_add_test(tc_basic, test_dtd_default_handling); 1460178848Scokane tcase_add_test(tc_basic, test_empty_ns_without_namespaces); 1461178848Scokane tcase_add_test(tc_basic, test_ns_in_attribute_default_without_namespaces); 1462178848Scokane tcase_add_test(tc_basic, test_stop_parser_between_char_data_calls); 1463178848Scokane tcase_add_test(tc_basic, test_suspend_parser_between_char_data_calls); 1464104349Sphk 1465104349Sphk suite_add_tcase(s, tc_namespace); 1466104349Sphk tcase_add_checked_fixture(tc_namespace, 1467104349Sphk namespace_setup, namespace_teardown); 1468104349Sphk tcase_add_test(tc_namespace, test_return_ns_triplet); 1469104349Sphk tcase_add_test(tc_namespace, test_ns_tagname_overwrite); 1470104349Sphk tcase_add_test(tc_namespace, test_ns_tagname_overwrite_triplet); 1471178848Scokane tcase_add_test(tc_namespace, test_start_ns_clears_start_element); 1472178848Scokane tcase_add_test(tc_namespace, test_default_ns_from_ext_subset_and_ext_ge); 1473178848Scokane tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_1); 1474178848Scokane tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_2); 1475178848Scokane tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_3); 1476178848Scokane tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_4); 1477178848Scokane tcase_add_test(tc_namespace, test_ns_default_with_empty_uri); 1478178848Scokane tcase_add_test(tc_namespace, test_ns_duplicate_attrs_diff_prefixes); 1479178848Scokane tcase_add_test(tc_namespace, test_ns_unbound_prefix_on_attribute); 1480178848Scokane tcase_add_test(tc_namespace, test_ns_unbound_prefix_on_element); 1481104349Sphk 1482104349Sphk return s; 1483104349Sphk} 1484104349Sphk 1485104349Sphk 1486104349Sphkint 1487104349Sphkmain(int argc, char *argv[]) 1488104349Sphk{ 1489104349Sphk int i, nf; 1490104349Sphk int verbosity = CK_NORMAL; 1491178848Scokane Suite *s = make_suite(); 1492104349Sphk SRunner *sr = srunner_create(s); 1493104349Sphk 1494104349Sphk /* run the tests for internal helper functions */ 1495104349Sphk testhelper_is_whitespace_normalized(); 1496104349Sphk 1497104349Sphk for (i = 1; i < argc; ++i) { 1498104349Sphk char *opt = argv[i]; 1499104349Sphk if (strcmp(opt, "-v") == 0 || strcmp(opt, "--verbose") == 0) 1500104349Sphk verbosity = CK_VERBOSE; 1501104349Sphk else if (strcmp(opt, "-q") == 0 || strcmp(opt, "--quiet") == 0) 1502104349Sphk verbosity = CK_SILENT; 1503104349Sphk else { 1504104349Sphk fprintf(stderr, "runtests: unknown option '%s'\n", opt); 1505104349Sphk return 2; 1506104349Sphk } 1507104349Sphk } 1508178848Scokane if (verbosity != CK_SILENT) 1509178848Scokane printf("Expat version: %s\n", XML_ExpatVersion()); 1510104349Sphk srunner_run_all(sr, verbosity); 1511104349Sphk nf = srunner_ntests_failed(sr); 1512104349Sphk srunner_free(sr); 1513104349Sphk 1514104349Sphk return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE; 1515104349Sphk} 1516