changeset: 101927:e3671a684ea0 parent: 101925:194549801bd5 parent: 101926:e44bd1259bda user: Serhiy Storchaka date: Sun Jun 12 09:47:20 2016 +0300 files: Lib/test/test_xml_etree.py Misc/NEWS Modules/_elementtree.c description: Issue #25455: Fixed a crash in repr of ElementTree.Element with recursive tag. diff -r 194549801bd5 -r e3671a684ea0 Lib/test/test_xml_etree.py --- a/Lib/test/test_xml_etree.py Sun Jun 12 09:35:13 2016 +0300 +++ b/Lib/test/test_xml_etree.py Sun Jun 12 09:47:20 2016 +0300 @@ -18,7 +18,7 @@ from itertools import product from test import support -from test.support import TESTFN, findfile, import_fresh_module, gc_collect +from test.support import TESTFN, findfile, import_fresh_module, gc_collect, swap_attr # pyET is the pure-Python implementation. # @@ -1864,6 +1864,12 @@ e.extend([ET.Element('bar')]) self.assertRaises(ValueError, e.remove, X('baz')) + def test_recursive_repr(self): + # Issue #25455 + e = ET.Element('foo') + with swap_attr(e, 'tag', e): + with self.assertRaises(RuntimeError): + repr(e) # Should not crash class MutatingElementPath(str): def __new__(cls, elem, *args): diff -r 194549801bd5 -r e3671a684ea0 Misc/NEWS --- a/Misc/NEWS Sun Jun 12 09:35:13 2016 +0300 +++ b/Misc/NEWS Sun Jun 12 09:47:20 2016 +0300 @@ -44,6 +44,8 @@ Library ------- +- Issue #25455: Fixed a crash in repr of ElementTree.Element with recursive tag. + - Issue #27294: Improved repr for Tkinter event objects. - Issue #20508: Improve exception message of IPv{4,6}Network.__getitem__. diff -r 194549801bd5 -r e3671a684ea0 Modules/_elementtree.c --- a/Modules/_elementtree.c Sun Jun 12 09:35:13 2016 +0300 +++ b/Modules/_elementtree.c Sun Jun 12 09:47:20 2016 +0300 @@ -1610,10 +1610,23 @@ static PyObject* element_repr(ElementObject* self) { - if (self->tag) - return PyUnicode_FromFormat("", self->tag, self); - else + int status; + + if (self->tag == NULL) return PyUnicode_FromFormat("", self); + + status = Py_ReprEnter((PyObject *)self); + if (status == 0) { + PyObject *res; + res = PyUnicode_FromFormat("", self->tag, self); + Py_ReprLeave((PyObject *)self); + return res; + } + if (status > 0) + PyErr_Format(PyExc_RuntimeError, + "reentrant call inside %s.__repr__", + Py_TYPE(self)->tp_name); + return NULL; } /*[clinic input]