tests: Cover suspend inside nested entites in internalEntityProcessor more

This commit is contained in:
Sebastian Pipping 2024-09-06 16:47:06 +02:00 committed by Berkay Eren Ürün
parent 3679f63dab
commit 0ab49eafae
3 changed files with 48 additions and 0 deletions

View file

@ -5469,6 +5469,35 @@ START_TEST(test_nested_entity_suspend) {
}
END_TEST
START_TEST(test_nested_entity_suspend_2) {
const char *const text = "<!DOCTYPE doc [\n"
" <!ENTITY ge1 'head1Ztail1'>\n"
" <!ENTITY ge2 'head2&ge1;tail2'>\n"
" <!ENTITY ge3 'head3&ge2;tail3'>\n"
"]>\n"
"<doc>&ge3;</doc>";
const XML_Char *const expected = XCS("head3") XCS("head2") XCS("head1")
XCS("Z") XCS("tail1") XCS("tail2") XCS("tail3");
CharData storage;
CharData_Init(&storage);
XML_Parser parser = XML_ParserCreate(NULL);
ParserPlusStorage parserPlusStorage = {parser, &storage};
XML_SetCharacterDataHandler(parser, accumulate_char_data_and_suspend);
XML_SetUserData(parser, &parserPlusStorage);
enum XML_Status status = XML_Parse(parser, text, (int)strlen(text), XML_TRUE);
while (status == XML_STATUS_SUSPENDED) {
status = XML_ResumeParser(parser);
}
if (status != XML_STATUS_OK)
xml_failure(parser);
CharData_CheckXMLChars(&storage, expected);
XML_ParserFree(parser);
}
END_TEST
/* Regression test for quadratic parsing on large tokens */
START_TEST(test_big_tokens_scale_linearly) {
const struct {
@ -6312,6 +6341,7 @@ make_basic_test_case(Suite *s) {
test_pool_integrity_with_unfinished_attr);
tcase_add_test__if_xml_ge(tc_basic, test_deep_nested_entity);
tcase_add_test__if_xml_ge(tc_basic, test_nested_entity_suspend);
tcase_add_test__if_xml_ge(tc_basic, test_nested_entity_suspend_2);
tcase_add_test(tc_basic, test_big_tokens_scale_linearly);
tcase_add_test(tc_basic, test_set_reparse_deferral);
tcase_add_test(tc_basic, test_reparse_deferral_is_inherited);

View file

@ -1891,6 +1891,20 @@ accumulate_entity_decl(void *userData, const XML_Char *entityName,
CharData_AppendXMLChars(storage, XCS("\n"), 1);
}
void XMLCALL
accumulate_char_data_and_suspend(void *userData, const XML_Char *s, int len) {
ParserPlusStorage *const parserPlusStorage = (ParserPlusStorage *)userData;
CharData_AppendXMLChars(parserPlusStorage->storage, s, len);
for (int i = 0; i < len; i++) {
if (s[i] == 'Z') {
XML_StopParser(parserPlusStorage->parser, /*resumable=*/XML_TRUE);
break;
}
}
}
void XMLCALL
accumulate_start_element(void *userData, const XML_Char *name,
const XML_Char **atts) {

View file

@ -574,6 +574,10 @@ extern void XMLCALL accumulate_entity_decl(
const XML_Char *systemId, const XML_Char *publicId,
const XML_Char *notationName);
extern void XMLCALL accumulate_char_data_and_suspend(void *userData,
const XML_Char *s,
int len);
extern void XMLCALL accumulate_start_element(void *userData,
const XML_Char *name,
const XML_Char **atts);