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:
Victor Stinner 2015-09-03 17:50:04 +02:00
parent 38b8ae0f5b
commit ca30b02abe
2 changed files with 25 additions and 18 deletions

View File

@ -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.

View File

@ -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)
@ -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)
dict = PyDict_New();
if (dict == NULL)
return NULL;
od = (PyODictObject *)PyDict_Type.tp_new(type, args, kwds);
if (od == NULL) {
Py_DECREF(dict);
return NULL; return NULL;
((PyODictObject *)od)->od_inst_dict = PyDict_New();
((PyODictObject *)od)->od_weakreflist = 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 */