summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Misc/NEWS.d/next/Core and Builtins/2018-09-11-15-19-37.bpo-1621.7o19yG.rst2
-rw-r--r--Objects/setobject.c11
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. */