diff --git a/expat/lib/xmlparse.c b/expat/lib/xmlparse.c index bbe3d9a6..256b4878 100644 --- a/expat/lib/xmlparse.c +++ b/expat/lib/xmlparse.c @@ -5853,7 +5853,7 @@ processInternalEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl) { if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) { entity->processed = (int)(next - textStart); parser->m_processor = internalEntityProcessor; - } else { + } else if (parser->m_openInternalEntities->entity == entity) { #if XML_GE == 1 entityTrackingOnClose(parser, entity, __LINE__); #endif /* XML_GE == 1 */ diff --git a/expat/tests/misc_tests.c b/expat/tests/misc_tests.c index 377bc7ae..89caf0da 100644 --- a/expat/tests/misc_tests.c +++ b/expat/tests/misc_tests.c @@ -474,6 +474,28 @@ START_TEST(test_misc_general_entities_support) { } END_TEST +static void XMLCALL +resumable_stopping_character_handler(void *userData, const XML_Char *s, + int len) { + UNUSED_P(s); + UNUSED_P(len); + XML_Parser parser = (XML_Parser)userData; + XML_StopParser(parser, XML_TRUE); +} + +// NOTE: This test needs active LeakSanitizer to be of actual use +START_TEST(test_misc_char_handler_stop_without_leak) { + const char *const data + = "]>&e2;"; + XML_Parser parser = XML_ParserCreate(NULL); + assert_true(parser != NULL); + XML_SetUserData(parser, parser); + XML_SetCharacterDataHandler(parser, resumable_stopping_character_handler); + _XML_Parse_SINGLE_BYTES(parser, data, (int)strlen(data), XML_FALSE); + XML_ParserFree(parser); +} +END_TEST + void make_miscellaneous_test_case(Suite *s) { TCase *tc_misc = tcase_create("miscellaneous tests"); @@ -497,4 +519,5 @@ make_miscellaneous_test_case(Suite *s) { tcase_add_test(tc_misc, test_misc_create_external_entity_parser_with_null_context); tcase_add_test(tc_misc, test_misc_general_entities_support); + tcase_add_test(tc_misc, test_misc_char_handler_stop_without_leak); }