[Python-checkins] cpython (merge 3.5 -> default): Issue #25455: Fixed a crash in repr of ElementTree.Element with recursive tag.

serhiy.storchaka python-checkins at python.org
Sun Jun 12 02:49:47 EDT 2016


https://hg.python.org/cpython/rev/e3671a684ea0
changeset:   101927:e3671a684ea0
parent:      101925:194549801bd5
parent:      101926:e44bd1259bda
user:        Serhiy Storchaka <storchaka at gmail.com>
date:        Sun Jun 12 09:47:20 2016 +0300
summary:
  Issue #25455: Fixed a crash in repr of ElementTree.Element with recursive tag.

files:
  Lib/test/test_xml_etree.py |   8 +++++++-
  Misc/NEWS                  |   2 ++
  Modules/_elementtree.c     |  19 ++++++++++++++++---
  3 files changed, 25 insertions(+), 4 deletions(-)


diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py
--- a/Lib/test/test_xml_etree.py
+++ b/Lib/test/test_xml_etree.py
@@ -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 --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -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 --git a/Modules/_elementtree.c b/Modules/_elementtree.c
--- a/Modules/_elementtree.c
+++ b/Modules/_elementtree.c
@@ -1610,10 +1610,23 @@
 static PyObject*
 element_repr(ElementObject* self)
 {
-    if (self->tag)
-        return PyUnicode_FromFormat("<Element %R at %p>", self->tag, self);
-    else
+    int status;
+
+    if (self->tag == NULL)
         return PyUnicode_FromFormat("<Element at %p>", self);
+
+    status = Py_ReprEnter((PyObject *)self);
+    if (status == 0) {
+        PyObject *res;
+        res = PyUnicode_FromFormat("<Element %R at %p>", 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]

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list