Skip to content

Commit 18f018c

Browse files
Issue #28871: Fixed a crash when deallocate deep ElementTree.
1 parent fb2ae15 commit 18f018c

3 files changed

Lines changed: 14 additions & 0 deletions

File tree

Lib/test/test_xml_etree_c.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
fresh=['_elementtree', 'xml.etree'])
1212

1313

14+
@unittest.skipUnless(cET, 'requires _elementtree')
1415
class MiscTests(unittest.TestCase):
1516
# Issue #8651.
1617
@support.bigmemtest(size=support._2G + 100, memuse=1, dry_run=False)
@@ -54,6 +55,15 @@ def test_del_attribute(self):
5455
del element.attrib
5556
self.assertEqual(element.attrib, {'A': 'B', 'C': 'D'})
5657

58+
def test_trashcan(self):
59+
# If this test fails, it will most likely die via segfault.
60+
e = root = cET.Element('root')
61+
for i in range(200000):
62+
e = cET.SubElement(e, 'x')
63+
del e
64+
del root
65+
support.gc_collect()
66+
5767

5868
@unittest.skipUnless(cET, 'requires _elementtree')
5969
class TestAliasWorking(unittest.TestCase):

Misc/NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ Core and Builtins
138138
Library
139139
-------
140140

141+
- Issue #28871: Fixed a crash when deallocate deep ElementTree.
142+
141143
- Issue #19542: Fix bugs in WeakValueDictionary.setdefault() and
142144
WeakValueDictionary.pop() when a GC collection happens in another
143145
thread.

Modules/_elementtree.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,7 @@ static void
652652
element_dealloc(ElementObject* self)
653653
{
654654
PyObject_GC_UnTrack(self);
655+
Py_TRASHCAN_SAFE_BEGIN(self)
655656

656657
if (self->weakreflist != NULL)
657658
PyObject_ClearWeakRefs((PyObject *) self);
@@ -662,6 +663,7 @@ element_dealloc(ElementObject* self)
662663

663664
RELEASE(sizeof(ElementObject), "destroy element");
664665
Py_TYPE(self)->tp_free((PyObject *)self);
666+
Py_TRASHCAN_SAFE_END(self)
665667
}
666668

667669
/* -------------------------------------------------------------------- */

0 commit comments

Comments
 (0)