]> granicus.if.org Git - python/commitdiff
Issue #16012: Fix a regression in pyexpat. The parser's UseForeignDTD()
authorChristian Heimes <christian@cheimes.de>
Mon, 24 Sep 2012 11:17:08 +0000 (13:17 +0200)
committerChristian Heimes <christian@cheimes.de>
Mon, 24 Sep 2012 11:17:08 +0000 (13:17 +0200)
method doesn't require an argument again.

Lib/test/test_pyexpat.py
Misc/NEWS
Modules/pyexpat.c

index 75b031ac17842a39c982788bcd20e86f2e698bb8..b911a2058cc3db31a4bdfb4de82111208b8d0119 100644 (file)
@@ -588,6 +588,58 @@ class MalformedInputText(unittest.TestCase):
         except expat.ExpatError as e:
             self.assertEqual(str(e), 'XML declaration not well-formed: line 1, column 14')
 
+class ForeignDTDTests(unittest.TestCase):
+    """
+    Tests for the UseForeignDTD method of expat parser objects.
+    """
+    def test_use_foreign_dtd(self):
+        """
+        If UseForeignDTD is passed True and a document without an external
+        entity reference is parsed, ExternalEntityRefHandler is first called
+        with None for the public and system ids.
+        """
+        handler_call_args = []
+        def resolve_entity(context, base, system_id, public_id):
+            handler_call_args.append((public_id, system_id))
+            return 1
+
+        parser = expat.ParserCreate()
+        parser.UseForeignDTD(True)
+        parser.SetParamEntityParsing(expat.XML_PARAM_ENTITY_PARSING_ALWAYS)
+        parser.ExternalEntityRefHandler = resolve_entity
+        parser.Parse("<?xml version='1.0'?><element/>")
+        self.assertEqual(handler_call_args, [(None, None)])
+
+        # test UseForeignDTD() is equal to UseForeignDTD(True)
+        handler_call_args[:] = []
+
+        parser = expat.ParserCreate()
+        parser.UseForeignDTD()
+        parser.SetParamEntityParsing(expat.XML_PARAM_ENTITY_PARSING_ALWAYS)
+        parser.ExternalEntityRefHandler = resolve_entity
+        parser.Parse("<?xml version='1.0'?><element/>")
+        self.assertEqual(handler_call_args, [(None, None)])
+
+    def test_ignore_use_foreign_dtd(self):
+        """
+        If UseForeignDTD is passed True and a document with an external
+        entity reference is parsed, ExternalEntityRefHandler is called with
+        the public and system ids from the document.
+        """
+        handler_call_args = []
+        def resolve_entity(context, base, system_id, public_id):
+            handler_call_args.append((public_id, system_id))
+            return 1
+
+        parser = expat.ParserCreate()
+        parser.UseForeignDTD(True)
+        parser.SetParamEntityParsing(expat.XML_PARAM_ENTITY_PARSING_ALWAYS)
+        parser.ExternalEntityRefHandler = resolve_entity
+        parser.Parse(
+            "<?xml version='1.0'?><!DOCTYPE foo PUBLIC 'bar' 'baz'><element/>")
+        self.assertEqual(handler_call_args, [("bar", "baz")])
+
+
 def test_main():
     run_unittest(SetAttributeTest,
                  ParseTest,
@@ -598,7 +650,8 @@ def test_main():
                  PositionTest,
                  sf1296433Test,
                  ChardataBufferTest,
-                 MalformedInputText)
+                 MalformedInputText,
+                 ForeignDTDTests)
 
 if __name__ == "__main__":
     test_main()
index 84d4bd1910cca5301dfb274c02b9590dbf48c4e5..bbdd5e543382864079a1a49319be5e2cc0fb406e 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -379,6 +379,12 @@ Library
 - Issue #6884: Fix long-standing bugs with MANIFEST.in parsing in distutils
   on Windows.
 
+Extension Modules
+-----------------
+
+- Issue #16012: Fix a regression in pyexpat. The parser's UseForeignDTD()
+  method doesn't require an argument again.
+
 Tests
 -----
 
index 4d9a1e598490604d2b76af648f27656877e32bcd..f2691136ca83b8dcd2f03e14f01f9efe66843bb1 100644 (file)
@@ -1176,7 +1176,7 @@ xmlparse_UseForeignDTD(xmlparseobject *self, PyObject *args)
     PyObject *flagobj = NULL;
     int flag = 1;
     enum XML_Error rc;
-    if (!PyArg_ParseTuple(args, "O:UseForeignDTD", &flagobj))
+    if (!PyArg_ParseTuple(args, "|O:UseForeignDTD", &flagobj))
         return NULL;
     if (flagobj != NULL) {
         flag = PyObject_IsTrue(flagobj);