Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/external/mit/expat/dist/tests/runtests.c,v rcsdiff: /ftp/cvs/cvsroot/src/external/mit/expat/dist/tests/runtests.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.1.1.2.2.2 retrieving revision 1.1.1.3 diff -u -p -r1.1.1.2.2.2 -r1.1.1.3 --- src/external/mit/expat/dist/tests/runtests.c 2012/04/17 00:04:44 1.1.1.2.2.2 +++ src/external/mit/expat/dist/tests/runtests.c 2017/02/04 10:16:13 1.1.1.3 @@ -13,9 +13,14 @@ #include #include #include +#include /* ptrdiff_t */ +#ifndef __cplusplus +# include +#endif #include "expat.h" #include "chardata.h" +#include "internal.h" /* for UNUSED_P only */ #include "minicheck.h" #if defined(__amigaos__) && defined(__USE_INLINE__) @@ -66,13 +71,34 @@ _xml_failure(XML_Parser parser, const ch _fail_unless(0, file, line, buffer); } +static enum XML_Status +_XML_Parse_SINGLE_BYTES(XML_Parser parser, const char *s, int len, int isFinal) +{ + enum XML_Status res = XML_STATUS_ERROR; + int offset = 0; + + if (len == 0) { + return XML_Parse(parser, s, len, isFinal); + } + + for (; offset < len; offset++) { + const int innerIsFinal = (offset == len - 1) && isFinal; + const char c = s[offset]; /* to help out-of-bounds detection */ + res = XML_Parse(parser, &c, sizeof(char), innerIsFinal); + if (res != XML_STATUS_OK) { + return res; + } + } + return res; +} + #define xml_failure(parser) _xml_failure((parser), __FILE__, __LINE__) static void -_expect_failure(char *text, enum XML_Error errorCode, char *errorMessage, - char *file, int lineno) +_expect_failure(const char *text, enum XML_Error errorCode, const char *errorMessage, + const char *file, int lineno) { - if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_OK) + if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_OK) /* Hackish use of _fail_unless() macro, but let's us report the right filename and line number. */ _fail_unless(0, file, lineno, errorMessage); @@ -89,63 +115,63 @@ _expect_failure(char *text, enum XML_Err */ static void XMLCALL -dummy_start_doctype_handler(void *userData, - const XML_Char *doctypeName, - const XML_Char *sysid, - const XML_Char *pubid, - int has_internal_subset) +dummy_start_doctype_handler(void *UNUSED_P(userData), + const XML_Char *UNUSED_P(doctypeName), + const XML_Char *UNUSED_P(sysid), + const XML_Char *UNUSED_P(pubid), + int UNUSED_P(has_internal_subset)) {} static void XMLCALL -dummy_end_doctype_handler(void *userData) +dummy_end_doctype_handler(void *UNUSED_P(userData)) {} static void XMLCALL -dummy_entity_decl_handler(void *userData, - const XML_Char *entityName, - int is_parameter_entity, - const XML_Char *value, - int value_length, - const XML_Char *base, - const XML_Char *systemId, - const XML_Char *publicId, - const XML_Char *notationName) +dummy_entity_decl_handler(void *UNUSED_P(userData), + const XML_Char *UNUSED_P(entityName), + int UNUSED_P(is_parameter_entity), + const XML_Char *UNUSED_P(value), + int UNUSED_P(value_length), + const XML_Char *UNUSED_P(base), + const XML_Char *UNUSED_P(systemId), + const XML_Char *UNUSED_P(publicId), + const XML_Char *UNUSED_P(notationName)) {} static void XMLCALL -dummy_notation_decl_handler(void *userData, - const XML_Char *notationName, - const XML_Char *base, - const XML_Char *systemId, - const XML_Char *publicId) +dummy_notation_decl_handler(void *UNUSED_P(userData), + const XML_Char *UNUSED_P(notationName), + const XML_Char *UNUSED_P(base), + const XML_Char *UNUSED_P(systemId), + const XML_Char *UNUSED_P(publicId)) {} static void XMLCALL -dummy_element_decl_handler(void *userData, - const XML_Char *name, - XML_Content *model) +dummy_element_decl_handler(void *UNUSED_P(userData), + const XML_Char *UNUSED_P(name), + XML_Content *UNUSED_P(model)) {} static void XMLCALL -dummy_attlist_decl_handler(void *userData, - const XML_Char *elname, - const XML_Char *attname, - const XML_Char *att_type, - const XML_Char *dflt, - int isrequired) +dummy_attlist_decl_handler(void *UNUSED_P(userData), + const XML_Char *UNUSED_P(elname), + const XML_Char *UNUSED_P(attname), + const XML_Char *UNUSED_P(att_type), + const XML_Char *UNUSED_P(dflt), + int UNUSED_P(isrequired)) {} static void XMLCALL -dummy_comment_handler(void *userData, const XML_Char *data) +dummy_comment_handler(void *UNUSED_P(userData), const XML_Char *UNUSED_P(data)) {} static void XMLCALL -dummy_pi_handler(void *userData, const XML_Char *target, const XML_Char *data) +dummy_pi_handler(void *UNUSED_P(userData), const XML_Char *UNUSED_P(target), const XML_Char *UNUSED_P(data)) {} static void XMLCALL -dummy_start_element(void *userData, - const XML_Char *name, const XML_Char **atts) +dummy_start_element(void *UNUSED_P(userData), + const XML_Char *UNUSED_P(name), const XML_Char **UNUSED_P(atts)) {} @@ -158,7 +184,7 @@ START_TEST(test_nul_byte) char text[] = "\0"; /* test that a NUL byte (in US-ASCII data) is an error */ - if (XML_Parse(parser, text, sizeof(text) - 1, XML_TRUE) == XML_STATUS_OK) + if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text) - 1, XML_TRUE) == XML_STATUS_OK) fail("Parser did not report error on NUL-byte."); if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_TOKEN) xml_failure(parser); @@ -178,9 +204,9 @@ END_TEST START_TEST(test_bom_utf8) { /* This test is really just making sure we don't core on a UTF-8 BOM. */ - char *text = "\357\273\277"; + const char *text = "\357\273\277"; - if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) + if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) xml_failure(parser); } END_TEST @@ -189,7 +215,7 @@ START_TEST(test_bom_utf16_be) { char text[] = "\376\377\0<\0e\0/\0>"; - if (XML_Parse(parser, text, sizeof(text)-1, XML_TRUE) == XML_STATUS_ERROR) + if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text)-1, XML_TRUE) == XML_STATUS_ERROR) xml_failure(parser); } END_TEST @@ -198,7 +224,7 @@ START_TEST(test_bom_utf16_le) { char text[] = "\377\376<\0e\0/\0>\0"; - if (XML_Parse(parser, text, sizeof(text)-1, XML_TRUE) == XML_STATUS_ERROR) + if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text)-1, XML_TRUE) == XML_STATUS_ERROR) xml_failure(parser); } END_TEST @@ -210,7 +236,7 @@ accumulate_characters(void *userData, co } static void XMLCALL -accumulate_attribute(void *userData, const XML_Char *name, +accumulate_attribute(void *userData, const XML_Char *UNUSED_P(name), const XML_Char **atts) { CharData *storage = (CharData *)userData; @@ -222,7 +248,7 @@ accumulate_attribute(void *userData, con static void -_run_character_check(XML_Char *text, XML_Char *expected, +_run_character_check(const XML_Char *text, const XML_Char *expected, const char *file, int line) { CharData storage; @@ -230,7 +256,7 @@ _run_character_check(XML_Char *text, XML CharData_Init(&storage); XML_SetUserData(parser, &storage); XML_SetCharacterDataHandler(parser, accumulate_characters); - if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) + if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) _xml_failure(parser, file, line); CharData_CheckXMLChars(&storage, expected); } @@ -239,7 +265,7 @@ _run_character_check(XML_Char *text, XML _run_character_check(text, expected, __FILE__, __LINE__) static void -_run_attribute_check(XML_Char *text, XML_Char *expected, +_run_attribute_check(const XML_Char *text, const XML_Char *expected, const char *file, int line) { CharData storage; @@ -247,7 +273,7 @@ _run_attribute_check(XML_Char *text, XML CharData_Init(&storage); XML_SetUserData(parser, &storage); XML_SetStartElementHandler(parser, accumulate_attribute); - if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) + if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) _xml_failure(parser, file, line); CharData_CheckXMLChars(&storage, expected); } @@ -258,7 +284,7 @@ _run_attribute_check(XML_Char *text, XML /* Regression test for SF bug #491986. */ START_TEST(test_danish_latin1) { - char *text = + const char *text = "\n" "J\xF8rgen \xE6\xF8\xE5\xC6\xD8\xC5"; run_character_check(text, @@ -270,7 +296,7 @@ END_TEST /* Regression test for SF bug #514281. */ START_TEST(test_french_charref_hexidecimal) { - char *text = + const char *text = "\n" "éèàçêÈ"; run_character_check(text, @@ -280,7 +306,7 @@ END_TEST START_TEST(test_french_charref_decimal) { - char *text = + const char *text = "\n" "éèàçêÈ"; run_character_check(text, @@ -290,7 +316,7 @@ END_TEST START_TEST(test_french_latin1) { - char *text = + const char *text = "\n" "\xE9\xE8\xE0\xE7\xEa\xC8"; run_character_check(text, @@ -300,7 +326,7 @@ END_TEST START_TEST(test_french_utf8) { - char *text = + const char *text = "\n" "\xC3\xA9"; run_character_check(text, "\xC3\xA9"); @@ -314,7 +340,7 @@ END_TEST */ START_TEST(test_utf8_false_rejection) { - char *text = "\xEF\xBA\xBF"; + const char *text = "\xEF\xBA\xBF"; run_character_check(text, "\xEF\xBA\xBF"); } END_TEST @@ -331,7 +357,7 @@ START_TEST(test_illegal_utf8) for (i = 128; i <= 255; ++i) { sprintf(text, "%ccd", i); - if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_OK) { + if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_OK) { sprintf(text, "expected token error for '%c' (ordinal %d) in UTF-8 text", i, i); @@ -345,6 +371,68 @@ START_TEST(test_illegal_utf8) } END_TEST + +/* Examples, not masks: */ +#define UTF8_LEAD_1 "\x7f" /* 0b01111111 */ +#define UTF8_LEAD_2 "\xdf" /* 0b11011111 */ +#define UTF8_LEAD_3 "\xef" /* 0b11101111 */ +#define UTF8_LEAD_4 "\xf7" /* 0b11110111 */ +#define UTF8_FOLLOW "\xbf" /* 0b10111111 */ + +START_TEST(test_utf8_auto_align) +{ + struct TestCase { + ptrdiff_t expectedMovementInChars; + const char * input; + }; + + struct TestCase cases[] = { + {00, ""}, + + {00, UTF8_LEAD_1}, + + {-1, UTF8_LEAD_2}, + {00, UTF8_LEAD_2 UTF8_FOLLOW}, + + {-1, UTF8_LEAD_3}, + {-2, UTF8_LEAD_3 UTF8_FOLLOW}, + {00, UTF8_LEAD_3 UTF8_FOLLOW UTF8_FOLLOW}, + + {-1, UTF8_LEAD_4}, + {-2, UTF8_LEAD_4 UTF8_FOLLOW}, + {-3, UTF8_LEAD_4 UTF8_FOLLOW UTF8_FOLLOW}, + {00, UTF8_LEAD_4 UTF8_FOLLOW UTF8_FOLLOW UTF8_FOLLOW}, + }; + + size_t i = 0; + bool success = true; + for (; i < sizeof(cases) / sizeof(*cases); i++) { + const char * fromLim = cases[i].input + strlen(cases[i].input); + const char * const fromLimInitially = fromLim; + ptrdiff_t actualMovementInChars; + + align_limit_to_full_utf8_characters(cases[i].input, &fromLim); + + actualMovementInChars = (fromLim - fromLimInitially); + if (actualMovementInChars != cases[i].expectedMovementInChars) { + size_t j = 0; + success = false; + printf("[-] UTF-8 case %2lu: Expected movement by %2ld chars" + ", actually moved by %2ld chars: \"", + i + 1, cases[i].expectedMovementInChars, actualMovementInChars); + for (; j < strlen(cases[i].input); j++) { + printf("\\x%02x", (unsigned char)cases[i].input[j]); + } + printf("\"\n"); + } + } + + if (! success) { + fail("UTF-8 auto-alignment is not bullet-proof\n"); + } +} +END_TEST + START_TEST(test_utf16) { /* @@ -358,7 +446,7 @@ START_TEST(test_utf16) "\000<\000d\000o\000c\000 \000a\000=\000'\0001\0002\0003\000'" "\000>\000s\000o\000m\000e\000 \000t\000e\000x\000t\000<\000/" "\000d\000o\000c\000>"; - if (XML_Parse(parser, text, sizeof(text)-1, XML_TRUE) == XML_STATUS_ERROR) + if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text)-1, XML_TRUE) == XML_STATUS_ERROR) xml_failure(parser); } END_TEST @@ -373,12 +461,12 @@ START_TEST(test_utf16_le_epilog_newline) if (first_chunk_bytes >= sizeof(text) - 1) fail("bad value of first_chunk_bytes"); - if ( XML_Parse(parser, text, first_chunk_bytes, XML_FALSE) + if ( _XML_Parse_SINGLE_BYTES(parser, text, first_chunk_bytes, XML_FALSE) == XML_STATUS_ERROR) xml_failure(parser); else { enum XML_Status rc; - rc = XML_Parse(parser, text + first_chunk_bytes, + rc = _XML_Parse_SINGLE_BYTES(parser, text + first_chunk_bytes, sizeof(text) - first_chunk_bytes - 1, XML_TRUE); if (rc == XML_STATUS_ERROR) xml_failure(parser); @@ -389,11 +477,11 @@ END_TEST /* Regression test for SF bug #481609, #774028. */ START_TEST(test_latin1_umlauts) { - char *text = + const char *text = "\n" "\xE4 \xF6 \xFC ä ö ü ä ö ü >"; - char *utf8 = + const char *utf8 = "\xC3\xA4 \xC3\xB6 \xC3\xBC " "\xC3\xA4 \xC3\xB6 \xC3\xBC " "\xC3\xA4 \xC3\xB6 \xC3\xBC >"; @@ -406,13 +494,13 @@ END_TEST /* Regression test #1 for SF bug #653180. */ START_TEST(test_line_number_after_parse) { - char *text = + const char *text = "\n" "\n" "\n"; XML_Size lineno; - if (XML_Parse(parser, text, strlen(text), XML_FALSE) == XML_STATUS_ERROR) + if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_FALSE) == XML_STATUS_ERROR) xml_failure(parser); lineno = XML_GetCurrentLineNumber(parser); if (lineno != 4) { @@ -427,10 +515,10 @@ END_TEST /* Regression test #2 for SF bug #653180. */ START_TEST(test_column_number_after_parse) { - char *text = ""; + const char *text = ""; XML_Size colno; - if (XML_Parse(parser, text, strlen(text), XML_FALSE) == XML_STATUS_ERROR) + if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_FALSE) == XML_STATUS_ERROR) xml_failure(parser); colno = XML_GetCurrentColumnNumber(parser); if (colno != 11) { @@ -444,7 +532,7 @@ END_TEST static void XMLCALL start_element_event_handler2(void *userData, const XML_Char *name, - const XML_Char **attr) + const XML_Char **UNUSED_P(attr)) { CharData *storage = (CharData *) userData; char buffer[100]; @@ -474,7 +562,7 @@ end_element_event_handler2(void *userDat /* Regression test #3 for SF bug #653180. */ START_TEST(test_line_and_column_numbers_inside_handlers) { - char *text = + const char *text = "\n" /* Unix end-of-line */ " \r\n" /* Windows end-of-line */ " \r" /* Mac OS end-of-line */ @@ -483,7 +571,7 @@ START_TEST(test_line_and_column_numbers_ " \n" " \n" ""; - char *expected = + const char *expected = " at col:0 line:1\n" " at col:2 line:2\n" " at col:4 line:3\n" @@ -500,7 +588,7 @@ START_TEST(test_line_and_column_numbers_ XML_SetUserData(parser, &storage); XML_SetStartElementHandler(parser, start_element_event_handler2); XML_SetEndElementHandler(parser, end_element_event_handler2); - if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) + if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) xml_failure(parser); CharData_CheckString(&storage, expected); @@ -510,12 +598,12 @@ END_TEST /* Regression test #4 for SF bug #653180. */ START_TEST(test_line_number_after_error) { - char *text = + const char *text = "\n" " \n" " "; /* missing */ XML_Size lineno; - if (XML_Parse(parser, text, strlen(text), XML_FALSE) != XML_STATUS_ERROR) + if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_FALSE) != XML_STATUS_ERROR) fail("Expected a parse error"); lineno = XML_GetCurrentLineNumber(parser); @@ -530,12 +618,12 @@ END_TEST /* Regression test #5 for SF bug #653180. */ START_TEST(test_column_number_after_error) { - char *text = + const char *text = "\n" " \n" " "; /* missing */ XML_Size colno; - if (XML_Parse(parser, text, strlen(text), XML_FALSE) != XML_STATUS_ERROR) + if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_FALSE) != XML_STATUS_ERROR) fail("Expected a parse error"); colno = XML_GetCurrentColumnNumber(parser); @@ -556,7 +644,7 @@ START_TEST(test_really_long_lines) really cheesy approach to building the input buffer, because this avoids writing bugs in buffer-filling code. */ - char *text = + const char *text = "" /* 64 chars */ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" @@ -578,7 +666,7 @@ START_TEST(test_really_long_lines) "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+" ""; - if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) + if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) xml_failure(parser); } END_TEST @@ -598,14 +686,14 @@ end_element_event_handler(void *userData START_TEST(test_end_element_events) { - char *text = ""; - char *expected = "/c/b/f/d/a"; + const char *text = ""; + const char *expected = "/c/b/f/d/a"; CharData storage; CharData_Init(&storage); XML_SetUserData(parser, &storage); XML_SetEndElementHandler(parser, end_element_event_handler); - if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) + if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) xml_failure(parser); CharData_CheckString(&storage, expected); } @@ -679,8 +767,8 @@ testhelper_is_whitespace_normalized(void } static void XMLCALL -check_attr_contains_normalized_whitespace(void *userData, - const XML_Char *name, +check_attr_contains_normalized_whitespace(void *UNUSED_P(userData), + const XML_Char *UNUSED_P(name), const XML_Char **atts) { int i; @@ -702,7 +790,7 @@ check_attr_contains_normalized_whitespac START_TEST(test_attr_whitespace_normalization) { - char *text = + const char *text = "\n" "]>\n" ""; XML_SetUnknownEncodingHandler(parser, UnknownEncodingHandler, NULL); - if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) + if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) xml_failure(parser); } END_TEST @@ -771,14 +859,14 @@ END_TEST static int XMLCALL external_entity_loader_set_encoding(XML_Parser parser, const XML_Char *context, - const XML_Char *base, - const XML_Char *systemId, - const XML_Char *publicId) + const XML_Char *UNUSED_P(base), + const XML_Char *UNUSED_P(systemId), + const XML_Char *UNUSED_P(publicId)) { /* This text says it's an unsupported encoding, but it's really UTF-8, which we tell Expat using XML_SetEncoding(). */ - char *text = + const char *text = "" "\xC3\xA9"; XML_Parser extparser; @@ -788,7 +876,7 @@ external_entity_loader_set_encoding(XML_ fail("Could not create external entity parser."); if (!XML_SetEncoding(extparser, "utf-8")) fail("XML_SetEncoding() ignored for external entity"); - if ( XML_Parse(extparser, text, strlen(text), XML_TRUE) + if ( _XML_Parse_SINGLE_BYTES(extparser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) { xml_failure(parser); return 0; @@ -798,7 +886,7 @@ external_entity_loader_set_encoding(XML_ START_TEST(test_ext_entity_set_encoding) { - char *text = + const char *text = "\n" "]>\n" @@ -814,11 +902,11 @@ END_TEST read an external subset. This was fixed in Expat 1.95.5. */ START_TEST(test_wfc_undeclared_entity_unread_external_subset) { - char *text = + const char *text = "\n" "&entity;"; - if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) + if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) xml_failure(parser); } END_TEST @@ -837,7 +925,7 @@ END_TEST read an external subset, but have been declared standalone. */ START_TEST(test_wfc_undeclared_entity_standalone) { - char *text = + const char *text = "\n" "\n" "&entity;"; @@ -851,9 +939,9 @@ END_TEST static int XMLCALL external_entity_loader(XML_Parser parser, const XML_Char *context, - const XML_Char *base, - const XML_Char *systemId, - const XML_Char *publicId) + const XML_Char *UNUSED_P(base), + const XML_Char *UNUSED_P(systemId), + const XML_Char *UNUSED_P(publicId)) { char *text = (char *)XML_GetUserData(parser); XML_Parser extparser; @@ -861,7 +949,7 @@ external_entity_loader(XML_Parser parser extparser = XML_ExternalEntityParserCreate(parser, context, NULL); if (extparser == NULL) fail("Could not create external entity parser."); - if ( XML_Parse(extparser, text, strlen(text), XML_TRUE) + if ( _XML_Parse_SINGLE_BYTES(extparser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) { xml_failure(parser); return XML_STATUS_ERROR; @@ -873,11 +961,11 @@ external_entity_loader(XML_Parser parser an external subset, and standalone is true. */ START_TEST(test_wfc_undeclared_entity_with_external_subset_standalone) { - char *text = + const char *text = "\n" "\n" "&entity;"; - char *foo_text = + char foo_text[] = ""; XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); @@ -893,24 +981,24 @@ END_TEST an external subset, and standalone is false. */ START_TEST(test_wfc_undeclared_entity_with_external_subset) { - char *text = + const char *text = "\n" "\n" "&entity;"; - char *foo_text = + char foo_text[] = ""; XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); XML_SetUserData(parser, foo_text); XML_SetExternalEntityRefHandler(parser, external_entity_loader); - if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) + if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) xml_failure(parser); } END_TEST START_TEST(test_wfc_no_recursive_entity_refs) { - char *text = + const char *text = "\n" "]>\n" @@ -925,7 +1013,7 @@ END_TEST /* Regression test for SF bug #483514. */ START_TEST(test_dtd_default_handling) { - char *text = + const char *text = "\n" "\n" @@ -957,12 +1045,12 @@ END_TEST */ START_TEST(test_empty_ns_without_namespaces) { - char *text = + const char *text = "\n" " \n" ""; - if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) + if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) xml_failure(parser); } END_TEST @@ -973,19 +1061,19 @@ END_TEST */ START_TEST(test_ns_in_attribute_default_without_namespaces) { - char *text = + const char *text = "\n" " ]>\n" ""; - if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) + if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) xml_failure(parser); } END_TEST -static char *long_character_data_text = +static const char *long_character_data_text = "" "012345678901234567890123456789012345678901234567890123456789" "012345678901234567890123456789012345678901234567890123456789" @@ -1012,8 +1100,8 @@ static char *long_character_data_text = static XML_Bool resumable = XML_FALSE; static void -clearing_aborting_character_handler(void *userData, - const XML_Char *s, int len) +clearing_aborting_character_handler(void *UNUSED_P(userData), + const XML_Char *UNUSED_P(s), int UNUSED_P(len)) { XML_StopParser(parser, resumable); XML_SetCharacterDataHandler(parser, NULL); @@ -1029,11 +1117,11 @@ START_TEST(test_stop_parser_between_char handler must stop the parser and clear the character data handler. */ - char *text = long_character_data_text; + const char *text = long_character_data_text; XML_SetCharacterDataHandler(parser, clearing_aborting_character_handler); resumable = XML_FALSE; - if (XML_Parse(parser, text, strlen(text), XML_TRUE) != XML_STATUS_ERROR) + if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) != XML_STATUS_ERROR) xml_failure(parser); if (XML_GetErrorCode(parser) != XML_ERROR_ABORTED) xml_failure(parser); @@ -1050,17 +1138,112 @@ START_TEST(test_suspend_parser_between_c handler must stop the parser and clear the character data handler. */ - char *text = long_character_data_text; + const char *text = long_character_data_text; XML_SetCharacterDataHandler(parser, clearing_aborting_character_handler); resumable = XML_TRUE; - if (XML_Parse(parser, text, strlen(text), XML_TRUE) != XML_STATUS_SUSPENDED) + if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) != XML_STATUS_SUSPENDED) xml_failure(parser); if (XML_GetErrorCode(parser) != XML_ERROR_NONE) xml_failure(parser); } END_TEST +START_TEST(test_good_cdata_ascii) +{ + const char *text = "Hello, world!]]>"; + const char *expected = "Hello, world!"; + + CharData storage; + CharData_Init(&storage); + XML_SetUserData(parser, &storage); + XML_SetCharacterDataHandler(parser, accumulate_characters); + + if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) + xml_failure(parser); + CharData_CheckXMLChars(&storage, expected); +} +END_TEST + +START_TEST(test_good_cdata_utf16) +{ + /* Test data is: + * + * + */ + const char text[] = + "\0<\0?\0x\0m\0l\0" + " \0v\0e\0r\0s\0i\0o\0n\0=\0'\0\x31\0.\0\x30\0'\0" + " \0e\0n\0c\0o\0d\0i\0n\0g\0=\0'\0u\0t\0f\0-\0""1\0""6\0'" + "\0?\0>\0\n" + "\0<\0a\0>\0<\0!\0[\0C\0D\0A\0T\0A\0[\0h\0e\0l\0l\0o\0]\0]\0>\0<\0/\0a\0>"; + const char *expected = "hello"; + + CharData storage; + CharData_Init(&storage); + XML_SetUserData(parser, &storage); + XML_SetCharacterDataHandler(parser, accumulate_characters); + + if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text) - 1, XML_TRUE) == XML_STATUS_ERROR) + xml_failure(parser); + CharData_CheckXMLChars(&storage, expected); +} +END_TEST + +START_TEST(test_bad_cdata) +{ + struct CaseData { + const char *text; + enum XML_Error expectedError; + }; + + struct CaseData cases[] = { + {"<", XML_ERROR_UNCLOSED_TOKEN}, + {"", XML_ERROR_INVALID_TOKEN}, + {"", XML_ERROR_UNCLOSED_TOKEN}, /* ?! */ + {"", XML_ERROR_UNCLOSED_TOKEN}, /* ?! */ + {"", XML_ERROR_INVALID_TOKEN}, + {"", XML_ERROR_INVALID_TOKEN}, + {"", XML_ERROR_INVALID_TOKEN}, + {"", XML_ERROR_INVALID_TOKEN}, + + {"", XML_ERROR_UNCLOSED_CDATA_SECTION}, + {"", XML_ERROR_UNCLOSED_CDATA_SECTION}, + {"", XML_ERROR_UNCLOSED_CDATA_SECTION} + }; + + size_t i = 0; + for (; i < sizeof(cases) / sizeof(struct CaseData); i++) { + const enum XML_Status actualStatus = _XML_Parse_SINGLE_BYTES( + parser, cases[i].text, strlen(cases[i].text), XML_TRUE); + const enum XML_Error actualError = XML_GetErrorCode(parser); + + assert(actualStatus == XML_STATUS_ERROR); + + if (actualError != cases[i].expectedError) { + char message[100]; + sprintf(message, "Expected error %d but got error %d for case %u: \"%s\"\n", + cases[i].expectedError, actualError, (unsigned int)i + 1, cases[i].text); + fail(message); + } + + XML_ParserReset(parser, NULL); + } +} +END_TEST + /* * Namespaces tests. @@ -1118,17 +1301,17 @@ triplet_end_checker(void *userData, cons START_TEST(test_return_ns_triplet) { - char *text = + const char *text = ""; - char *elemstr[] = { + const char *elemstr[] = { "http://expat.sf.net/ e foo", "http://expat.sf.net/ a bar" }; XML_SetReturnNSTriplet(parser, XML_TRUE); XML_SetUserData(parser, elemstr); XML_SetElementHandler(parser, triplet_start_checker, triplet_end_checker); - if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) + if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) xml_failure(parser); } END_TEST @@ -1158,14 +1341,14 @@ overwrite_end_checker(void *userData, co } static void -run_ns_tagname_overwrite_test(char *text, char *result) +run_ns_tagname_overwrite_test(const char *text, const char *result) { CharData storage; CharData_Init(&storage); XML_SetUserData(parser, &storage); XML_SetElementHandler(parser, overwrite_start_checker, overwrite_end_checker); - if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) + if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) xml_failure(parser); CharData_CheckString(&storage, result); } @@ -1173,12 +1356,12 @@ run_ns_tagname_overwrite_test(char *text /* Regression test for SF bug #566334. */ START_TEST(test_ns_tagname_overwrite) { - char *text = + const char *text = "\n" " \n" " \n" ""; - char *result = + const char *result = "start http://xml.libexpat.org/ e\n" "start http://xml.libexpat.org/ f\n" "attribute http://xml.libexpat.org/ attr\n" @@ -1194,12 +1377,12 @@ END_TEST /* Regression test for SF bug #566334. */ START_TEST(test_ns_tagname_overwrite_triplet) { - char *text = + const char *text = "\n" " \n" " \n" ""; - char *result = + const char *result = "start http://xml.libexpat.org/ e n\n" "start http://xml.libexpat.org/ f n\n" "attribute http://xml.libexpat.org/ attr n\n" @@ -1216,8 +1399,8 @@ END_TEST /* Regression test for SF bug #620343. */ static void XMLCALL -start_element_fail(void *userData, - const XML_Char *name, const XML_Char **atts) +start_element_fail(void *UNUSED_P(userData), + const XML_Char *UNUSED_P(name), const XML_Char **UNUSED_P(atts)) { /* We should never get here. */ fail("should never reach start_element_fail()"); @@ -1225,8 +1408,8 @@ start_element_fail(void *userData, static void XMLCALL start_ns_clearing_start_element(void *userData, - const XML_Char *prefix, - const XML_Char *uri) + const XML_Char *UNUSED_P(prefix), + const XML_Char *UNUSED_P(uri)) { XML_SetStartElementHandler((XML_Parser) userData, NULL); } @@ -1237,12 +1420,12 @@ START_TEST(test_start_ns_clears_start_el syntax doesn't cause the problematic path through Expat to be taken. */ - char *text = ""; + const char *text = ""; XML_SetStartElementHandler(parser, start_element_fail); XML_SetStartNamespaceDeclHandler(parser, start_ns_clearing_start_element); XML_UseParserAsHandlerArg(parser); - if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) + if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) xml_failure(parser); } END_TEST @@ -1251,12 +1434,12 @@ END_TEST static int XMLCALL external_entity_handler(XML_Parser parser, const XML_Char *context, - const XML_Char *base, - const XML_Char *systemId, - const XML_Char *publicId) + const XML_Char *UNUSED_P(base), + const XML_Char *UNUSED_P(systemId), + const XML_Char *UNUSED_P(publicId)) { intptr_t callno = 1 + (intptr_t)XML_GetUserData(parser); - char *text; + const char *text; XML_Parser p2; if (callno == 1) @@ -1269,7 +1452,7 @@ external_entity_handler(XML_Parser parse XML_SetUserData(parser, (void *) callno); p2 = XML_ExternalEntityParserCreate(parser, context, NULL); - if (XML_Parse(p2, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) { + if (_XML_Parse_SINGLE_BYTES(p2, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) { xml_failure(p2); return 0; } @@ -1279,7 +1462,7 @@ external_entity_handler(XML_Parser parse START_TEST(test_default_ns_from_ext_subset_and_ext_ge) { - char *text = + const char *text = "\n" "\n" @@ -1293,7 +1476,7 @@ START_TEST(test_default_ns_from_ext_subs /* We actually need to set this handler to tickle this bug. */ XML_SetStartElementHandler(parser, dummy_start_element); XML_SetUserData(parser, NULL); - if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) + if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) xml_failure(parser); } END_TEST @@ -1301,7 +1484,7 @@ END_TEST /* Regression test #1 for SF bug #673791. */ START_TEST(test_ns_prefix_with_empty_uri_1) { - char *text = + const char *text = "\n" " \n" ""; @@ -1316,7 +1499,7 @@ END_TEST /* Regression test #2 for SF bug #673791. */ START_TEST(test_ns_prefix_with_empty_uri_2) { - char *text = + const char *text = "\n" ""; @@ -1329,7 +1512,7 @@ END_TEST /* Regression test #3 for SF bug #673791. */ START_TEST(test_ns_prefix_with_empty_uri_3) { - char *text = + const char *text = "\n" " \n" " \n" " \n" ""; - if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) + if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) xml_failure(parser); } END_TEST @@ -1381,7 +1564,7 @@ END_TEST /* Regression test for SF bug #692964: two prefixes for one namespace. */ START_TEST(test_ns_duplicate_attrs_diff_prefixes) { - char *text = + const char *text = ""; @@ -1394,7 +1577,7 @@ END_TEST /* Regression test for SF bug #695401: unbound prefix. */ START_TEST(test_ns_unbound_prefix_on_attribute) { - char *text = ""; + const char *text = ""; expect_failure(text, XML_ERROR_UNBOUND_PREFIX, "did not report unbound prefix on attribute"); @@ -1404,7 +1587,7 @@ END_TEST /* Regression test for SF bug #695401: unbound prefix. */ START_TEST(test_ns_unbound_prefix_on_element) { - char *text = ""; + const char *text = ""; expect_failure(text, XML_ERROR_UNBOUND_PREFIX, "did not report unbound prefix on element"); @@ -1426,6 +1609,7 @@ make_suite(void) tcase_add_test(tc_basic, test_bom_utf16_be); tcase_add_test(tc_basic, test_bom_utf16_le); tcase_add_test(tc_basic, test_illegal_utf8); + tcase_add_test(tc_basic, test_utf8_auto_align); tcase_add_test(tc_basic, test_utf16); tcase_add_test(tc_basic, test_utf16_le_epilog_newline); tcase_add_test(tc_basic, test_latin1_umlauts); @@ -1461,6 +1645,9 @@ make_suite(void) tcase_add_test(tc_basic, test_ns_in_attribute_default_without_namespaces); tcase_add_test(tc_basic, test_stop_parser_between_char_data_calls); tcase_add_test(tc_basic, test_suspend_parser_between_char_data_calls); + tcase_add_test(tc_basic, test_good_cdata_ascii); + tcase_add_test(tc_basic, test_good_cdata_utf16); + tcase_add_test(tc_basic, test_bad_cdata); suite_add_tcase(s, tc_namespace); tcase_add_checked_fixture(tc_namespace,