Move some entity suspension tests out of runtests.c

This commit is contained in:
Rhodri James 2022-10-28 20:52:32 +01:00
parent b08ce35a73
commit dc9689b1c2
4 changed files with 140 additions and 133 deletions

View file

@ -3340,6 +3340,117 @@ START_TEST(test_partial_char_in_epilog) {
}
END_TEST
/* Test resuming a parse suspended in entity substitution */
START_TEST(test_suspend_resume_internal_entity) {
const char *text
= "<!DOCTYPE doc [\n"
"<!ENTITY foo '<suspend>Hi<suspend>Ho</suspend></suspend>'>\n"
"]>\n"
"<doc>&foo;</doc>\n";
const XML_Char *expected1 = XCS("Hi");
const XML_Char *expected2 = XCS("HiHo");
CharData storage;
CharData_Init(&storage);
XML_SetStartElementHandler(g_parser, start_element_suspender);
XML_SetCharacterDataHandler(g_parser, accumulate_characters);
XML_SetUserData(g_parser, &storage);
if (XML_Parse(g_parser, text, (int)strlen(text), XML_TRUE)
!= XML_STATUS_SUSPENDED)
xml_failure(g_parser);
CharData_CheckXMLChars(&storage, XCS(""));
if (XML_ResumeParser(g_parser) != XML_STATUS_SUSPENDED)
xml_failure(g_parser);
CharData_CheckXMLChars(&storage, expected1);
if (XML_ResumeParser(g_parser) != XML_STATUS_OK)
xml_failure(g_parser);
CharData_CheckXMLChars(&storage, expected2);
}
END_TEST
START_TEST(test_suspend_resume_internal_entity_issue_629) {
const char *const text
= "<!DOCTYPE a [<!ENTITY e '<!--COMMENT-->a'>]><a>&e;<b>\n"
"<"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"/>"
"</b></a>";
const size_t firstChunkSizeBytes = 54;
XML_Parser parser = XML_ParserCreate(NULL);
XML_SetUserData(parser, parser);
XML_SetCommentHandler(parser, suspending_comment_handler);
if (XML_Parse(parser, text, (int)firstChunkSizeBytes, XML_FALSE)
!= XML_STATUS_SUSPENDED)
xml_failure(parser);
if (XML_ResumeParser(parser) != XML_STATUS_OK)
xml_failure(parser);
if (XML_Parse(parser, text + firstChunkSizeBytes,
(int)(strlen(text) - firstChunkSizeBytes), XML_TRUE)
!= XML_STATUS_OK)
xml_failure(parser);
XML_ParserFree(parser);
}
END_TEST
/* Test syntax error is caught at parse resumption */
START_TEST(test_resume_entity_with_syntax_error) {
const char *text = "<!DOCTYPE doc [\n"
"<!ENTITY foo '<suspend>Hi</wombat>'>\n"
"]>\n"
"<doc>&foo;</doc>\n";
XML_SetStartElementHandler(g_parser, start_element_suspender);
if (XML_Parse(g_parser, text, (int)strlen(text), XML_TRUE)
!= XML_STATUS_SUSPENDED)
xml_failure(g_parser);
if (XML_ResumeParser(g_parser) != XML_STATUS_ERROR)
fail("Syntax error in entity not faulted");
if (XML_GetErrorCode(g_parser) != XML_ERROR_TAG_MISMATCH)
xml_failure(g_parser);
}
END_TEST
TCase *
make_basic_test_case(Suite *s) {
TCase *tc_basic = tcase_create("basic tests");
@ -3492,6 +3603,10 @@ make_basic_test_case(Suite *s) {
tcase_add_test(tc_basic, test_suspend_in_sole_empty_tag);
tcase_add_test(tc_basic, test_unfinished_epilog);
tcase_add_test(tc_basic, test_partial_char_in_epilog);
tcase_add_test__ifdef_xml_dtd(tc_basic, test_suspend_resume_internal_entity);
tcase_add_test__ifdef_xml_dtd(tc_basic,
test_suspend_resume_internal_entity_issue_629);
tcase_add_test__ifdef_xml_dtd(tc_basic, test_resume_entity_with_syntax_error);
return tc_basic; /* TEMPORARY: this will become a void function */
}

View file

@ -158,6 +158,17 @@ suspending_end_handler(void *userData, const XML_Char *s) {
XML_StopParser((XML_Parser)userData, 1);
}
void XMLCALL
start_element_suspender(void *userData, const XML_Char *name,
const XML_Char **atts) {
UNUSED_P(userData);
UNUSED_P(atts);
if (! xcstrcmp(name, XCS("suspend")))
XML_StopParser(g_parser, XML_TRUE);
if (! xcstrcmp(name, XCS("abort")))
XML_StopParser(g_parser, XML_FALSE);
}
/* Text encoding handlers */
int XMLCALL
@ -1162,3 +1173,10 @@ selective_aborting_default_handler(void *userData, const XML_Char *s, int len) {
XML_SetDefaultHandler(g_parser, NULL);
}
}
void XMLCALL
suspending_comment_handler(void *userData, const XML_Char *data) {
UNUSED_P(data);
XML_Parser parser = (XML_Parser)userData;
XML_StopParser(parser, XML_TRUE);
}

View file

