diff options
author | Raymond Hettinger <python@rcn.com> | 2015-07-16 06:54:02 (GMT) |
---|---|---|
committer | Raymond Hettinger <python@rcn.com> | 2015-07-16 06:54:02 (GMT) |
commit | 061091a7c505403fbb95e8f8e16e1b7b6ed5dd1b (patch) | |
tree | 90aef7fcba53a0fc0825fa0a3965cf6ce43f108e /Objects/setobject.c | |
parent | d702044bcdb0678cb0ba96235c43ffcaa737214c (diff) | |
download | cpython-061091a7c505403fbb95e8f8e16e1b7b6ed5dd1b.zip cpython-061091a7c505403fbb95e8f8e16e1b7b6ed5dd1b.tar.gz cpython-061091a7c505403fbb95e8f8e16e1b7b6ed5dd1b.tar.bz2 |
Issue #24583: Fix crash when set is mutated while being updated.
Diffstat (limited to 'Objects/setobject.c')
-rw-r--r-- | Objects/setobject.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/Objects/setobject.c b/Objects/setobject.c index 922c619..fbac596 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -127,7 +127,7 @@ set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash) static int set_table_resize(PySetObject *, Py_ssize_t); static int -set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash) +_set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash) { setentry *table = so->table; setentry *freeslot; @@ -162,7 +162,7 @@ set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash) if (cmp < 0) /* unlikely */ return -1; if (table != so->table || entry->key != startkey) /* unlikely */ - return set_add_entry(so, key, hash); + return _set_add_entry(so, key, hash); if (cmp > 0) /* likely */ goto found_active; mask = so->mask; /* help avoid a register spill */ @@ -190,7 +190,7 @@ set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash) if (cmp < 0) return -1; if (table != so->table || entry->key != startkey) - return set_add_entry(so, key, hash); + return _set_add_entry(so, key, hash); if (cmp > 0) goto found_active; mask = so->mask; @@ -211,14 +211,12 @@ set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash) found_unused_or_dummy: if (freeslot == NULL) goto found_unused; - Py_INCREF(key); so->used++; freeslot->key = key; freeslot->hash = hash; return 0; found_unused: - Py_INCREF(key); so->fill++; so->used++; entry->key = key; @@ -231,6 +229,16 @@ set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash) return 0; } +static int +set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash) +{ + Py_INCREF(key); + if (!_set_add_entry(so, key, hash)) + return 0; + Py_DECREF(key); + return -1; +} + /* Internal routine used by set_table_resize() to insert an item which is known to be absent from the set. This routine also assumes that |