]> granicus.if.org Git - libexpat/commitdiff
Test suspending from an external entity's XML declaration handler
authorRhodri James <rhodri@kynesim.co.uk>
Thu, 9 Feb 2017 16:55:35 +0000 (16:55 +0000)
committerSebastian Pipping <sebastian@pipping.org>
Sun, 16 Jul 2017 16:23:20 +0000 (18:23 +0200)
expat/tests/runtests.c

index 39e6c30525769bd960bcaaaf3c7d51852b19f4b8..869307b60a541dff8f1077211a9ae8c885437a8e 100644 (file)
@@ -2122,6 +2122,91 @@ START_TEST(test_subordinate_suspend)
 }
 END_TEST
 
+/* Test suspending a subordinate parser from an XML declaration */
+/* Increases code coverage of the tests */
+static void XMLCALL
+entity_suspending_xdecl_handler(void *userData,
+                                const XML_Char *UNUSED_P(version),
+                                const XML_Char *UNUSED_P(encoding),
+                                int UNUSED_P(standalone))
+{
+    XML_Parser ext_parser = (XML_Parser)userData;
+
+    XML_StopParser(ext_parser, resumable);
+    XML_SetXmlDeclHandler(ext_parser, NULL);
+}
+
+static int XMLCALL
+external_entity_suspend_xmldecl(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 = "<?xml version='1.0' encoding='us-ascii'?>";
+    XML_Parser ext_parser;
+    XML_ParsingStatus status;
+    enum XML_Status rc;
+
+    ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
+    if (ext_parser == NULL)
+        fail("Could not create external entity parser");
+    XML_SetXmlDeclHandler(ext_parser, entity_suspending_xdecl_handler);
+    XML_SetUserData(ext_parser, ext_parser);
+    rc = _XML_Parse_SINGLE_BYTES(ext_parser, text, strlen(text), XML_TRUE);
+    XML_GetParsingStatus(ext_parser, &status);
+    if (resumable) {
+        if (rc == XML_STATUS_ERROR)
+            xml_failure(ext_parser);
+        if (status.parsing != XML_SUSPENDED)
+            fail("Ext Parsing status not SUSPENDED");
+    } else {
+        if (rc != XML_STATUS_ERROR)
+            fail("Ext parsing not aborted");
+        if (XML_GetErrorCode(ext_parser) != XML_ERROR_ABORTED)
+            xml_failure(ext_parser);
+        if (status.parsing != XML_FINISHED)
+            fail("Ext Parsing status not FINISHED");
+    }
+    return XML_STATUS_OK;
+}
+
+START_TEST(test_subordinate_xdecl_suspend)
+{
+    const char *text =
+        "<!DOCTYPE doc [\n"
+        "  <!ENTITY entity SYSTEM 'http://xml.libexpat.org/dummy.ent'>\n"
+        "]>\n"
+        "<doc>&entity;</doc>";
+
+    XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
+    XML_SetExternalEntityRefHandler(parser,
+                                    external_entity_suspend_xmldecl);
+    resumable = XML_TRUE;
+    if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
+                                XML_TRUE) == XML_STATUS_ERROR)
+        xml_failure(parser);
+}
+END_TEST
+
+START_TEST(test_subordinate_xdecl_abort)
+{
+    const char *text =
+        "<!DOCTYPE doc [\n"
+        "  <!ENTITY entity SYSTEM 'http://xml.libexpat.org/dummy.ent'>\n"
+        "]>\n"
+        "<doc>&entity;</doc>";
+
+    XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
+    XML_SetExternalEntityRefHandler(parser,
+                                    external_entity_suspend_xmldecl);
+    resumable = XML_FALSE;
+    if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
+                                XML_TRUE) == XML_STATUS_ERROR)
+        xml_failure(parser);
+}
+END_TEST
+
 
 /* Test setting an explicit encoding */
 START_TEST(test_explicit_encoding)
@@ -3764,6 +3849,8 @@ make_suite(void)
     tcase_add_test(tc_basic, test_resume_resuspended);
     tcase_add_test(tc_basic, test_subordinate_reset);
     tcase_add_test(tc_basic, test_subordinate_suspend);
+    tcase_add_test(tc_basic, test_subordinate_xdecl_suspend);
+    tcase_add_test(tc_basic, test_subordinate_xdecl_abort);
     tcase_add_test(tc_basic, test_explicit_encoding);
     tcase_add_test(tc_basic, test_user_parameters);
     tcase_add_test(tc_basic, test_ext_entity_ref_parameter);