Skip to content

Commit 842c49b

Browse files
authored
[3.14] pythongh-140593: Fix a memory leak in function my_ElementDeclHandler of pyexpat (pythonGH-140602) (python#140629)
[3.14] pythongh-140593: Fix a memory leak in function `my_ElementDeclHandler` of `pyexpat` (pythonGH-140602) Ensure that the memory allocated for the content model passed to `my_ElementDeclHandler` is freed in all error paths. (cherry picked from commit e34a5e3)
1 parent 30ee67b commit 842c49b

File tree

3 files changed

+22
-1
lines changed

3 files changed

+22
-1
lines changed

Lib/test/test_pyexpat.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import os
55
import sys
66
import sysconfig
7+
import textwrap
78
import unittest
89
import traceback
910
from io import BytesIO
@@ -668,6 +669,23 @@ def test_change_size_2(self):
668669
parser.Parse(xml2, True)
669670
self.assertEqual(self.n, 4)
670671

672+
class ElementDeclHandlerTest(unittest.TestCase):
673+
def test_trigger_leak(self):
674+
# Unfixed, this test would leak the memory of the so-called
675+
# "content model" in function ``my_ElementDeclHandler`` of pyexpat.
676+
# See https://github.com/python/cpython/issues/140593.
677+
data = textwrap.dedent('''\
678+
<!DOCTYPE quotations SYSTEM "quotations.dtd" [
679+
<!ELEMENT root ANY>
680+
]>
681+
<root/>
682+
''').encode('UTF-8')
683+
684+
parser = expat.ParserCreate()
685+
parser.NotStandaloneHandler = lambda: 1.234 # arbitrary float
686+
parser.ElementDeclHandler = lambda _1, _2: None
687+
self.assertRaises(TypeError, parser.Parse, data, True)
688+
671689
class MalformedInputTest(unittest.TestCase):
672690
def test1(self):
673691
xml = b"\0\r\n"
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
:mod:`xml.parsers.expat`: Fix a memory leak that could affect users with
2+
:meth:`~xml.parsers.expat.xmlparser.ElementDeclHandler` set to a custom
3+
element declaration handler. Patch by Sebastian Pipping.

Modules/pyexpat.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,7 @@ my_ElementDeclHandler(void *userData,
597597
PyObject *modelobj, *nameobj;
598598

599599
if (PyErr_Occurred())
600-
return;
600+
goto finally;
601601

602602
if (flush_character_buffer(self) < 0)
603603
goto finally;

0 commit comments

Comments
 (0)