diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-10-06-22-08-50.bpo-31165.rH1Z10.rst b/Misc/NEWS.d/next/Core and Builtins/2017-10-06-22-08-50.bpo-31165.rH1Z10.rst new file mode 100644 index 00000000000000..b963ee07bc3595 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2017-10-06-22-08-50.bpo-31165.rH1Z10.rst @@ -0,0 +1,2 @@ +Detect mutated list in list_slice(): check if the list size changed +before/after allocating a new list object to prevent a crash. diff --git a/Objects/listobject.c b/Objects/listobject.c index 858532252e92a7..cc3f60bd7d66aa 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -436,20 +436,26 @@ list_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh) { PyListObject *np; PyObject **src, **dest; - Py_ssize_t i, len; + Py_ssize_t alen, i, len; + alen = Py_SIZE(a); if (ilow < 0) ilow = 0; - else if (ilow > Py_SIZE(a)) - ilow = Py_SIZE(a); + else if (ilow > alen) + ilow = alen; if (ihigh < ilow) ihigh = ilow; - else if (ihigh > Py_SIZE(a)) - ihigh = Py_SIZE(a); + else if (ihigh > alen) + ihigh = alen; len = ihigh - ilow; np = (PyListObject *) PyList_New(len); if (np == NULL) return NULL; + if (Py_SIZE(a) != alen) { + PyErr_SetString(PyExc_RuntimeError, "list mutated during slicing"); + return NULL; + } + src = a->ob_item + ilow; dest = np->ob_item; for (i = 0; i < len; i++) {