diff -r 9acdcafd1418 Objects/bytearrayobject.c --- a/Objects/bytearrayobject.c Tue Dec 27 15:08:27 2016 +0100 +++ b/Objects/bytearrayobject.c Thu Jan 05 00:21:00 2017 +0800 @@ -1577,24 +1577,23 @@ self_len = PyByteArray_GET_SIZE(self); /* 1 at the end plus 1 after every character */ - count = self_len+1; - if (maxcount < count) - count = maxcount; + count = self_len < maxcount ? self_len + 1 : maxcount; /* Check for overflow */ /* result_len = count * to_len + self_len; */ + assert(to_len > 0); + if (count > PY_SSIZE_T_MAX / to_len) { + PyErr_SetString(PyExc_OverflowError, + "replace bytes is too long"); + return NULL; + } product = count * to_len; - if (product / to_len != count) { + if (product > PY_SSIZE_T_MAX - self_len) { PyErr_SetString(PyExc_OverflowError, - "replace string is too long"); + "replace bytes is too long"); return NULL; } result_len = product + self_len; - if (result_len < 0) { - PyErr_SetString(PyExc_OverflowError, - "replace string is too long"); - return NULL; - } if (! (result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, result_len)) ) @@ -1838,16 +1837,17 @@ /* use the difference between current and new, hence the "-1" */ /* result_len = self_len + count * (to_len-1) */ + assert(to_len-1 > 0); + if (count > PY_SSIZE_T_MAX / (to_len-1)) { + PyErr_SetString(PyExc_OverflowError, "replace bytes is too long"); + return NULL; + } product = count * (to_len-1); - if (product / (to_len-1) != count) { + if (product > PY_SSIZE_T_MAX - self_len) { PyErr_SetString(PyExc_OverflowError, "replace bytes is too long"); return NULL; } result_len = self_len + product; - if (result_len < 0) { - PyErr_SetString(PyExc_OverflowError, "replace bytes is too long"); - return NULL; - } if ( (result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, result_len)) == NULL) @@ -1891,7 +1891,7 @@ char *self_s, *result_s; char *start, *next, *end; Py_ssize_t self_len, result_len; - Py_ssize_t count, offset, product; + Py_ssize_t count, offset, difference; PyByteArrayObject *result; self_s = PyByteArray_AS_STRING(self); @@ -1908,15 +1908,25 @@ /* Check for overflow */ /* result_len = self_len + count * (to_len-from_len) */ - product = count * (to_len-from_len); - if (product / (to_len-from_len) != count) { - PyErr_SetString(PyExc_OverflowError, "replace bytes is too long"); - return NULL; - } - result_len = self_len + product; - if (result_len < 0) { - PyErr_SetString(PyExc_OverflowError, "replace bytes is too long"); - return NULL; + difference = to_len - from_len; + if (difference <= 0) { + result_len = self_len + count * difference; + if (result_len < 0) { + PyErr_SetString(PyExc_OverflowError, "replace bytes is too long"); + return NULL; + } + } else { + Py_ssize_t product; + if (count > PY_SSIZE_T_MAX / difference) { + PyErr_SetString(PyExc_OverflowError, "replace bytes is too long"); + return NULL; + } + product = count * difference; + if (product > PY_SSIZE_T_MAX - self_len) { + PyErr_SetString(PyExc_OverflowError, "replace bytes is too long"); + return NULL; + } + result_len = self_len + product; } if ( (result = (PyByteArrayObject *) diff -r 9acdcafd1418 Objects/stringobject.c --- a/Objects/stringobject.c Tue Dec 27 15:08:27 2016 +0100 +++ b/Objects/stringobject.c Thu Jan 05 00:21:00 2017 +0800 @@ -2364,24 +2364,23 @@ self_len = PyString_GET_SIZE(self); /* 1 at the end plus 1 after every character */ - count = self_len+1; - if (maxcount < count) - count = maxcount; + count = self_len < maxcount ? self_len + 1 : maxcount; /* Check for overflow */ /* result_len = count * to_len + self_len; */ + assert(to_len > 0); + if (count > PY_SSIZE_T_MAX / to_len) { + PyErr_SetString(PyExc_OverflowError, + "replace string is too long"); + return NULL; + } product = count * to_len; - if (product / to_len != count) { + if (product > PY_SSIZE_T_MAX - self_len) { PyErr_SetString(PyExc_OverflowError, "replace string is too long"); return NULL; } result_len = product + self_len; - if (result_len < 0) { - PyErr_SetString(PyExc_OverflowError, - "replace string is too long"); - return NULL; - } if (! (result = (PyStringObject *) PyString_FromStringAndSize(NULL, result_len)) ) @@ -2624,16 +2623,17 @@ /* use the difference between current and new, hence the "-1" */ /* result_len = self_len + count * (to_len-1) */ + assert(to_len-1 > 0); + if (count > PY_SSIZE_T_MAX / (to_len-1)) { + PyErr_SetString(PyExc_OverflowError, "replace string is too long"); + return NULL; + } product = count * (to_len-1); - if (product / (to_len-1) != count) { + if (product > PY_SSIZE_T_MAX - self_len) { PyErr_SetString(PyExc_OverflowError, "replace string is too long"); return NULL; } result_len = self_len + product; - if (result_len < 0) { - PyErr_SetString(PyExc_OverflowError, "replace string is too long"); - return NULL; - } if ( (result = (PyStringObject *) PyString_FromStringAndSize(NULL, result_len)) == NULL) @@ -2676,7 +2676,7 @@ char *self_s, *result_s; char *start, *next, *end; Py_ssize_t self_len, result_len; - Py_ssize_t count, offset, product; + Py_ssize_t count, offset, difference; PyStringObject *result; self_s = PyString_AS_STRING(self); @@ -2693,15 +2693,25 @@ /* Check for overflow */ /* result_len = self_len + count * (to_len-from_len) */ - product = count * (to_len-from_len); - if (product / (to_len-from_len) != count) { - PyErr_SetString(PyExc_OverflowError, "replace string is too long"); - return NULL; - } - result_len = self_len + product; - if (result_len < 0) { - PyErr_SetString(PyExc_OverflowError, "replace string is too long"); - return NULL; + difference = to_len - from_len; + if (difference <= 0) { + result_len = self_len + count * difference; + if (result_len < 0) { + PyErr_SetString(PyExc_OverflowError, "replace string is too long"); + return NULL; + } + } else { + Py_ssize_t product; + if (count > PY_SSIZE_T_MAX / difference) { + PyErr_SetString(PyExc_OverflowError, "replace string is too long"); + return NULL; + } + product = count * difference; + if (product > PY_SSIZE_T_MAX - self_len) { + PyErr_SetString(PyExc_OverflowError, "replace string is too long"); + return NULL; + } + result_len = self_len + product; } if ( (result = (PyStringObject *)