@ -95,6 +95,10 @@ extern void XMLCALL counting_start_element_handler(void *userData,
extern void XMLCALL suspending_end_handler(void *userData, const XML_Char *s);
extern void XMLCALL start_element_suspender(void *userData,
const XML_Char *name,
const XML_Char **atts);
/* Text encoding handlers */
extern int XMLCALL UnknownEncodingHandler(void *data, const XML_Char *encoding,
@ -363,6 +367,9 @@ extern void XMLCALL selective_aborting_default_handler(void *userData,
const XML_Char *s,
int len);
extern void XMLCALL suspending_comment_handler(void *userData,
const XML_Char *data);
#endif /* XML_HANDLERS_H */
#ifdef __cplusplus

View file

@ -74,135 +74,6 @@
XML_Parser g_parser = NULL;
/* Test resuming a parse suspended in entity substitution */
static void XMLCALL
start_element_suspender(void *userData, const XML_Char *name,
const XML_Char **atts) {
UNUSED_P(userData);
UNUSED_P(atts);
if (! xcstrcmp(name, XCS("suspend")))
XML_StopParser(g_parser, XML_TRUE);
if (! xcstrcmp(name, XCS("abort")))
XML_StopParser(g_parser, XML_FALSE);
}
START_TEST(test_suspend_resume_internal_entity) {
const char *text
= "<!DOCTYPE doc [\n"
"<!ENTITY foo '<suspend>Hi<suspend>Ho</suspend></suspend>'>\n"
"]>\n"
"<doc>&foo;</doc>\n";
const XML_Char *expected1 = XCS("Hi");
const XML_Char *expected2 = XCS("HiHo");
CharData storage;
CharData_Init(&storage);
XML_SetStartElementHandler(g_parser, start_element_suspender);
XML_SetCharacterDataHandler(g_parser, accumulate_characters);
XML_SetUserData(g_parser, &storage);
if (XML_Parse(g_parser, text, (int)strlen(text), XML_TRUE)
!= XML_STATUS_SUSPENDED)
xml_failure(g_parser);
CharData_CheckXMLChars(&storage, XCS(""));
if (XML_ResumeParser(g_parser) != XML_STATUS_SUSPENDED)
xml_failure(g_parser);
CharData_CheckXMLChars(&storage, expected1);
if (XML_ResumeParser(g_parser) != XML_STATUS_OK)
xml_failure(g_parser);
CharData_CheckXMLChars(&storage, expected2);
}
END_TEST
static void XMLCALL
suspending_comment_handler(void *userData, const XML_Char *data) {
UNUSED_P(data);
XML_Parser parser = (XML_Parser)userData;
XML_StopParser(parser, XML_TRUE);
}
START_TEST(test_suspend_resume_internal_entity_issue_629) {
const char *const text
= "<!DOCTYPE a [<!ENTITY e '<!--COMMENT-->a'>]><a>&e;<b>\n"
"<"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"/>"
"</b></a>";
const size_t firstChunkSizeBytes = 54;
XML_Parser parser = XML_ParserCreate(NULL);
XML_SetUserData(parser, parser);
XML_SetCommentHandler(parser, suspending_comment_handler);
if (XML_Parse(parser, text, (int)firstChunkSizeBytes, XML_FALSE)
!= XML_STATUS_SUSPENDED)
xml_failure(parser);
if (XML_ResumeParser(parser) != XML_STATUS_OK)
xml_failure(parser);
if (XML_Parse(parser, text + firstChunkSizeBytes,
(int)(strlen(text) - firstChunkSizeBytes), XML_TRUE)
!= XML_STATUS_OK)
xml_failure(parser);
XML_ParserFree(parser);
}
END_TEST
/* Test syntax error is caught at parse resumption */
START_TEST(test_resume_entity_with_syntax_error) {
const char *text = "<!DOCTYPE doc [\n"
"<!ENTITY foo '<suspend>Hi</wombat>'>\n"
"]>\n"
"<doc>&foo;</doc>\n";
XML_SetStartElementHandler(g_parser, start_element_suspender);
if (XML_Parse(g_parser, text, (int)strlen(text), XML_TRUE)
!= XML_STATUS_SUSPENDED)
xml_failure(g_parser);
if (XML_ResumeParser(g_parser) != XML_STATUS_ERROR)
fail("Syntax error in entity not faulted");
if (XML_GetErrorCode(g_parser) != XML_ERROR_TAG_MISMATCH)
xml_failure(g_parser);
}
END_TEST
/* Test suspending and resuming in a parameter entity substitution */
static void XMLCALL
element_decl_suspender(void *userData, const XML_Char *name,
@ -7216,10 +7087,6 @@ make_suite(void) {
TCase *tc_accounting = tcase_create("accounting tests");
#endif
tcase_add_test__ifdef_xml_dtd(tc_basic, test_suspend_resume_internal_entity);
tcase_add_test__ifdef_xml_dtd(tc_basic,
test_suspend_resume_internal_entity_issue_629);
tcase_add_test__ifdef_xml_dtd(tc_basic, test_resume_entity_with_syntax_error);
tcase_add_test__ifdef_xml_dtd(tc_basic, test_suspend_resume_parameter_entity);
tcase_add_test(tc_basic, test_restart_on_error);
tcase_add_test(tc_basic, test_reject_lt_in_attribute_value);