Issue #24583: Fix crash when set is mutated while being updated.
This commit is contained in:
parent
d702044bcd
commit
061091a7c5
@ -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_table_resize(PySetObject *, Py_ssize_t);
|
||||||
|
|
||||||
static int
|
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 *table = so->table;
|
||||||
setentry *freeslot;
|
setentry *freeslot;
|
||||||
@ -162,7 +162,7 @@ set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
|
|||||||
if (cmp < 0) /* unlikely */
|
if (cmp < 0) /* unlikely */
|
||||||
return -1;
|
return -1;
|
||||||
if (table != so->table || entry->key != startkey) /* unlikely */
|
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 */
|
if (cmp > 0) /* likely */
|
||||||
goto found_active;
|
goto found_active;
|
||||||
mask = so->mask; /* help avoid a register spill */
|
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)
|
if (cmp < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (table != so->table || entry->key != startkey)
|
if (table != so->table || entry->key != startkey)
|
||||||
return set_add_entry(so, key, hash);
|
return _set_add_entry(so, key, hash);
|
||||||
if (cmp > 0)
|
if (cmp > 0)
|
||||||
goto found_active;
|
goto found_active;
|
||||||
mask = so->mask;
|
mask = so->mask;
|
||||||
@ -211,14 +211,12 @@ set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
|
|||||||
found_unused_or_dummy:
|
found_unused_or_dummy:
|
||||||
if (freeslot == NULL)
|
if (freeslot == NULL)
|
||||||
goto found_unused;
|
goto found_unused;
|
||||||
Py_INCREF(key);
|
|
||||||
so->used++;
|
so->used++;
|
||||||
freeslot->key = key;
|
freeslot->key = key;
|
||||||
freeslot->hash = hash;
|
freeslot->hash = hash;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
found_unused:
|
found_unused:
|
||||||
Py_INCREF(key);
|
|
||||||
so->fill++;
|
so->fill++;
|
||||||
so->used++;
|
so->used++;
|
||||||
entry->key = key;
|
entry->key = key;
|
||||||
@ -231,6 +229,16 @@ set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
|
|||||||
return 0;
|
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
|
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
|
known to be absent from the set. This routine also assumes that
|
||||||
|
Loading…
x
Reference in New Issue
Block a user