]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Issue #25455: Fixed a crash in repr of ElementTree.Element with recursive tag.
authorSerhiy Storchaka <storchaka@gmail.com>
Sun, 12 Jun 2016 06:43:55 +0000 (09:43 +0300)
committerSerhiy Storchaka <storchaka@gmail.com>
Sun, 12 Jun 2016 06:43:55 +0000 (09:43 +0300)
Lib/test/test_xml_etree.py
Misc/NEWS
Modules/_elementtree.c

index 44e3142dc91f856a901fcc099335cced2bd501ed..bc1dd1461bea37f4b8b04e62b7d6ec86d572df37 100644 (file)
@@ -18,7 +18,7 @@ import weakref
 
 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.
 #
@@ -1860,6 +1860,12 @@ class BadElementTest(ElementTestCase, unittest.TestCase):
         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):
index 9d826265387f0537f86a2c17ba6c471c078f0dee..19cb832f4b2faf571e152ddf3df384b653580607 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -143,6 +143,8 @@ Core and Builtins
 Library
 -------
 
+- Issue #25455: Fixed a crash in repr of ElementTree.Element with recursive tag.
+
 - Issue #26556: Update expat to 2.1.1, fixes CVE-2015-1283.
 
 - Fix TLS stripping vulnerability in smptlib, CVE-2016-0772.  Reported by Team
index 0f1d6a1faa40c89e607c5c3dac0b44158677f0f0..85ffca206bab2d60a6ec80727fd73dd12f8fac4a 100644 (file)
@@ -1582,10 +1582,23 @@ _elementtree_Element_remove_impl(ElementObject *self, PyObject *subelement)
 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]