mirror of
https://github.com/python/cpython.git
synced 2026-05-06 04:37:33 -04:00
[3.13] gh-148735: Fix a UAF in Element.findtext() (GH-148738) (#148923)
(cherry picked from commit 0469e6d38d)
This commit is contained in:
@@ -3167,6 +3167,16 @@ class BadElementPathTest(ElementTestCase, unittest.TestCase):
|
||||
e.extend([ET.Element('bar')])
|
||||
e.findtext(cls(e, 'x'))
|
||||
|
||||
def test_findtext_with_mutating_non_none_text(self):
|
||||
for cls in [MutationDeleteElementPath, MutationClearElementPath]:
|
||||
with self.subTest(cls):
|
||||
e = ET.Element('foo')
|
||||
child = ET.Element('bar')
|
||||
child.text = str(object())
|
||||
e.append(child)
|
||||
del child
|
||||
repr(e.findtext(cls(e, 'x')))
|
||||
|
||||
def test_findtext_with_error(self):
|
||||
e = ET.Element('foo')
|
||||
e.extend([ET.Element('bar')])
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
:mod:`xml.etree.ElementTree`: Fix a use-after-free in
|
||||
:meth:`Element.findtext <xml.etree.ElementTree.Element.findtext>` when the
|
||||
element tree is mutated concurrently during the search.
|
||||
+9
-13
@@ -563,7 +563,7 @@ element_get_attrib(ElementObject* self)
|
||||
LOCAL(PyObject*)
|
||||
element_get_text(ElementObject* self)
|
||||
{
|
||||
/* return borrowed reference to text attribute */
|
||||
/* return new reference to text attribute */
|
||||
|
||||
PyObject *res = self->text;
|
||||
|
||||
@@ -578,13 +578,13 @@ element_get_text(ElementObject* self)
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
return Py_NewRef(res);
|
||||
}
|
||||
|
||||
LOCAL(PyObject*)
|
||||
element_get_tail(ElementObject* self)
|
||||
{
|
||||
/* return borrowed reference to text attribute */
|
||||
/* return new reference to tail attribute */
|
||||
|
||||
PyObject *res = self->tail;
|
||||
|
||||
@@ -599,7 +599,7 @@ element_get_tail(ElementObject* self)
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
return Py_NewRef(res);
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
@@ -1340,9 +1340,9 @@ _elementtree_Element_findtext_impl(ElementObject *self, PyTypeObject *cls,
|
||||
PyObject *text = element_get_text((ElementObject *)item);
|
||||
Py_DECREF(item);
|
||||
if (text == Py_None) {
|
||||
Py_DECREF(text);
|
||||
return Py_GetConstant(Py_CONSTANT_EMPTY_STR);
|
||||
}
|
||||
Py_XINCREF(text);
|
||||
return text;
|
||||
}
|
||||
Py_DECREF(item);
|
||||
@@ -2042,15 +2042,13 @@ element_tag_getter(ElementObject *self, void *closure)
|
||||
static PyObject*
|
||||
element_text_getter(ElementObject *self, void *closure)
|
||||
{
|
||||
PyObject *res = element_get_text(self);
|
||||
return Py_XNewRef(res);
|
||||
return element_get_text(self);
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
element_tail_getter(ElementObject *self, void *closure)
|
||||
{
|
||||
PyObject *res = element_get_tail(self);
|
||||
return Py_XNewRef(res);
|
||||
return element_get_tail(self);
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
@@ -2283,16 +2281,14 @@ elementiter_next(ElementIterObject *it)
|
||||
continue;
|
||||
|
||||
gettext:
|
||||
Py_DECREF(elem);
|
||||
if (!text) {
|
||||
Py_DECREF(elem);
|
||||
return NULL;
|
||||
}
|
||||
if (text == Py_None) {
|
||||
Py_DECREF(elem);
|
||||
Py_DECREF(text);
|
||||
}
|
||||
else {
|
||||
Py_INCREF(text);
|
||||
Py_DECREF(elem);
|
||||
rc = PyObject_IsTrue(text);
|
||||
if (rc > 0)
|
||||
return text;
|
||||
|
||||
Reference in New Issue
Block a user