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