cpython: ef1f5aebe1a6 (original) (raw)
Mercurial > cpython
changeset 97629:ef1f5aebe1a6 3.5
Issue #24992: Fix error handling and a race condition (related to garbage collection) in collections.OrderedDict constructor. Patch reviewed by Serhiy Storchaka. [#24992]
Victor Stinner victor.stinner@gmail.com | |
---|---|
date | Thu, 03 Sep 2015 17:50:04 +0200 |
parents | ac1995b01028 |
children | e9929da99349 863407e80370 |
files | Misc/NEWS Objects/odictobject.c |
diffstat | 2 files changed, 25 insertions(+), 18 deletions(-)[+] [-] Misc/NEWS 3 Objects/odictobject.c 40 |
line wrap: on
line diff
--- a/Misc/NEWS +++ b/Misc/NEWS @@ -14,6 +14,9 @@ Core and Builtins Library ------- +- Issue #24992: Fix error handling and a race condition (related to garbage
- Issue #24881: Fixed setting binary mode in Python implementation of FileIO on Windows and Cygwin. Patch from Akira Li.
--- a/Objects/odictobject.c +++ b/Objects/odictobject.c @@ -98,7 +98,6 @@ For removing nodes: Others: -* _odict_initialize(od)
- _odict_find_node(od, key)
- _odict_keys_equal(od1, od2) @@ -602,15 +601,6 @@ static Py_ssize_t 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. */ static _ODictNode * _odict_find_node(PyODictObject *od, PyObject *key) @@ -744,7 +734,7 @@ static _ODictNode / If someone calls PyDict_DelItem() directly on an OrderedDict, we'll get all sorts of problems here. In PyODict_DelItem we make sure to call _odict_clear_node first.
- + 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 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 *arg static PyObject * odict_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
- PyObject *od = PyDict_Type.tp_new(type, args, kwds);
- if (od != NULL) {
if (_odict_initialize((PyODictObject *)od) < 0)[](#l2.42)
return NULL;[](#l2.43)
((PyODictObject *)od)->od_inst_dict = PyDict_New();[](#l2.44)
((PyODictObject *)od)->od_weakreflist = NULL;[](#l2.45)
- od = (PyODictObject *)PyDict_Type.tp_new(type, args, kwds);
- if (od == NULL) {
Py_DECREF(dict);[](#l2.55)
}return NULL;[](#l2.56)