diff --git a/expat/tests/alloc_tests.c b/expat/tests/alloc_tests.c index ed87dad2..36c4f91d 100644 --- a/expat/tests/alloc_tests.c +++ b/expat/tests/alloc_tests.c @@ -284,6 +284,53 @@ START_TEST(test_alloc_parse_comment_2) { } END_TEST +/* Test that external parser creation running out of memory is + * correctly reported. Based on the external entity test cases. + */ +START_TEST(test_alloc_create_external_parser) { + const char *text = "\n" + "\n" + "&entity;"; + char foo_text[] = ""; + + XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS); + XML_SetUserData(g_parser, foo_text); + XML_SetExternalEntityRefHandler(g_parser, external_entity_duff_loader); + if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) + != XML_STATUS_ERROR) { + fail("External parser allocator returned success incorrectly"); + } +} +END_TEST + +/* More external parser memory allocation testing */ +START_TEST(test_alloc_run_external_parser) { + const char *text = "\n" + "\n" + "&entity;"; + char foo_text[] = ""; + unsigned int i; + const unsigned int max_alloc_count = 15; + + for (i = 0; i < max_alloc_count; i++) { + XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS); + XML_SetUserData(g_parser, foo_text); + XML_SetExternalEntityRefHandler(g_parser, external_entity_null_loader); + g_allocation_count = i; + if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) + != XML_STATUS_ERROR) + break; + /* See comment in test_alloc_parse_xdecl() */ + alloc_teardown(); + alloc_setup(); + } + if (i == 0) + fail("Parsing ignored failing allocator"); + else if (i == max_alloc_count) + fail("Parsing failed with allocation count 10"); +} +END_TEST + TCase * make_alloc_test_case(Suite *s) { TCase *tc_alloc = tcase_create("allocation tests"); @@ -298,6 +345,8 @@ make_alloc_test_case(Suite *s) { tcase_add_test(tc_alloc, test_alloc_parse_pi_3); tcase_add_test(tc_alloc, test_alloc_parse_comment); tcase_add_test(tc_alloc, test_alloc_parse_comment_2); + tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_create_external_parser); + tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_run_external_parser); return tc_alloc; /* TEMPORARY: this will become a void function */ } diff --git a/expat/tests/handlers.c b/expat/tests/handlers.c index 43b2ac08..bebda6e4 100644 --- a/expat/tests/handlers.c +++ b/expat/tests/handlers.c @@ -1248,6 +1248,38 @@ external_entity_handler(XML_Parser parser, const XML_Char *context, return XML_STATUS_OK; } +int XMLCALL +external_entity_duff_loader(XML_Parser parser, const XML_Char *context, + const XML_Char *base, const XML_Char *systemId, + const XML_Char *publicId) { + XML_Parser new_parser; + unsigned int i; + const unsigned int max_alloc_count = 10; + + UNUSED_P(base); + UNUSED_P(systemId); + UNUSED_P(publicId); + /* Try a few different allocation levels */ + for (i = 0; i < max_alloc_count; i++) { + g_allocation_count = i; + new_parser = XML_ExternalEntityParserCreate(parser, context, NULL); + if (new_parser != NULL) { + XML_ParserFree(new_parser); + break; + } + } + if (i == 0) + fail("External parser creation ignored failing allocator"); + else if (i == max_alloc_count) + fail("Extern parser not created with max allocation count"); + + /* Make sure other random allocation doesn't now fail */ + g_allocation_count = ALLOC_ALWAYS_SUCCEED; + + /* Make sure the failure code path is executed too */ + return XML_STATUS_ERROR; +} + /* NotStandalone handlers */ int XMLCALL diff --git a/expat/tests/handlers.h b/expat/tests/handlers.h index f87fa503..e72e8779 100644 --- a/expat/tests/handlers.h +++ b/expat/tests/handlers.h @@ -364,6 +364,12 @@ extern int XMLCALL external_entity_handler(XML_Parser parser, const XML_Char *systemId, const XML_Char *publicId); +extern int XMLCALL external_entity_duff_loader(XML_Parser parser, + const XML_Char *context, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId); + /* NotStandalone handlers */ extern int XMLCALL reject_not_standalone_handler(void *userData); diff --git a/expat/tests/runtests.c b/expat/tests/runtests.c index a6f8fb5b..4bae79ed 100644 --- a/expat/tests/runtests.c +++ b/expat/tests/runtests.c @@ -76,85 +76,6 @@ XML_Parser g_parser = NULL; -static int XMLCALL -external_entity_duff_loader(XML_Parser parser, const XML_Char *context, - const XML_Char *base, const XML_Char *systemId, - const XML_Char *publicId) { - XML_Parser new_parser; - unsigned int i; - const unsigned int max_alloc_count = 10; - - UNUSED_P(base); - UNUSED_P(systemId); - UNUSED_P(publicId); - /* Try a few different allocation levels */ - for (i = 0; i < max_alloc_count; i++) { - g_allocation_count = i; - new_parser = XML_ExternalEntityParserCreate(parser, context, NULL); - if (new_parser != NULL) { - XML_ParserFree(new_parser); - break; - } - } - if (i == 0) - fail("External parser creation ignored failing allocator"); - else if (i == max_alloc_count) - fail("Extern parser not created with max allocation count"); - - /* Make sure other random allocation doesn't now fail */ - g_allocation_count = ALLOC_ALWAYS_SUCCEED; - - /* Make sure the failure code path is executed too */ - return XML_STATUS_ERROR; -} - -/* Test that external parser creation running out of memory is - * correctly reported. Based on the external entity test cases. - */ -START_TEST(test_alloc_create_external_parser) { - const char *text = "\n" - "\n" - "&entity;"; - char foo_text[] = ""; - - XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS); - XML_SetUserData(g_parser, foo_text); - XML_SetExternalEntityRefHandler(g_parser, external_entity_duff_loader); - if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) - != XML_STATUS_ERROR) { - fail("External parser allocator returned success incorrectly"); - } -} -END_TEST - -/* More external parser memory allocation testing */ -START_TEST(test_alloc_run_external_parser) { - const char *text = "\n" - "\n" - "&entity;"; - char foo_text[] = ""; - unsigned int i; - const unsigned int max_alloc_count = 15; - - for (i = 0; i < max_alloc_count; i++) { - XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS); - XML_SetUserData(g_parser, foo_text); - XML_SetExternalEntityRefHandler(g_parser, external_entity_null_loader); - g_allocation_count = i; - if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) - != XML_STATUS_ERROR) - break; - /* See comment in test_alloc_parse_xdecl() */ - alloc_teardown(); - alloc_setup(); - } - if (i == 0) - fail("Parsing ignored failing allocator"); - else if (i == max_alloc_count) - fail("Parsing failed with allocation count 10"); -} -END_TEST - static int XMLCALL external_entity_dbl_handler(XML_Parser parser, const XML_Char *context, const XML_Char *base, const XML_Char *systemId, @@ -3925,8 +3846,6 @@ make_suite(void) { TCase *tc_accounting = tcase_create("accounting tests"); #endif - tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_create_external_parser); - tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_run_external_parser); tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_dtd_copy_default_atts); tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_external_entity); tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_ext_entity_set_encoding);