]> granicus.if.org Git - libexpat/commitdiff
Test reallocation of attribute list with failing reallocator
authorRhodri James <rhodri@kynesim.co.uk>
Thu, 16 Feb 2017 18:28:37 +0000 (18:28 +0000)
committerSebastian Pipping <sebastian@pipping.org>
Sun, 16 Jul 2017 21:02:30 +0000 (23:02 +0200)
expat/tests/runtests.c

index 6c241c667a8762830042a018c9aee3e11790739b..22a962ce17431fa532855eb29ee9ad47fcf899a9 100644 (file)
@@ -5006,6 +5006,103 @@ START_TEST(test_alloc_realloc_buffer)
 }
 END_TEST
 
+/* Same test for external entity parsers */
+static int XMLCALL
+external_entity_reallocator(XML_Parser parser,
+                            const XML_Char *context,
+                            const XML_Char *UNUSED_P(base),
+                            const XML_Char *UNUSED_P(systemId),
+                            const XML_Char *UNUSED_P(publicId))
+{
+    const char *text = get_buffer_test_text;
+    XML_Parser ext_parser;
+    void *buffer;
+    enum XML_Status status;
+
+    ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
+    if (ext_parser == NULL)
+        fail("Could not create external entity parser");
+
+    reallocation_count = (intptr_t)XML_GetUserData(parser);
+    buffer = XML_GetBuffer(ext_parser, 1536);
+    if (buffer == NULL)
+        fail("Buffer allocation failed");
+    memcpy(buffer, text, strlen(text));
+    status = XML_ParseBuffer(ext_parser, strlen(text), XML_FALSE);
+    reallocation_count = -1;
+    XML_ParserFree(ext_parser);
+    return (status == XML_STATUS_OK) ? 1 : 0;
+}
+
+START_TEST(test_alloc_ext_entity_realloc_buffer)
+{
+    const char *text =
+        "<!DOCTYPE doc [\n"
+        "  <!ENTITY en SYSTEM 'http://xml.libexpat.org/dummy.ent'>\n"
+        "]>\n"
+        "<doc>&en;</doc>";
+    int i;
+
+    for (i = 0; i < 10; i++) {
+        XML_SetExternalEntityRefHandler(parser,
+                                        external_entity_reallocator);
+        XML_SetUserData(parser, (void *)(intptr_t)i);
+        if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
+                                    XML_TRUE) == XML_STATUS_OK)
+            break;
+        XML_ParserReset(parser, NULL);
+    }
+    if (i == 0)
+        fail("Succeeded with no reallocations");
+    if (i == 10)
+        fail("Failed with 10 reallocations");
+}
+END_TEST
+
+/* Test elements with many attributes are handled correctly */
+START_TEST(test_alloc_realloc_many_attributes)
+{
+    const char *text =
+        "<!DOCTYPE doc [\n"
+        "<!ATTLIST doc za CDATA 'default'>\n"
+        "<!ATTLIST doc zb CDATA 'def2'>\n"
+        "<!ATTLIST doc zc CDATA 'def3'>\n"
+        "]>\n"
+        "<doc a='1'"
+        "     b='2'"
+        "     c='3'"
+        "     d='4'"
+        "     e='5'"
+        "     f='6'"
+        "     g='7'"
+        "     h='8'"
+        "     i='9'"
+        "     j='10'"
+        "     k='11'"
+        "     l='12'"
+        "     m='13'"
+        "     n='14'"
+        "     p='15'>"
+        "</doc>";
+    int i;
+#define MAX_REALLOC_COUNT 10
+
+    for (i = 0; i < MAX_REALLOC_COUNT; i++) {
+        reallocation_count = i;
+        if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
+                                    XML_TRUE) != XML_STATUS_ERROR)
+            break;
+        XML_ParserReset(parser, NULL);
+    }
+    if (i == 0)
+        fail("Parse succeeded despite no reallocations");
+    if (i == MAX_REALLOC_COUNT)
+        fail("Parse failed at max reallocations");
+#undef MAX_REALLOC_COUNT
+}
+END_TEST
+
+
 static void
 nsalloc_setup(void)
 {
@@ -5746,6 +5843,8 @@ make_suite(void)
     tcase_add_test(tc_alloc, test_alloc_explicit_encoding);
     tcase_add_test(tc_alloc, test_alloc_set_base);
     tcase_add_test(tc_alloc, test_alloc_realloc_buffer);
+    tcase_add_test(tc_alloc, test_alloc_ext_entity_realloc_buffer);
+    tcase_add_test(tc_alloc, test_alloc_realloc_many_attributes);
 
     suite_add_tcase(s, tc_nsalloc);
     tcase_add_checked_fixture(tc_nsalloc, nsalloc_setup, nsalloc_teardown);