diff -r f2353e74b335 Modules/_randommodule.c --- a/Modules/_randommodule.c Tue Jan 08 23:12:00 2013 +0200 +++ b/Modules/_randommodule.c Wed Jan 09 19:00:27 2013 +0200 @@ -283,7 +283,8 @@ n = newn; if (keyused>= keymax) { unsigned long bigger = keymax << 1; - if ((bigger>> 1) != keymax) { + if ((bigger>> 1) != keymax || + bigger> PY_SSIZE_T_MAX / sizeof(*key)) { PyErr_NoMemory(); goto Done; } diff -r f2353e74b335 Modules/arraymodule.c --- a/Modules/arraymodule.c Tue Jan 08 23:12:00 2013 +0200 +++ b/Modules/arraymodule.c Wed Jan 09 19:00:27 2013 +0200 @@ -423,11 +423,11 @@ return NULL; } - nbytes = size * descr->itemsize; /* Check for overflow */ - if (nbytes / descr->itemsize != (size_t)size) { + if (size> PY_SSIZE_T_MAX / descr->itemsize) { return PyErr_NoMemory(); } + nbytes = size * descr->itemsize; op = (arrayobject *) type->tp_alloc(type, 0); if (op == NULL) { return NULL; @@ -1205,13 +1205,10 @@ char *item = self->ob_item; Py_ssize_t itemsize = self->ob_descr->itemsize; size_t nread; - Py_ssize_t newlength; size_t newbytes; - /* Be careful here about overflow */ - if ((newlength = Py_SIZE(self) + n) <= 0 || - (newbytes = newlength * itemsize) / itemsize != - (size_t)newlength) + if (n> (PY_SSIZE_T_MAX - Py_SIZE(self)) / itemsize) goto nomem; + newbytes = (Py_SIZE(self) + n) * itemsize; PyMem_RESIZE(item, char, newbytes); if (item == NULL) { nomem: diff -r f2353e74b335 Modules/audioop.c --- a/Modules/audioop.c Tue Jan 08 23:12:00 2013 +0200 +++ b/Modules/audioop.c Wed Jan 09 19:00:27 2013 +0200 @@ -1094,8 +1094,7 @@ PyErr_SetString(AudioopError, "# of channels should be>= 1"); return NULL; } - bytes_per_frame = size * nchannels; - if (bytes_per_frame / nchannels != size) { + if (size> INT_MAX / nchannels) { /* This overflow test is rigorously correct because both multiplicands are>= 1. Use the argument names from the docs for the error msg. */ @@ -1103,6 +1102,7 @@ "width * nchannels too big for a C int"); return NULL; } + bytes_per_frame = size * nchannels; if (weightA < 1 || weightB < 0) { PyErr_SetString(AudioopError, "weightA should be>= 1, weightB should be>= 0"); diff -r f2353e74b335 Modules/cPickle.c --- a/Modules/cPickle.c Tue Jan 08 23:12:00 2013 +0200 +++ b/Modules/cPickle.c Wed Jan 09 19:00:27 2013 +0200 @@ -218,14 +218,12 @@ size_t nbytes; PyObject **tmp; + if (self->size == 0 || self->size> (INT_MAX>> 1)) + goto nomemory; bigger = self->size << 1; - if (bigger <= 0) /* was 0, or new value overflows */ - goto nomemory; - if ((int)(size_t)bigger != bigger) + if ((size_t)bigger> PY_SSIZE_T_MAX / sizeof(PyObject *)) goto nomemory; nbytes = (size_t)bigger * sizeof(PyObject *); - if (nbytes / sizeof(PyObject *) != (size_t)bigger) - goto nomemory; tmp = realloc(self->data, nbytes); if (tmp == NULL) goto nomemory; diff -r f2353e74b335 Objects/bytearrayobject.c --- a/Objects/bytearrayobject.c Tue Jan 08 23:12:00 2013 +0200 +++ b/Objects/bytearrayobject.c Wed Jan 09 19:00:27 2013 +0200 @@ -357,9 +357,9 @@ if (count < 0) count = 0; mysize = Py_SIZE(self); + if (count != 0 && mysize> PY_SSIZE_T_MAX / count) + return PyErr_NoMemory(); size = mysize * count; - if (count != 0 && size / count != mysize) - return PyErr_NoMemory(); result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size); if (result != NULL && size != 0) { if (mysize == 1) @@ -382,9 +382,9 @@ if (count < 0) count = 0; mysize = Py_SIZE(self); + if (count != 0 && mysize> PY_SSIZE_T_MAX / count) + return PyErr_NoMemory(); size = mysize * count; - if (count != 0 && size / count != mysize) - return PyErr_NoMemory(); if (size < self->ob_alloc) { Py_SIZE(self) = size; self->ob_bytes[Py_SIZE(self)] = '0円'; /* Trailing null byte */ @@ -1568,7 +1568,7 @@ { char *self_s, *result_s; Py_ssize_t self_len, result_len; - Py_ssize_t count, i, product; + Py_ssize_t count, i; PyByteArrayObject *result; self_len = PyByteArray_GET_SIZE(self); @@ -1580,18 +1580,13 @@ /* Check for overflow */ /* result_len = count * to_len + self_len; */ - product = count * to_len; - if (product / to_len != count) { + assert(count> 0); + if (to_len> (PY_SSIZE_T_MAX - self_len) / count) { 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; - } + result_len = count * to_len + self_len; if (! (result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, result_len)) ) @@ -1821,7 +1816,7 @@ char *self_s, *result_s; char *start, *next, *end; Py_ssize_t self_len, result_len; - Py_ssize_t count, product; + Py_ssize_t count; PyByteArrayObject *result; self_s = PyByteArray_AS_STRING(self); @@ -1835,16 +1830,12 @@ /* use the difference between current and new, hence the "-1" */ /* result_len = self_len + count * (to_len-1) */ - product = count * (to_len-1); - if (product / (to_len-1) != count) { + assert(count> 0); + if (to_len - 1> (PY_SSIZE_T_MAX - self_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; - } + result_len = self_len + count * (to_len - 1); if ( (result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, result_len)) == NULL) @@ -1888,7 +1879,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; PyByteArrayObject *result; self_s = PyByteArray_AS_STRING(self); @@ -1905,16 +1896,12 @@ /* 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) { + assert(count> 0); + if (to_len - from_len> (PY_SSIZE_T_MAX - self_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; - } + result_len = self_len + count * (to_len - from_len); if ( (result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, result_len)) == NULL) diff -r f2353e74b335 Objects/longobject.c --- a/Objects/longobject.c Tue Jan 08 23:12:00 2013 +0200 +++ b/Objects/longobject.c Wed Jan 09 19:00:27 2013 +0200 @@ -483,10 +483,9 @@ assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0); if (ndigits> 0) { digit msd = v->ob_digit[ndigits - 1]; - - result = (ndigits - 1) * PyLong_SHIFT; - if (result / PyLong_SHIFT != (size_t)(ndigits - 1)) + if ((size_t)(ndigits - 1)> PY_SIZE_MAX / (size_t)PyLong_SHIFT) goto Overflow; + result = (size_t)(ndigits - 1) * (size_t)PyLong_SHIFT; do { ++result; if (result == 0) diff -r f2353e74b335 Objects/stringobject.c --- a/Objects/stringobject.c Tue Jan 08 23:12:00 2013 +0200 +++ b/Objects/stringobject.c Wed Jan 09 19:00:27 2013 +0200 @@ -922,13 +922,15 @@ PyString_Repr(PyObject *obj, int smartquotes) { register PyStringObject* op = (PyStringObject*) obj; - size_t newsize = 2 + 4 * Py_SIZE(op); + size_t newsize; PyObject *v; - if (newsize> PY_SSIZE_T_MAX || newsize / 4 != Py_SIZE(op)) { + if (Py_SIZE(op)> (PY_SSIZE_T_MAX - 2) / 4) { + PyErr_SetString(PyExc_OverflowError, "string is too large to make repr"); return NULL; } + newsize = 2 + 4 * Py_SIZE(op); v = PyString_FromStringAndSize((char *)NULL, newsize); if (v == NULL) { return NULL; @@ -1079,12 +1081,12 @@ /* watch out for overflows: the size can overflow int, * and the # of bytes needed can overflow size_t */ - size = Py_SIZE(a) * n; - if (n && size / n != Py_SIZE(a)) { + if (n> 0 && Py_SIZE(a)> PY_SSIZE_T_MAX / n) { PyErr_SetString(PyExc_OverflowError, "repeated string is too long"); return NULL; } + size = Py_SIZE(a) * n; if (size == Py_SIZE(a) && PyString_CheckExact(a)) { Py_INCREF(a); return (PyObject *)a; @@ -2354,7 +2356,7 @@ { char *self_s, *result_s; Py_ssize_t self_len, result_len; - Py_ssize_t count, i, product; + Py_ssize_t count, i; PyStringObject *result; self_len = PyString_GET_SIZE(self); @@ -2366,18 +2368,13 @@ /* Check for overflow */ /* result_len = count * to_len + self_len; */ - product = count * to_len; - if (product / to_len != count) { + assert(count> 0); + if (to_len> (PY_SSIZE_T_MAX - self_len) / count) { 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; - } + result_len = count * to_len + self_len; if (! (result = (PyStringObject *) PyString_FromStringAndSize(NULL, result_len)) ) @@ -2606,7 +2603,7 @@ char *self_s, *result_s; char *start, *next, *end; Py_ssize_t self_len, result_len; - Py_ssize_t count, product; + Py_ssize_t count; PyStringObject *result; self_s = PyString_AS_STRING(self); @@ -2620,16 +2617,12 @@ /* use the difference between current and new, hence the "-1" */ /* result_len = self_len + count * (to_len-1) */ - product = count * (to_len-1); - if (product / (to_len-1) != count) { + assert(count> 0); + if (to_len - 1> (PY_SSIZE_T_MAX - self_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; - } + result_len = self_len + count * (to_len - 1); if ( (result = (PyStringObject *) PyString_FromStringAndSize(NULL, result_len)) == NULL) @@ -2672,7 +2665,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; PyStringObject *result; self_s = PyString_AS_STRING(self); @@ -2689,16 +2682,12 @@ /* 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) { + assert(count> 0); + if (to_len - from_len> (PY_SSIZE_T_MAX - self_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; - } + result_len = self_len + count * (to_len-from_len); if ( (result = (PyStringObject *) PyString_FromStringAndSize(NULL, result_len)) == NULL) diff -r f2353e74b335 Objects/tupleobject.c --- a/Objects/tupleobject.c Tue Jan 08 23:12:00 2013 +0200 +++ b/Objects/tupleobject.c Wed Jan 09 19:00:27 2013 +0200 @@ -79,11 +79,9 @@ else #endif { - Py_ssize_t nbytes = size * sizeof(PyObject *); /* Check for overflow */ - if (nbytes / sizeof(PyObject *) != (size_t)size || - (nbytes> PY_SSIZE_T_MAX - sizeof(PyTupleObject) - sizeof(PyObject *))) - { + if (size> (PY_SSIZE_T_MAX - sizeof(PyTupleObject) - + sizeof(PyObject *)) / sizeof(PyObject *)) { return PyErr_NoMemory(); } @@ -490,9 +488,9 @@ if (Py_SIZE(a) == 0) return PyTuple_New(0); } + if (n> PY_SSIZE_T_MAX / Py_SIZE(a)) + return PyErr_NoMemory(); size = Py_SIZE(a) * n; - if (size/Py_SIZE(a) != n) - return PyErr_NoMemory(); np = (PyTupleObject *) PyTuple_New(size); if (np == NULL) return NULL; diff -r f2353e74b335 Objects/unicodeobject.c --- a/Objects/unicodeobject.c Tue Jan 08 23:12:00 2013 +0200 +++ b/Objects/unicodeobject.c Wed Jan 09 19:00:27 2013 +0200 @@ -1758,8 +1758,6 @@ const char *errors) { PyObject *v; - /* It might be possible to tighten this worst case */ - Py_ssize_t allocated = 8 * size; int inShift = 0; Py_ssize_t i = 0; unsigned int base64bits = 0; @@ -1767,13 +1765,14 @@ char * out; char * start; - if (allocated / 8 != size) + /* It might be possible to tighten this worst case */ + if (size> PY_SSIZE_T_MAX / 8) return PyErr_NoMemory(); if (size == 0) return PyString_FromStringAndSize(NULL, 0); - v = PyString_FromStringAndSize(NULL, allocated); + v = PyString_FromStringAndSize(NULL, size * 8); if (v == NULL) return NULL; @@ -2097,10 +2096,9 @@ } else { /* Overallocate on the heap, and give the excess back at the end. */ - nallocated = size * 4; - if (nallocated / 4 != size) /* overflow! */ + if (size> PY_SSIZE_T_MAX / 4) return PyErr_NoMemory(); - v = PyString_FromStringAndSize(NULL, nallocated); + v = PyString_FromStringAndSize(NULL, size * 4); if (v == NULL) return NULL; p = PyString_AS_STRING(v); @@ -2360,7 +2358,7 @@ { PyObject *v; unsigned char *p; - Py_ssize_t nsize, bytesize; + Py_ssize_t nsize; #ifndef Py_UNICODE_WIDE Py_ssize_t i, pairs; #else @@ -2391,10 +2389,9 @@ pairs++; #endif nsize = (size - pairs + (byteorder == 0)); - bytesize = nsize * 4; - if (bytesize / 4 != nsize) + if (nsize> PY_SSIZE_T_MAX / 4) return PyErr_NoMemory(); - v = PyString_FromStringAndSize(NULL, bytesize); + v = PyString_FromStringAndSize(NULL, nsize * 4); if (v == NULL) return NULL; @@ -2637,7 +2634,7 @@ { PyObject *v; unsigned char *p; - Py_ssize_t nsize, bytesize; + Py_ssize_t nsize; #ifdef Py_UNICODE_WIDE Py_ssize_t i, pairs; #else @@ -2667,10 +2664,9 @@ size> PY_SSIZE_T_MAX - pairs - (byteorder == 0)) return PyErr_NoMemory(); nsize = size + pairs + (byteorder == 0); - bytesize = nsize * 2; - if (bytesize / 2 != nsize) + if (nsize> PY_SSIZE_T_MAX / 2) return PyErr_NoMemory(); - v = PyString_FromStringAndSize(NULL, bytesize); + v = PyString_FromStringAndSize(NULL, nsize * 2); if (v == NULL) return NULL; @@ -5863,7 +5859,7 @@ } else { Py_ssize_t n, i, j; - Py_ssize_t product, new_size, delta; + Py_ssize_t new_size, delta; Py_UNICODE *p; /* replace strings */ @@ -5876,18 +5872,14 @@ if (delta == 0) { new_size = self->length; } else { - product = n * (str2->length - str1->length); - if ((product / (str2->length - str1->length)) != n) { + if (str2->length> str1->length && + str2->length - str1->length> + (PY_SSIZE_T_MAX - self->length) / n) { PyErr_SetString(PyExc_OverflowError, "replace string is too long"); return NULL; } - new_size = self->length + product; - if (new_size < 0) { - PyErr_SetString(PyExc_OverflowError, - "replace string is too long"); - return NULL; - } + new_size = self->length + n * (str2->length - str1->length); } u = _PyUnicode_New(new_size); if (!u) @@ -7132,7 +7124,6 @@ PyUnicodeObject *u; Py_UNICODE *p; Py_ssize_t nchars; - size_t nbytes; if (len < 0) len = 0; @@ -7146,18 +7137,12 @@ /* ensure # of chars needed doesn't overflow int and # of bytes * needed doesn't overflow size_t */ - nchars = len * str->length; - if (len && nchars / len != str->length) { + if (len && str->length> (PY_SSIZE_T_MAX / sizeof(Py_UNICODE) - 1) / len) { PyErr_SetString(PyExc_OverflowError, "repeated string is too long"); return NULL; } - nbytes = (nchars + 1) * sizeof(Py_UNICODE); - if (nbytes / sizeof(Py_UNICODE) != (size_t)(nchars + 1)) { - PyErr_SetString(PyExc_OverflowError, - "repeated string is too long"); - return NULL; - } + nchars = len * str->length; u = _PyUnicode_New(nchars); if (!u) return NULL;