Skip to content

Commit 9062c26

Browse files
Issue python#25455: Fixed a crash in repr of ElementTree.Element with recursive tag.
1 parent 3c317e7 commit 9062c26

3 files changed

Lines changed: 25 additions & 4 deletions

File tree

Lib/test/test_xml_etree.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
from itertools import product
2020
from test import support
21-
from test.support import TESTFN, findfile, import_fresh_module, gc_collect
21+
from test.support import TESTFN, findfile, import_fresh_module, gc_collect, swap_attr
2222

2323
# pyET is the pure-Python implementation.
2424
#
@@ -1860,6 +1860,12 @@ def __eq__(self, o):
18601860
e.extend([ET.Element('bar')])
18611861
self.assertRaises(ValueError, e.remove, X('baz'))
18621862

1863+
def test_recursive_repr(self):
1864+
# Issue #25455
1865+
e = ET.Element('foo')
1866+
with swap_attr(e, 'tag', e):
1867+
with self.assertRaises(RuntimeError):
1868+
repr(e) # Should not crash
18631869

18641870
class MutatingElementPath(str):
18651871
def __new__(cls, elem, *args):

Misc/NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,8 @@ Core and Builtins
143143
Library
144144
-------
145145

146+
- Issue #25455: Fixed a crash in repr of ElementTree.Element with recursive tag.
147+
146148
- Issue #26556: Update expat to 2.1.1, fixes CVE-2015-1283.
147149

148150
- Fix TLS stripping vulnerability in smptlib, CVE-2016-0772. Reported by Team

Modules/_elementtree.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1582,10 +1582,23 @@ _elementtree_Element_remove_impl(ElementObject *self, PyObject *subelement)
15821582
static PyObject*
15831583
element_repr(ElementObject* self)
15841584
{
1585-
if (self->tag)
1586-
return PyUnicode_FromFormat("<Element %R at %p>", self->tag, self);
1587-
else
1585+
int status;
1586+
1587+
if (self->tag == NULL)
15881588
return PyUnicode_FromFormat("<Element at %p>", self);
1589+
1590+
status = Py_ReprEnter((PyObject *)self);
1591+
if (status == 0) {
1592+
PyObject *res;
1593+
res = PyUnicode_FromFormat("<Element %R at %p>", self->tag, self);
1594+
Py_ReprLeave((PyObject *)self);
1595+
return res;
1596+
}
1597+
if (status > 0)
1598+
PyErr_Format(PyExc_RuntimeError,
1599+
"reentrant call inside %s.__repr__",
1600+
Py_TYPE(self)->tp_name);
1601+
return NULL;
15891602
}
15901603

15911604
/*[clinic input]

0 commit comments

Comments
 (0)