]> granicus.if.org Git - libexpat/commitdiff
Test appropriately long context URI with a failing reallocator
authorRhodri James <rhodri@kynesim.co.uk>
Fri, 28 Apr 2017 16:27:45 +0000 (17:27 +0100)
committerSebastian Pipping <sebastian@pipping.org>
Sat, 22 Jul 2017 20:49:15 +0000 (22:49 +0200)
expat/tests/runtests.c

index 1a4e493cfea109d9c80d3aec30b8a8b77c5ae07c..dd04267ea680eade97aefceab06052949a55b818 100644 (file)
@@ -9039,6 +9039,93 @@ START_TEST(test_nsalloc_less_long_namespace)
 #undef MAX_ALLOC_COUNT
 END_TEST
 
+typedef struct ExtOption {
+    const char *system_id;
+    const char *parse_text;
+} ExtOption;
+
+static int XMLCALL
+external_entity_optioner(XML_Parser parser,
+                         const XML_Char *context,
+                         const XML_Char *UNUSED_P(base),
+                         const XML_Char *systemId,
+                         const XML_Char *UNUSED_P(publicId))
+{
+    ExtOption *options = (ExtOption *)XML_GetUserData(parser);
+    XML_Parser ext_parser;
+
+    while (options->parse_text != NULL) {
+        if (!strcmp(systemId, options->system_id)) {
+            ext_parser =
+                XML_ExternalEntityParserCreate(parser, context, NULL);
+            if (ext_parser == NULL)
+                return XML_STATUS_ERROR;
+            if (_XML_Parse_SINGLE_BYTES(ext_parser, options->parse_text,
+                                        strlen(options->parse_text),
+                                        XML_TRUE) == XML_STATUS_ERROR)
+                return XML_STATUS_ERROR;
+            XML_ParserFree(ext_parser);
+            return XML_STATUS_OK;
+        }
+        options++;
+    }
+    fail("No suitable option found");
+    return XML_STATUS_ERROR;
+}
+
+START_TEST(test_nsalloc_realloc_long_context)
+{
+    const char *text =
+        "<!DOCTYPE doc SYSTEM 'foo' [\n"
+        "  <!ENTITY en SYSTEM 'bar'>\n"
+        "]>\n"
+        "<doc xmlns='http://example.org/"
+        /* 64 characters per line */
+        "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
+        "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
+        "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
+        "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
+        "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
+        "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
+        "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
+        "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
+        "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
+        "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
+        "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
+        "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
+        "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
+        "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
+        "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
+        "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKL"
+        "'>\n"
+        "&en;"
+        "</doc>";
+    ExtOption options[] = {
+        { "foo", "<!ELEMENT e EMPTY>"},
+        { "bar", "<e/>" },
+        { NULL, NULL }
+    };
+    int i;
+#define MAX_REALLOC_COUNT 5
+
+    for (i = 0; i < MAX_REALLOC_COUNT; i++) {
+        reallocation_count = i;
+        XML_SetUserData(parser, options);
+        XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
+        XML_SetExternalEntityRefHandler(parser, external_entity_optioner);
+        if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
+                                    XML_TRUE) != XML_STATUS_ERROR)
+            break;
+        XML_ParserReset(parser, NULL);
+    }
+    if (i == 0)
+        fail("Parsing worked despite failing reallocations");
+    else if (i == MAX_REALLOC_COUNT)
+        fail("Parsing failed even at max reallocation count");
+}
+#undef MAX_REALLOC_COUNT
+END_TEST
+
 
 static Suite *
 make_suite(void)
@@ -9293,6 +9380,7 @@ make_suite(void)
     tcase_add_test(tc_nsalloc, test_nsalloc_realloc_longer_prefix);
     tcase_add_test(tc_nsalloc, test_nsalloc_long_namespace);
     tcase_add_test(tc_nsalloc, test_nsalloc_less_long_namespace);
+    tcase_add_test(tc_nsalloc, test_nsalloc_realloc_long_context);
 
     return s;
 }