diff options
-rw-r--r-- | Misc/NEWS.d/next/Core and Builtins/2018-09-11-15-19-37.bpo-1621.7o19yG.rst | 2 | ||||
-rw-r--r-- | Objects/setobject.c | 11 |
2 files changed, 5 insertions, 8 deletions
diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-09-11-15-19-37.bpo-1621.7o19yG.rst b/Misc/NEWS.d/next/Core and Builtins/2018-09-11-15-19-37.bpo-1621.7o19yG.rst new file mode 100644 index 0000000..4047ff3 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-09-11-15-19-37.bpo-1621.7o19yG.rst @@ -0,0 +1,2 @@ +Do not assume signed integer overflow behavior (C undefined behavior) when +performing set hash table resizing. diff --git a/Objects/setobject.c b/Objects/setobject.c index 82b5838..e7a5288 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -302,7 +302,6 @@ actually be smaller than the old one. static int set_table_resize(PySetObject *so, Py_ssize_t minused) { - Py_ssize_t newsize; setentry *oldtable, *newtable, *entry; Py_ssize_t oldmask = so->mask; size_t newmask; @@ -313,13 +312,9 @@ set_table_resize(PySetObject *so, Py_ssize_t minused) /* Find the smallest table size > minused. */ /* XXX speed-up with intrinsics */ - for (newsize = PySet_MINSIZE; - newsize <= minused && newsize > 0; - newsize <<= 1) - ; - if (newsize <= 0) { - PyErr_NoMemory(); - return -1; + size_t newsize = PySet_MINSIZE; + while (newsize <= (size_t)minused) { + newsize <<= 1; // The largest possible value is PY_SSIZE_T_MAX + 1. } /* Get space for a new table. */ |