mirror of
https://github.com/python/cpython.git
synced 2025-12-04 00:30:19 +00:00
Tim pointed out a remaining vulnerability in popitem(): the
PyTuple_New() could *conceivably* clear the dict, so move the test for an empty dict after the tuple allocation. It means that we waste time allocating and deallocating a 2-tuple when the dict is empty, but who cares. It also means that when the dict is empty *and* there's no memory to allocate a 2-tuple, we raise MemoryError, not KeyError -- but that may actually a good idea: if there's no room for a lousy 2-tuple, what are the chances that there's room for a KeyError instance?
This commit is contained in:
parent
a4dd011259
commit
e04eaec5b6
1 changed files with 6 additions and 5 deletions
|
|
@ -1155,11 +1155,6 @@ dict_popitem(dictobject *mp, PyObject *args)
|
|||
|
||||
if (!PyArg_NoArgs(args))
|
||||
return NULL;
|
||||
if (mp->ma_used == 0) {
|
||||
PyErr_SetString(PyExc_KeyError,
|
||||
"popitem(): dictionary is empty");
|
||||
return NULL;
|
||||
}
|
||||
/* Allocate the result tuple first. Believe it or not,
|
||||
* this allocation could trigger a garbage collection which
|
||||
* could resize the dict, which would invalidate the pointer
|
||||
|
|
@ -1169,6 +1164,12 @@ dict_popitem(dictobject *mp, PyObject *args)
|
|||
res = PyTuple_New(2);
|
||||
if (res == NULL)
|
||||
return NULL;
|
||||
if (mp->ma_used == 0) {
|
||||
Py_DECREF(res);
|
||||
PyErr_SetString(PyExc_KeyError,
|
||||
"popitem(): dictionary is empty");
|
||||
return NULL;
|
||||
}
|
||||
/* Set ep to "the first" dict entry with a value. We abuse the hash
|
||||
* field of slot 0 to hold a search finger:
|
||||
* If slot 0 has a value, use slot 0.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue