]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-140593: Fix a memory leak in function `my_ElementDeclHandler` of `pyexpat` (#140602)
authorSebastian Pipping <sebastian@pipping.org>
Sun, 26 Oct 2025 13:45:32 +0000 (14:45 +0100)
committerGitHub <noreply@github.com>
Sun, 26 Oct 2025 13:45:32 +0000 (13:45 +0000)
Ensure that the memory allocated for the content model
passed to `my_ElementDeclHandler` is freed in all error
paths.

Lib/test/test_pyexpat.py
Misc/NEWS.d/next/Library/2025-10-25-21-26-16.gh-issue-140593.OxlLc9.rst [new file with mode: 0644]
Modules/pyexpat.c

index b4ce72dfd5177421da854bb20b43db9e19f0e212..74a75458289b4dc37d02376049b6d291352bc79f 100644 (file)
@@ -684,6 +684,23 @@ class ChardataBufferTest(unittest.TestCase):
         parser.Parse(xml2, True)
         self.assertEqual(self.n, 4)
 
+class ElementDeclHandlerTest(unittest.TestCase):
+    def test_trigger_leak(self):
+        # Unfixed, this test would leak the memory of the so-called
+        # "content model" in function ``my_ElementDeclHandler`` of pyexpat.
+        # See https://github.com/python/cpython/issues/140593.
+        data = textwrap.dedent('''\
+            <!DOCTYPE quotations SYSTEM "quotations.dtd" [
+                <!ELEMENT root ANY>
+            ]>
+            <root/>
+        ''').encode('UTF-8')
+
+        parser = expat.ParserCreate()
+        parser.NotStandaloneHandler = lambda: 1.234  # arbitrary float
+        parser.ElementDeclHandler = lambda _1, _2: None
+        self.assertRaises(TypeError, parser.Parse, data, True)
+
 class MalformedInputTest(unittest.TestCase):
     def test1(self):
         xml = b"\0\r\n"
diff --git a/Misc/NEWS.d/next/Library/2025-10-25-21-26-16.gh-issue-140593.OxlLc9.rst b/Misc/NEWS.d/next/Library/2025-10-25-21-26-16.gh-issue-140593.OxlLc9.rst
new file mode 100644 (file)
index 0000000..612ad82
--- /dev/null
@@ -0,0 +1,3 @@
+:mod:`xml.parsers.expat`: Fix a memory leak that could affect users with
+:meth:`~xml.parsers.expat.xmlparser.ElementDeclHandler` set to a custom
+element declaration handler. Patch by Sebastian Pipping.
index 9c252be9cf22b2b0087e96632f8d4e24575a3626..e9255038eee5b5d72107fa580352a92decf368d1 100644 (file)
@@ -642,7 +642,7 @@ my_ElementDeclHandler(void *userData,
         PyObject *modelobj, *nameobj;
 
         if (PyErr_Occurred())
-            return;
+            goto finally;
 
         if (flush_character_buffer(self) < 0)
             goto finally;