summaryrefslogtreecommitdiffstats
path: root/Objects/setobject.c
diff options
context:
space:
mode:
authorRaymond Hettinger <python@rcn.com>2015-07-16 06:54:02 (GMT)
committerRaymond Hettinger <python@rcn.com>2015-07-16 06:54:02 (GMT)
commit061091a7c505403fbb95e8f8e16e1b7b6ed5dd1b (patch)
tree90aef7fcba53a0fc0825fa0a3965cf6ce43f108e /Objects/setobject.c
parentd702044bcdb0678cb0ba96235c43ffcaa737214c (diff)
downloadcpython-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.c18
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