mirror of
https://github.com/python/cpython.git
synced 2025-09-10 02:36:56 +00:00
bpo-27946: Fix possible crash in ElementTree.Element (GH-29915)
Getting an attribute via attrib.get() simultaneously with replacing the attrib dict can lead to access to deallocated dict.
This commit is contained in:
parent
f42a06ba27
commit
d15cdb2f32
3 changed files with 25 additions and 13 deletions
|
@ -169,6 +169,18 @@ class MiscTests(unittest.TestCase):
|
||||||
del parser
|
del parser
|
||||||
support.gc_collect()
|
support.gc_collect()
|
||||||
|
|
||||||
|
def test_dict_disappearing_during_get_item(self):
|
||||||
|
# test fix for seg fault reported in issue 27946
|
||||||
|
class X:
|
||||||
|
def __hash__(self):
|
||||||
|
e.attrib = {} # this frees e->extra->attrib
|
||||||
|
[{i: i} for i in range(1000)] # exhaust the dict keys cache
|
||||||
|
return 13
|
||||||
|
|
||||||
|
e = cET.Element("elem", {1: 2})
|
||||||
|
r = e.get(X())
|
||||||
|
self.assertIsNone(r)
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(cET, 'requires _elementtree')
|
@unittest.skipUnless(cET, 'requires _elementtree')
|
||||||
class TestAliasWorking(unittest.TestCase):
|
class TestAliasWorking(unittest.TestCase):
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
Fix possible crash when getting an attribute of
|
||||||
|
class:`xml.etree.ElementTree.Element` simultaneously with
|
||||||
|
replacing the ``attrib`` dict.
|
|
@ -1393,22 +1393,19 @@ _elementtree_Element_get_impl(ElementObject *self, PyObject *key,
|
||||||
PyObject *default_value)
|
PyObject *default_value)
|
||||||
/*[clinic end generated code: output=523c614142595d75 input=ee153bbf8cdb246e]*/
|
/*[clinic end generated code: output=523c614142595d75 input=ee153bbf8cdb246e]*/
|
||||||
{
|
{
|
||||||
PyObject* value;
|
if (self->extra && self->extra->attrib) {
|
||||||
|
PyObject *attrib = self->extra->attrib;
|
||||||
if (!self->extra || !self->extra->attrib)
|
Py_INCREF(attrib);
|
||||||
value = default_value;
|
PyObject *value = PyDict_GetItemWithError(attrib, key);
|
||||||
else {
|
Py_XINCREF(value);
|
||||||
value = PyDict_GetItemWithError(self->extra->attrib, key);
|
Py_DECREF(attrib);
|
||||||
if (!value) {
|
if (value != NULL || PyErr_Occurred()) {
|
||||||
if (PyErr_Occurred()) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
value = default_value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Py_INCREF(value);
|
|
||||||
return value;
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Py_INCREF(default_value);
|
||||||
|
return default_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue