]> granicus.if.org Git - libexpat/commitdiff
SF bug #620343: segfault: bad API/callback interaction
authorFred L. Drake, Jr. <fdrake@users.sourceforge.net>
Tue, 8 Oct 2002 17:04:55 +0000 (17:04 +0000)
committerFred L. Drake, Jr. <fdrake@users.sourceforge.net>
Tue, 8 Oct 2002 17:04:55 +0000 (17:04 +0000)
The start-namespace-decl callback can set the start-element callback to
NULL, but Expat tried to call it anyway.

expat/lib/xmlparse.c
expat/tests/runtests.c

index 602108d3dbe53e8da81de96357bb8e257b7b2299..b834d1aef8a08ac60e18487b90dd17e49a3fa161 100644 (file)
@@ -2075,8 +2075,9 @@ doContent(XML_Parser parser,
           result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
           if (result)
             return result;
-          startElementHandler(handlerArg, tag->name.str,
-                              (const XML_Char **)atts);
+          if (startElementHandler)
+            startElementHandler(handlerArg, tag->name.str,
+                                (const XML_Char **)atts);
         }
         else if (defaultHandler)
           reportDefault(parser, enc, s, next);
index fcb7e6a7fd529c4bd61ab62a9a78a1b946456180..99a4bfb74758ba3f9e5eff601717d0299cc16fee 100644 (file)
@@ -790,6 +790,41 @@ START_TEST(test_ns_tagname_overwrite_triplet)
 }
 END_TEST
 
+
+/* Regression test for SF bug #620343. */
+static void
+start_element_fail(void *userData,
+                    const XML_Char *name, const XML_Char **atts)
+{
+    /* We should never get here. */
+    fail("should never reach start_element_fail()");
+}
+
+static void
+start_ns_clearing_start_element(void *userData,
+                                       const XML_Char *prefix,
+                                       const XML_Char *uri)
+{
+    XML_SetStartElementHandler((XML_Parser) userData, NULL);
+}
+
+START_TEST(test_start_ns_clears_start_element)
+{
+    /* This needs to use separate start/end tags; using the empty tag
+       syntax doesn't cause the problematic path through Expat to be
+       taken.
+    */
+    char *text = "<e xmlns='http://xml.libexpat.org/'></e>";
+
+    XML_SetStartElementHandler(parser, start_element_fail);
+    XML_SetStartNamespaceDeclHandler(parser, start_ns_clearing_start_element);
+    XML_UseParserAsHandlerArg(parser);
+    if (XML_Parse(parser, text, strlen(text), 1) == XML_STATUS_ERROR)
+        xml_failure(parser);
+}
+END_TEST
+
+
 static Suite *
 make_basic_suite(void)
 {
@@ -835,6 +870,7 @@ make_basic_suite(void)
     tcase_add_test(tc_namespace, test_return_ns_triplet);
     tcase_add_test(tc_namespace, test_ns_tagname_overwrite);
     tcase_add_test(tc_namespace, test_ns_tagname_overwrite_triplet);
+    tcase_add_test(tc_namespace, test_start_ns_clears_start_element);
 
     return s;
 }