mirror of https://github.com/python/cpython
Issue #25449: Fixed a crash and leaking NULL in repr() of OrderedDict that
was mutated by direct calls of dict methods.
This commit is contained in:
parent
b45b7b2137
commit
710cd34bdb
|
@ -2145,6 +2145,60 @@ class OrderedDictTests:
|
||||||
key = c0 + c1
|
key = c0 + c1
|
||||||
od[key] = key
|
od[key] = key
|
||||||
|
|
||||||
|
# Direct use of dict methods
|
||||||
|
|
||||||
|
def test_dict_setitem(self):
|
||||||
|
OrderedDict = self.OrderedDict
|
||||||
|
od = OrderedDict()
|
||||||
|
dict.__setitem__(od, 'spam', 1)
|
||||||
|
self.assertNotIn('NULL', repr(od))
|
||||||
|
|
||||||
|
def test_dict_delitem(self):
|
||||||
|
OrderedDict = self.OrderedDict
|
||||||
|
od = OrderedDict()
|
||||||
|
od['spam'] = 1
|
||||||
|
od['ham'] = 2
|
||||||
|
dict.__delitem__(od, 'spam')
|
||||||
|
with self.assertRaises(KeyError):
|
||||||
|
repr(od)
|
||||||
|
|
||||||
|
def test_dict_clear(self):
|
||||||
|
OrderedDict = self.OrderedDict
|
||||||
|
od = OrderedDict()
|
||||||
|
od['spam'] = 1
|
||||||
|
od['ham'] = 2
|
||||||
|
dict.clear(od)
|
||||||
|
self.assertNotIn('NULL', repr(od))
|
||||||
|
|
||||||
|
def test_dict_pop(self):
|
||||||
|
OrderedDict = self.OrderedDict
|
||||||
|
od = OrderedDict()
|
||||||
|
od['spam'] = 1
|
||||||
|
od['ham'] = 2
|
||||||
|
dict.pop(od, 'spam')
|
||||||
|
with self.assertRaises(KeyError):
|
||||||
|
repr(od)
|
||||||
|
|
||||||
|
def test_dict_popitem(self):
|
||||||
|
OrderedDict = self.OrderedDict
|
||||||
|
od = OrderedDict()
|
||||||
|
od['spam'] = 1
|
||||||
|
od['ham'] = 2
|
||||||
|
dict.popitem(od)
|
||||||
|
with self.assertRaises(KeyError):
|
||||||
|
repr(od)
|
||||||
|
|
||||||
|
def test_dict_setdefault(self):
|
||||||
|
OrderedDict = self.OrderedDict
|
||||||
|
od = OrderedDict()
|
||||||
|
dict.setdefault(od, 'spam', 1)
|
||||||
|
self.assertNotIn('NULL', repr(od))
|
||||||
|
|
||||||
|
def test_dict_update(self):
|
||||||
|
od = OrderedDict()
|
||||||
|
dict.update(od, [('spam', 1)])
|
||||||
|
self.assertNotIn('NULL', repr(od))
|
||||||
|
|
||||||
|
|
||||||
class PurePythonOrderedDictTests(OrderedDictTests, unittest.TestCase):
|
class PurePythonOrderedDictTests(OrderedDictTests, unittest.TestCase):
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,9 @@ Release date: TBA
|
||||||
Core and Builtins
|
Core and Builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Issue #25449: Fixed a crash and leaking NULL in repr() of OrderedDict that
|
||||||
|
was mutated by direct calls of dict methods.
|
||||||
|
|
||||||
- Issue #25449: Iterating OrderedDict with keys with unstable hash now raises
|
- Issue #25449: Iterating OrderedDict with keys with unstable hash now raises
|
||||||
KeyError in C implementations as well as in Python implementation.
|
KeyError in C implementations as well as in Python implementation.
|
||||||
|
|
||||||
|
|
|
@ -1462,7 +1462,6 @@ odict_repr(PyODictObject *self)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
_Py_IDENTIFIER(items);
|
_Py_IDENTIFIER(items);
|
||||||
Py_ssize_t count = -1;
|
|
||||||
PyObject *pieces = NULL, *result = NULL;
|
PyObject *pieces = NULL, *result = NULL;
|
||||||
const char *classname;
|
const char *classname;
|
||||||
|
|
||||||
|
@ -1481,6 +1480,7 @@ odict_repr(PyODictObject *self)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PyODict_CheckExact(self)) {
|
if (PyODict_CheckExact(self)) {
|
||||||
|
Py_ssize_t count = 0;
|
||||||
_ODictNode *node;
|
_ODictNode *node;
|
||||||
pieces = PyList_New(PyODict_SIZE(self));
|
pieces = PyList_New(PyODict_SIZE(self));
|
||||||
if (pieces == NULL)
|
if (pieces == NULL)
|
||||||
|
@ -1499,8 +1499,19 @@ odict_repr(PyODictObject *self)
|
||||||
if (pair == NULL)
|
if (pair == NULL)
|
||||||
goto Done;
|
goto Done;
|
||||||
|
|
||||||
PyList_SET_ITEM(pieces, ++count, pair); /* steals reference */
|
if (count < PyList_GET_SIZE(pieces))
|
||||||
|
PyList_SET_ITEM(pieces, count, pair); /* steals reference */
|
||||||
|
else {
|
||||||
|
if (PyList_Append(pieces, pair) < 0) {
|
||||||
|
Py_DECREF(pair);
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
Py_DECREF(pair);
|
||||||
|
}
|
||||||
|
count++;
|
||||||
}
|
}
|
||||||
|
if (count < PyList_GET_SIZE(pieces))
|
||||||
|
PyList_GET_SIZE(pieces) = count;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
PyObject *items = _PyObject_CallMethodIdObjArgs((PyObject *)self,
|
PyObject *items = _PyObject_CallMethodIdObjArgs((PyObject *)self,
|
||||||
|
|
Loading…
Reference in New Issue