Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0469e6d

Browse files
gh-148735: Fix a UAF in Element.findtext() (#148738)
1 parent 158dbbb commit 0469e6d

3 files changed

Lines changed: 22 additions & 13 deletions

File tree

Lib/test/test_xml_etree.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3271,6 +3271,16 @@ def test_findtext_with_mutating(self):
32713271
e.extend([ET.Element('bar')])
32723272
e.findtext(cls(e, 'x'))
32733273

3274+
def test_findtext_with_mutating_non_none_text(self):
3275+
for cls in [MutationDeleteElementPath, MutationClearElementPath]:
3276+
with self.subTest(cls):
3277+
e = ET.Element('foo')
3278+
child = ET.Element('bar')
3279+
child.text = str(object())
3280+
e.append(child)
3281+
del child
3282+
repr(e.findtext(cls(e, 'x')))
3283+
32743284
def test_findtext_with_error(self):
32753285
e = ET.Element('foo')
32763286
e.extend([ET.Element('bar')])
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
:mod:`xml.etree.ElementTree`: Fix a use-after-free in
2+
:meth:`Element.findtext <xml.etree.ElementTree.Element.findtext>` when the
3+
element tree is mutated concurrently during the search.

Modules/_elementtree.c

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,7 @@ element_get_attrib(ElementObject* self)
573573
LOCAL(PyObject*)
574574
element_get_text(ElementObject* self)
575575
{
576-
/* return borrowed reference to text attribute */
576+
/* return new reference to text attribute */
577577

578578
PyObject *res = self->text;
579579

@@ -588,13 +588,13 @@ element_get_text(ElementObject* self)
588588
}
589589
}
590590

591-
return res;
591+
return Py_NewRef(res);
592592
}
593593

594594
LOCAL(PyObject*)
595595
element_get_tail(ElementObject* self)
596596
{
597-
/* return borrowed reference to text attribute */
597+
/* return new reference to tail attribute */
598598

599599
PyObject *res = self->tail;
600600

@@ -609,7 +609,7 @@ element_get_tail(ElementObject* self)
609609
}
610610
}
611611

612-
return res;
612+
return Py_NewRef(res);
613613
}
614614

615615
static PyObject*
@@ -1359,9 +1359,9 @@ _elementtree_Element_findtext_impl(ElementObject *self, PyTypeObject *cls,
13591359
PyObject *text = element_get_text((ElementObject *)item);
13601360
Py_DECREF(item);
13611361
if (text == Py_None) {
1362+
Py_DECREF(text);
13621363
return Py_GetConstant(Py_CONSTANT_EMPTY_STR);
13631364
}
1364-
Py_XINCREF(text);
13651365
return text;
13661366
}
13671367
Py_DECREF(item);
@@ -2064,16 +2064,14 @@ static PyObject*
20642064
element_text_getter(PyObject *op, void *closure)
20652065
{
20662066
ElementObject *self = _Element_CAST(op);
2067-
PyObject *res = element_get_text(self);
2068-
return Py_XNewRef(res);
2067+
return element_get_text(self);
20692068
}
20702069

20712070
static PyObject*
20722071
element_tail_getter(PyObject *op, void *closure)
20732072
{
20742073
ElementObject *self = _Element_CAST(op);
2075-
PyObject *res = element_get_tail(self);
2076-
return Py_XNewRef(res);
2074+
return element_get_tail(self);
20772075
}
20782076

20792077
static PyObject*
@@ -2316,16 +2314,14 @@ elementiter_next(PyObject *op)
23162314
continue;
23172315

23182316
gettext:
2317+
Py_DECREF(elem);
23192318
if (!text) {
2320-
Py_DECREF(elem);
23212319
return NULL;
23222320
}
23232321
if (text == Py_None) {
2324-
Py_DECREF(elem);
2322+
Py_DECREF(text);
23252323
}
23262324
else {
2327-
Py_INCREF(text);
2328-
Py_DECREF(elem);
23292325
rc = PyObject_IsTrue(text);
23302326
if (rc > 0)
23312327
return text;

0 commit comments

Comments
 (0)