diff -r f28aff31900a Modules/_codecsmodule.c --- a/Modules/_codecsmodule.c Wed Jan 09 12:21:57 2013 +0200 +++ b/Modules/_codecsmodule.c Wed Jan 09 19:00:20 2013 +0200 @@ -174,12 +174,12 @@ return NULL; size = PyBytes_GET_SIZE(str); - newsize = 4*size; - if (newsize > PY_SSIZE_T_MAX || newsize / 4 != size) { + if (size > PY_SSIZE_T_MAX / 4) { PyErr_SetString(PyExc_OverflowError, "string is too large to encode"); return NULL; } + newsize = 4*size; v = PyBytes_FromStringAndSize(NULL, newsize); if (v == NULL) { diff -r f28aff31900a Modules/_datetimemodule.c --- a/Modules/_datetimemodule.c Wed Jan 09 12:21:57 2013 +0200 +++ b/Modules/_datetimemodule.c Wed Jan 09 19:00:20 2013 +0200 @@ -1286,14 +1286,13 @@ assert(ptoappend != NULL); assert(ntoappend > 0); while (usednew + ntoappend > totalnew) { - size_t bigger = totalnew << 1; - if ((bigger >> 1) != totalnew) { /* overflow */ + if (totalnew > (PY_SSIZE_T_MAX >> 1)) { /* overflow */ PyErr_NoMemory(); goto Done; } - if (_PyBytes_Resize(&newfmt, bigger) < 0) + totalnew <<= 1; + if (_PyBytes_Resize(&newfmt, totalnew) < 0) goto Done; - totalnew = bigger; pnew = PyBytes_AsString(newfmt) + usednew; } memcpy(pnew, ptoappend, ntoappend); diff -r f28aff31900a Modules/_randommodule.c --- a/Modules/_randommodule.c Wed Jan 09 12:21:57 2013 +0200 +++ b/Modules/_randommodule.c Wed Jan 09 19:00:20 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 f28aff31900a Modules/arraymodule.c --- a/Modules/arraymodule.c Wed Jan 09 12:21:57 2013 +0200 +++ b/Modules/arraymodule.c Wed Jan 09 19:00:20 2013 +0200 @@ -426,11 +426,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; @@ -1196,11 +1196,15 @@ if (!PyArg_ParseTuple(args, "On:fromfile", &f, &n)) return NULL; - nbytes = n * itemsize; - if (nbytes < 0 || nbytes/itemsize != n) { + if (n < 0) { + PyErr_SetString(PyExc_ValueError, "negative count"); + return NULL; + } + if (n > PY_SSIZE_T_MAX / itemsize) { PyErr_NoMemory(); return NULL; } + nbytes = n * itemsize; b = PyObject_CallMethod(f, "read", "n", nbytes); if (b == NULL) diff -r f28aff31900a Modules/audioop.c --- a/Modules/audioop.c Wed Jan 09 12:21:57 2013 +0200 +++ b/Modules/audioop.c Wed Jan 09 19:00:20 2013 +0200 @@ -1110,8 +1110,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. */ @@ -1119,6 +1118,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 f28aff31900a Objects/longobject.c --- a/Objects/longobject.c Wed Jan 09 12:21:57 2013 +0200 +++ b/Objects/longobject.c Wed Jan 09 19:00:20 2013 +0200 @@ -658,10 +658,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 f28aff31900a Objects/tupleobject.c --- a/Objects/tupleobject.c Wed Jan 09 12:21:57 2013 +0200 +++ b/Objects/tupleobject.c Wed Jan 09 19:00:20 2013 +0200 @@ -80,15 +80,11 @@ 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(); } - nbytes += sizeof(PyTupleObject) - sizeof(PyObject *); - op = PyObject_GC_NewVar(PyTupleObject, &PyTuple_Type, size); if (op == NULL) return NULL; @@ -465,9 +461,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 f28aff31900a Objects/unicodeobject.c --- a/Objects/unicodeobject.c Wed Jan 09 12:21:57 2013 +0200 +++ b/Objects/unicodeobject.c Wed Jan 09 19:00:20 2013 +0200 @@ -2427,8 +2427,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; @@ -2439,10 +2437,10 @@ if (size == 0) return PyBytes_FromStringAndSize(NULL, 0); - if (allocated / 8 != size) + /* It might be possible to tighten this worst case */ + if (size > PY_SSIZE_T_MAX / 8) return PyErr_NoMemory(); - - v = PyBytes_FromStringAndSize(NULL, allocated); + v = PyBytes_FromStringAndSize(NULL, size * 8); if (v == NULL) return NULL; @@ -2940,9 +2938,9 @@ } else { /* Overallocate on the heap, and give the excess back at the end. */ + if (size > PY_SSIZE_T_MAX / 4) + return PyErr_NoMemory(); nallocated = size * 4; - if (nallocated / 4 != size) /* overflow! */ - return PyErr_NoMemory(); result = PyBytes_FromStringAndSize(NULL, nallocated); if (result == NULL) return NULL; @@ -3270,7 +3268,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 @@ -3301,10 +3299,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 = PyBytes_FromStringAndSize(NULL, bytesize); + v = PyBytes_FromStringAndSize(NULL, nsize * 4); if (v == NULL) return NULL; @@ -3659,7 +3656,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 @@ -3689,10 +3686,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 = PyBytes_FromStringAndSize(NULL, bytesize); + v = PyBytes_FromStringAndSize(NULL, nsize * 2); if (v == NULL) return NULL; @@ -7035,7 +7031,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 */ @@ -7048,18 +7044,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) @@ -8316,7 +8308,6 @@ PyUnicodeObject *u; Py_UNICODE *p; Py_ssize_t nchars; - size_t nbytes; if (len < 1) { Py_INCREF(unicode_empty); @@ -8332,18 +8323,12 @@ /* ensure # of chars needed doesn't overflow int and # of bytes * needed doesn't overflow size_t */ - nchars = len * str->length; - if (nchars / len != str->length) { + if (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;