diff --git a/expat/tests/basic_tests.c b/expat/tests/basic_tests.c index 83f310b9..797ef73d 100644 --- a/expat/tests/basic_tests.c +++ b/expat/tests/basic_tests.c @@ -5338,10 +5338,10 @@ make_basic_test_case(Suite *s) { tcase_add_test(tc_basic, test_skipped_null_loaded_ext_entity); tcase_add_test(tc_basic, test_skipped_unloaded_ext_entity); tcase_add_test__ifdef_xml_dtd(tc_basic, test_param_entity_with_trailing_cr); - tcase_add_test(tc_basic, test_invalid_character_entity); - tcase_add_test(tc_basic, test_invalid_character_entity_2); - tcase_add_test(tc_basic, test_invalid_character_entity_3); - tcase_add_test(tc_basic, test_invalid_character_entity_4); + tcase_add_test__if_xml_ge(tc_basic, test_invalid_character_entity); + tcase_add_test__if_xml_ge(tc_basic, test_invalid_character_entity_2); + tcase_add_test__if_xml_ge(tc_basic, test_invalid_character_entity_3); + tcase_add_test__if_xml_ge(tc_basic, test_invalid_character_entity_4); tcase_add_test(tc_basic, test_pi_handled_in_default); tcase_add_test(tc_basic, test_comment_handled_in_default); tcase_add_test(tc_basic, test_pi_yml); diff --git a/expat/tests/handlers.c b/expat/tests/handlers.c index 43fedfce..5cbab324 100644 --- a/expat/tests/handlers.c +++ b/expat/tests/handlers.c @@ -669,6 +669,24 @@ external_entity_suspending_faulter(XML_Parser parser, const XML_Char *context, return XML_STATUS_ERROR; } +int XMLCALL +external_entity_failer__if_not_xml_ge(XML_Parser parser, + const XML_Char *context, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId) { + UNUSED_P(parser); + UNUSED_P(context); + UNUSED_P(base); + UNUSED_P(systemId); + UNUSED_P(publicId); +#if XML_GE == 0 + fail( + "Function external_entity_suspending_failer was called despite XML_GE==0."); +#endif + return XML_STATUS_OK; +} + int XMLCALL external_entity_cr_catcher(XML_Parser parser, const XML_Char *context, const XML_Char *base, const XML_Char *systemId, @@ -1860,6 +1878,36 @@ accumulate_entity_decl(void *userData, const XML_Char *entityName, CharData_AppendXMLChars(storage, XCS("\n"), 1); } +void XMLCALL +accumulate_char_data(void *userData, const XML_Char *s, int len) { + CharData *const storage = (CharData *)userData; + CharData_AppendXMLChars(storage, s, len); +} + +void XMLCALL +accumulate_start_element(void *userData, const XML_Char *name, + const XML_Char **atts) { + CharData *const storage = (CharData *)userData; + CharData_AppendXMLChars(storage, XCS("("), 1); + CharData_AppendXMLChars(storage, name, -1); + + if ((atts != NULL) && (atts[0] != NULL)) { + CharData_AppendXMLChars(storage, XCS("("), 1); + while (atts[0] != NULL) { + CharData_AppendXMLChars(storage, atts[0], -1); + CharData_AppendXMLChars(storage, XCS("="), 1); + CharData_AppendXMLChars(storage, atts[1], -1); + atts += 2; + if (atts[0] != NULL) { + CharData_AppendXMLChars(storage, XCS(","), 1); + } + } + CharData_AppendXMLChars(storage, XCS(")"), 1); + } + + CharData_AppendXMLChars(storage, XCS(")\n"), 2); +} + void XMLCALL checking_default_handler(void *userData, const XML_Char *s, int len) { DefaultCheck *data = (DefaultCheck *)userData; diff --git a/expat/tests/handlers.h b/expat/tests/handlers.h index 60f8fd07..069982e7 100644 --- a/expat/tests/handlers.h +++ b/expat/tests/handlers.h @@ -185,6 +185,9 @@ extern int XMLCALL external_entity_faulter(XML_Parser parser, const XML_Char *base, const XML_Char *systemId, const XML_Char *publicId); +extern int XMLCALL external_entity_failer__if_not_xml_ge( + XML_Parser parser, const XML_Char *context, const XML_Char *base, + const XML_Char *systemId, const XML_Char *publicId); extern int XMLCALL external_entity_null_loader(XML_Parser parser, const XML_Char *context, const XML_Char *base, @@ -561,6 +564,13 @@ extern void XMLCALL accumulate_entity_decl( const XML_Char *systemId, const XML_Char *publicId, const XML_Char *notationName); +extern void XMLCALL accumulate_char_data(void *userData, const XML_Char *s, + int len); + +extern void XMLCALL accumulate_start_element(void *userData, + const XML_Char *name, + const XML_Char **atts); + typedef struct default_check { const XML_Char *expected; const int expectedLen; diff --git a/expat/tests/misc_tests.c b/expat/tests/misc_tests.c index db2b14b9..4167c4cc 100644 --- a/expat/tests/misc_tests.c +++ b/expat/tests/misc_tests.c @@ -406,6 +406,50 @@ START_TEST(test_misc_create_external_entity_parser_with_null_context) { } END_TEST +START_TEST(test_misc_general_entities_support) { + const char *const doc + = "\n" + "\n" + "]>\n" + "[&e1;][&e2;][&'><"]"; + + CharData storage; + CharData_Init(&storage); + + XML_Parser parser = XML_ParserCreate(NULL); + XML_SetUserData(parser, &storage); + XML_SetStartElementHandler(parser, accumulate_start_element); + XML_SetExternalEntityRefHandler(parser, + external_entity_failer__if_not_xml_ge); + XML_SetEntityDeclHandler(parser, accumulate_entity_decl); + XML_SetCharacterDataHandler(parser, accumulate_char_data); + + if (_XML_Parse_SINGLE_BYTES(parser, doc, (int)strlen(doc), XML_TRUE) + != XML_STATUS_OK) { + xml_failure(parser); + } + + XML_ParserFree(parser); + + CharData_CheckXMLChars(&storage, + /* clang-format off */ +#if XML_GE == 1 + XCS("e1=v1\n") + XCS("e2=(null)\n") + XCS("(r(a1=[v1]))\n") + XCS("[v1][][&'><\"]") +#else + XCS("e1=&e1;\n") + XCS("e2=(null)\n") + XCS("(r(a1=[&e1;]))\n") + XCS("[&e1;][&e2;][&'><\"]") +#endif + ); + /* clang-format on */ +} +END_TEST + void make_miscellaneous_test_case(Suite *s) { TCase *tc_misc = tcase_create("miscellaneous tests"); @@ -428,4 +472,5 @@ make_miscellaneous_test_case(Suite *s) { tcase_add_test(tc_misc, test_misc_tag_mismatch_reset_leak); tcase_add_test(tc_misc, test_misc_create_external_entity_parser_with_null_context); + tcase_add_test(tc_misc, test_misc_general_entities_support); }