[Python-checkins] cpython: Issue #24583: Fix crash when set is mutated while being updated.

raymond.hettinger python-checkins at python.org
Thu Jul 16 08:54:18 CEST 2015


https://hg.python.org/cpython/rev/05cb67dab161
changeset:   96919:05cb67dab161
user:        Raymond Hettinger <python at rcn.com>
date:        Wed Jul 15 23:54:02 2015 -0700
summary:
  Issue #24583: Fix crash when set is mutated while being updated.

files:
  Objects/setobject.c |  18 +++++++++++++-----
  1 files changed, 13 insertions(+), 5 deletions(-)


diff --git a/Objects/setobject.c b/Objects/setobject.c
--- a/Objects/setobject.c
+++ b/Objects/setobject.c
@@ -127,7 +127,7 @@
 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 @@
             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 @@
                     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 @@
   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 @@
     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

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list