diff --git a/expat/tests/basic_tests.c b/expat/tests/basic_tests.c index e52e0c42..3ec51b07 100644 --- a/expat/tests/basic_tests.c +++ b/expat/tests/basic_tests.c @@ -1202,6 +1202,79 @@ START_TEST(test_wfc_no_recursive_entity_refs) { } END_TEST +START_TEST(test_no_indirectly_recursive_entity_refs) { + struct TestCase { + const char *doc; + bool usesParameterEntities; + }; + + const struct TestCase cases[] = { + // general entity + character data + {"\n" + " \n" + "]>&e2;\n", + false}, + + // general entity + attribute value + {"\n" + " \n" + "]>\n", + false}, + + // parameter entity + {"\n" + " \n" + " \">\n" + " %define_g;\n" + "]>\n" + "\n", + true}, + }; + for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) { + const char *const doc = cases[i].doc; + const bool usesParameterEntities = cases[i].usesParameterEntities; + + set_subtest("[%i] %s", (int)i, doc); + +#ifdef XML_DTD // both GE and DTD + const bool rejection_expected = true; +#elif XML_GE == 1 // GE but not DTD + const bool rejection_expected = ! usesParameterEntities; +#else // neither DTD nor GE + const bool rejection_expected = false; +#endif + + XML_Parser parser = XML_ParserCreate(NULL); + +#ifdef XML_DTD + if (usesParameterEntities) { + assert_true( + XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS) + == 1); + } +#else + UNUSED_P(usesParameterEntities); +#endif // XML_DTD + + const enum XML_Status status + = _XML_Parse_SINGLE_BYTES(parser, doc, (int)strlen(doc), + /*isFinal*/ XML_TRUE); + + if (rejection_expected) { + assert_true(status == XML_STATUS_ERROR); + assert_true(XML_GetErrorCode(parser) == XML_ERROR_RECURSIVE_ENTITY_REF); + } else { + assert_true(status == XML_STATUS_OK); + } + + XML_ParserFree(parser); + } +} +END_TEST + START_TEST(test_recursive_external_parameter_entity_2) { struct TestCase { const char *doc; @@ -5996,6 +6069,7 @@ make_basic_test_case(Suite *s) { tcase_add_test(tc_basic, test_not_standalone_handler_reject); tcase_add_test(tc_basic, test_not_standalone_handler_accept); tcase_add_test__if_xml_ge(tc_basic, test_wfc_no_recursive_entity_refs); + tcase_add_test(tc_basic, test_no_indirectly_recursive_entity_refs); tcase_add_test__ifdef_xml_dtd(tc_basic, test_ext_entity_invalid_parse); tcase_add_test__if_xml_ge(tc_basic, test_dtd_default_handling); tcase_add_test(tc_basic, test_dtd_attr_handling);