From 35d79fa9d40fe4447be57822636d57f20b84917b Mon Sep 17 00:00:00 2001 From: Xiang Zhang Date: Mon, 20 Feb 2017 15:27:00 +0800 Subject: [PATCH 1/2] bpo-27660: remove unnecessary overflow checks in list_resize --- Objects/listobject.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/Objects/listobject.c b/Objects/listobject.c index 89941749d4953e..4102b15eadd6cb 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -26,7 +26,7 @@ static int list_resize(PyListObject *self, Py_ssize_t newsize) { PyObject **items; - size_t new_allocated; + size_t new_allocated, size; Py_ssize_t allocated = self->allocated; /* Bypass realloc() when a previous overallocation is large enough @@ -47,22 +47,17 @@ list_resize(PyListObject *self, Py_ssize_t newsize) * The growth pattern is: 0, 4, 8, 16, 25, 35, 46, 58, 72, 88, ... */ new_allocated = (newsize >> 3) + (newsize < 9 ? 3 : 6); - - /* check for integer overflow */ - if (new_allocated > SIZE_MAX - newsize) { + /* can't overflow, largest number is PY_SSIZE_T_MAX * (9 / 8) + 6 */ + new_allocated += (size_t)newsize; + if (new_allocated > (size_t)PY_SSIZE_T_MAX / sizeof(PyObject *)) { PyErr_NoMemory(); return -1; - } else { - new_allocated += newsize; } if (newsize == 0) new_allocated = 0; - items = self->ob_item; - if (new_allocated <= (SIZE_MAX / sizeof(PyObject *))) - PyMem_RESIZE(items, PyObject *, new_allocated); - else - items = NULL; + size = new_allocated * sizeof(PyObject *); + items = (PyObject **)PyMem_Realloc(self->ob_item, size); if (items == NULL) { PyErr_NoMemory(); return -1; From 529f3333a41a4083fb8894044f61e8dc865bee17 Mon Sep 17 00:00:00 2001 From: Xiang Zhang Date: Tue, 21 Feb 2017 11:33:42 +0800 Subject: [PATCH 2/2] fix two style nits by Raymond --- Objects/listobject.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Objects/listobject.c b/Objects/listobject.c index 4102b15eadd6cb..edd4a15068adca 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -26,7 +26,7 @@ static int list_resize(PyListObject *self, Py_ssize_t newsize) { PyObject **items; - size_t new_allocated, size; + size_t new_allocated, num_allocated_bytes; Py_ssize_t allocated = self->allocated; /* Bypass realloc() when a previous overallocation is large enough @@ -45,10 +45,10 @@ list_resize(PyListObject *self, Py_ssize_t newsize) * sequence of appends() in the presence of a poorly-performing * system realloc(). * The growth pattern is: 0, 4, 8, 16, 25, 35, 46, 58, 72, 88, ... + * Note: new_allocated won't overflow because the largest possible value + * is PY_SSIZE_T_MAX * (9 / 8) + 6 which always fits in a size_t. */ - new_allocated = (newsize >> 3) + (newsize < 9 ? 3 : 6); - /* can't overflow, largest number is PY_SSIZE_T_MAX * (9 / 8) + 6 */ - new_allocated += (size_t)newsize; + new_allocated = (size_t)newsize + (newsize >> 3) + (newsize < 9 ? 3 : 6); if (new_allocated > (size_t)PY_SSIZE_T_MAX / sizeof(PyObject *)) { PyErr_NoMemory(); return -1; @@ -56,8 +56,8 @@ list_resize(PyListObject *self, Py_ssize_t newsize) if (newsize == 0) new_allocated = 0; - size = new_allocated * sizeof(PyObject *); - items = (PyObject **)PyMem_Realloc(self->ob_item, size); + num_allocated_bytes = new_allocated * sizeof(PyObject *); + items = (PyObject **)PyMem_Realloc(self->ob_item, num_allocated_bytes); if (items == NULL) { PyErr_NoMemory(); return -1;