mirror of https://github.com/python/cpython
Issue #24992: Fix error handling and a race condition (related to garbage
collection) in collections.OrderedDict constructor. Patch reviewed by Serhiy Storchaka.
This commit is contained in:
parent
38b8ae0f5b
commit
ca30b02abe
|
@ -14,6 +14,9 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #24992: Fix error handling and a race condition (related to garbage
|
||||||
|
collection) in collections.OrderedDict constructor.
|
||||||
|
|
||||||
- Issue #24881: Fixed setting binary mode in Python implementation of FileIO
|
- Issue #24881: Fixed setting binary mode in Python implementation of FileIO
|
||||||
on Windows and Cygwin. Patch from Akira Li.
|
on Windows and Cygwin. Patch from Akira Li.
|
||||||
|
|
||||||
|
|
|
@ -98,7 +98,6 @@ For removing nodes:
|
||||||
|
|
||||||
Others:
|
Others:
|
||||||
|
|
||||||
* _odict_initialize(od)
|
|
||||||
* _odict_find_node(od, key)
|
* _odict_find_node(od, key)
|
||||||
* _odict_keys_equal(od1, od2)
|
* _odict_keys_equal(od1, od2)
|
||||||
|
|
||||||
|
@ -602,15 +601,6 @@ _odict_get_index(PyODictObject *od, PyObject *key)
|
||||||
return _odict_get_index_hash(od, key, hash);
|
return _odict_get_index_hash(od, key, hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
_odict_initialize(PyODictObject *od)
|
|
||||||
{
|
|
||||||
od->od_state = 0;
|
|
||||||
_odict_FIRST(od) = NULL;
|
|
||||||
_odict_LAST(od) = NULL;
|
|
||||||
return _odict_resize((PyODictObject *)od);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns NULL if there was some error or the key was not found. */
|
/* Returns NULL if there was some error or the key was not found. */
|
||||||
static _ODictNode *
|
static _ODictNode *
|
||||||
_odict_find_node(PyODictObject *od, PyObject *key)
|
_odict_find_node(PyODictObject *od, PyObject *key)
|
||||||
|
@ -744,7 +734,7 @@ _odict_pop_node(PyODictObject *od, _ODictNode *node, PyObject *key)
|
||||||
/* If someone calls PyDict_DelItem() directly on an OrderedDict, we'll
|
/* If someone calls PyDict_DelItem() directly on an OrderedDict, we'll
|
||||||
get all sorts of problems here. In PyODict_DelItem we make sure to
|
get all sorts of problems here. In PyODict_DelItem we make sure to
|
||||||
call _odict_clear_node first.
|
call _odict_clear_node first.
|
||||||
|
|
||||||
This matters in the case of colliding keys. Suppose we add 3 keys:
|
This matters in the case of colliding keys. Suppose we add 3 keys:
|
||||||
[A, B, C], where the hash of C collides with A and the next possible
|
[A, B, C], where the hash of C collides with A and the next possible
|
||||||
index in the hash table is occupied by B. If we remove B then for C
|
index in the hash table is occupied by B. If we remove B then for C
|
||||||
|
@ -1739,14 +1729,28 @@ odict_init(PyObject *self, PyObject *args, PyObject *kwds)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
odict_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
odict_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
{
|
{
|
||||||
PyObject *od = PyDict_Type.tp_new(type, args, kwds);
|
PyObject *dict;
|
||||||
if (od != NULL) {
|
PyODictObject *od;
|
||||||
if (_odict_initialize((PyODictObject *)od) < 0)
|
|
||||||
return NULL;
|
dict = PyDict_New();
|
||||||
((PyODictObject *)od)->od_inst_dict = PyDict_New();
|
if (dict == NULL)
|
||||||
((PyODictObject *)od)->od_weakreflist = NULL;
|
return NULL;
|
||||||
|
|
||||||
|
od = (PyODictObject *)PyDict_Type.tp_new(type, args, kwds);
|
||||||
|
if (od == NULL) {
|
||||||
|
Py_DECREF(dict);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
return od;
|
|
||||||
|
od->od_inst_dict = dict;
|
||||||
|
/* type constructor fills the memory with zeros (see
|
||||||
|
PyType_GenericAlloc()), there is no need to set them to zero again */
|
||||||
|
if (_odict_resize(od) < 0) {
|
||||||
|
Py_DECREF(od);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (PyObject*)od;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* PyODict_Type */
|
/* PyODict_Type */
|
||||||
|
|
Loading…
Reference in New Issue