Added checks for integer overflows, contributed by Google. Some are
only available if asserts are left in the code, in cases where they
can't be triggered from Python code.
diff --git a/Modules/_csv.c b/Modules/_csv.c
index 5e03635..2cd9199 100644
--- a/Modules/_csv.c
+++ b/Modules/_csv.c
@@ -560,6 +560,10 @@
 		self->field = PyMem_Malloc(self->field_size);
 	}
 	else {
+		if (self->field_size > INT_MAX / 2) {
+			PyErr_NoMemory();
+			return 0;
+		} 
 		self->field_size *= 2;
 		self->field = PyMem_Realloc(self->field, self->field_size);
 	}
@@ -1055,6 +1059,12 @@
 static int
 join_check_rec_size(WriterObj *self, int rec_len)
 {
+
+	if (rec_len < 0 || rec_len > INT_MAX - MEM_INCR) {
+		PyErr_NoMemory();
+		return 0;
+	}
+
 	if (rec_len > self->rec_size) {
 		if (self->rec_size == 0) {
 			self->rec_size = (rec_len / MEM_INCR + 1) * MEM_INCR;
diff --git a/Modules/_struct.c b/Modules/_struct.c
index 53c6484..41183fa 100644
--- a/Modules/_struct.c
+++ b/Modules/_struct.c
@@ -1336,6 +1336,12 @@
 		}
 	}
 
+	/* check for overflow */
+	if ((len + 1) > (PY_SSIZE_T_MAX / sizeof(formatcode))) {
+		PyErr_NoMemory();
+		return -1;
+	}
+
 	self->s_size = size;
 	self->s_len = len;
 	codes = PyMem_MALLOC((len + 1) * sizeof(formatcode));
diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c
index 3ba5cf8..da6e88f 100644
--- a/Modules/arraymodule.c
+++ b/Modules/arraymodule.c
@@ -652,6 +652,9 @@
 		PyErr_BadArgument();
 		return NULL;
 	}
+	if (a->ob_size > PY_SSIZE_T_MAX - b->ob_size) {
+		return PyErr_NoMemory();
+	}
 	size = a->ob_size + b->ob_size;
 	np = (arrayobject *) newarrayobject(&Arraytype, size, a->ob_descr);
 	if (np == NULL) {
@@ -674,6 +677,9 @@
 	Py_ssize_t nbytes;
 	if (n < 0)
 		n = 0;
+	if ((a->ob_size != 0) && (n > PY_SSIZE_T_MAX / a->ob_size)) {
+		return PyErr_NoMemory();
+	}
 	size = a->ob_size * n;
 	np = (arrayobject *) newarrayobject(&Arraytype, size, a->ob_descr);
 	if (np == NULL)
@@ -818,6 +824,11 @@
 			     "can only extend with array of same kind");
 		return -1;
 	}
+	if ((self->ob_size > PY_SSIZE_T_MAX - b->ob_size) ||
+		((self->ob_size + b->ob_size) > PY_SSIZE_T_MAX / self->ob_descr->itemsize)) {
+			PyErr_NoMemory();
+			return -1;
+	}
 	size = self->ob_size + b->ob_size;
         PyMem_RESIZE(self->ob_item, char, size*self->ob_descr->itemsize);
         if (self->ob_item == NULL) {
@@ -859,6 +870,10 @@
 		if (n < 0)
 			n = 0;
 		items = self->ob_item;
+		if ((self->ob_descr->itemsize != 0) && 
+			(self->ob_size > PY_SSIZE_T_MAX / self->ob_descr->itemsize)) {
+			return PyErr_NoMemory();
+		}
 		size = self->ob_size * self->ob_descr->itemsize;
 		if (n == 0) {
 			PyMem_FREE(items);
@@ -867,6 +882,9 @@
 			self->allocated = 0;
 		}
 		else {
+			if (size > PY_SSIZE_T_MAX / n) {
+				return PyErr_NoMemory();
+			}
 			PyMem_Resize(items, char, n * size);
 			if (items == NULL)
 				return PyErr_NoMemory();
@@ -1148,6 +1166,10 @@
 		Py_INCREF(dict);
 	}
 	if (array->ob_size > 0) {
+		if (array->ob_descr->itemsize 
+				> PY_SSIZE_T_MAX / array->ob_size) {
+			return PyErr_NoMemory();
+		}
 		result = Py_BuildValue("O(cs#)O", 
 			array->ob_type, 
 			array->ob_descr->typecode,
@@ -1310,6 +1332,9 @@
 			if ((*self->ob_descr->setitem)(self,
 					self->ob_size - n + i, v) != 0) {
 				self->ob_size -= n;
+				if (itemsize && (self->ob_size > PY_SSIZE_T_MAX / itemsize)) {
+					return PyErr_NoMemory();
+				}
 				PyMem_RESIZE(item, char,
 					          self->ob_size * itemsize);
 				self->ob_item = item;
@@ -1369,6 +1394,10 @@
 	n = n / itemsize;
 	if (n > 0) {
 		char *item = self->ob_item;
+		if ((n > PY_SSIZE_T_MAX - self->ob_size) ||
+			((self->ob_size + n) > PY_SSIZE_T_MAX / itemsize)) {
+				return PyErr_NoMemory();
+		}
 		PyMem_RESIZE(item, char, (self->ob_size + n) * itemsize);
 		if (item == NULL) {
 			PyErr_NoMemory();
@@ -1394,8 +1423,12 @@
 static PyObject *
 array_tostring(arrayobject *self, PyObject *unused)
 {
-	return PyString_FromStringAndSize(self->ob_item,
+	if (self->ob_size <= PY_SSIZE_T_MAX / self->ob_descr->itemsize) {
+		return PyString_FromStringAndSize(self->ob_item,
 				    self->ob_size * self->ob_descr->itemsize);
+	} else {
+		return PyErr_NoMemory();
+	}
 }
 
 PyDoc_STRVAR(tostring_doc,
@@ -1423,6 +1456,9 @@
 	}
 	if (n > 0) {
 		Py_UNICODE *item = (Py_UNICODE *) self->ob_item;
+		if (self->ob_size > PY_SSIZE_T_MAX - n) {
+			return PyErr_NoMemory();
+		}
 		PyMem_RESIZE(item, Py_UNICODE, self->ob_size + n);
 		if (item == NULL) {
 			PyErr_NoMemory();
diff --git a/Modules/audioop.c b/Modules/audioop.c
index 8f5d30c..04355c1 100644
--- a/Modules/audioop.c
+++ b/Modules/audioop.c
@@ -824,7 +824,7 @@
 audioop_tostereo(PyObject *self, PyObject *args)
 {
         signed char *cp, *ncp;
-        int len, size, val1, val2, val = 0;
+        int len, new_len, size, val1, val2, val = 0;
         double fac1, fac2, fval, maxval;
         PyObject *rv;
         int i;
@@ -841,7 +841,14 @@
                 return 0;
         }
     
-        rv = PyString_FromStringAndSize(NULL, len*2);
+        new_len = len*2;
+        if (new_len < 0) {
+                PyErr_SetString(PyExc_MemoryError,
+                                "not enough memory for output buffer");
+                return 0;
+        }
+
+        rv = PyString_FromStringAndSize(NULL, new_len);
         if ( rv == 0 )
                 return 0;
         ncp = (signed char *)PyString_AsString(rv);
@@ -1004,7 +1011,7 @@
 {
         signed char *cp;
         unsigned char *ncp;
-        int len, size, size2, val = 0;
+        int len, new_len, size, size2, val = 0;
         PyObject *rv;
         int i, j;
 
@@ -1018,7 +1025,13 @@
                 return 0;
         }
     
-        rv = PyString_FromStringAndSize(NULL, (len/size)*size2);
+        new_len = (len/size)*size2;
+        if (new_len < 0) {
+                PyErr_SetString(PyExc_MemoryError,
+                                "not enough memory for output buffer");
+                return 0;
+        }
+        rv = PyString_FromStringAndSize(NULL, new_len);
         if ( rv == 0 )
                 return 0;
         ncp = (unsigned char *)PyString_AsString(rv);
@@ -1054,6 +1067,7 @@
         int chan, d, *prev_i, *cur_i, cur_o;
         PyObject *state, *samps, *str, *rv = NULL;
         int bytes_per_frame;
+        size_t alloc_size;
 
         weightA = 1;
         weightB = 0;
@@ -1096,8 +1110,14 @@
         inrate /= d;
         outrate /= d;
 
-        prev_i = (int *) malloc(nchannels * sizeof(int));
-        cur_i = (int *) malloc(nchannels * sizeof(int));
+        alloc_size = sizeof(int) * (unsigned)nchannels;
+        if (alloc_size < nchannels) {
+                PyErr_SetString(PyExc_MemoryError,
+                                "not enough memory for output buffer");
+                return 0;
+        }
+        prev_i = (int *) malloc(alloc_size);
+        cur_i = (int *) malloc(alloc_size);
         if (prev_i == NULL || cur_i == NULL) {
                 (void) PyErr_NoMemory();
                 goto exit;
@@ -1271,7 +1291,7 @@
         unsigned char *cp;
         unsigned char cval;
         signed char *ncp;
-        int len, size, val;
+        int len, new_len, size, val;
         PyObject *rv;
         int i;
 
@@ -1284,12 +1304,18 @@
                 return 0;
         }
     
-        rv = PyString_FromStringAndSize(NULL, len*size);
+        new_len = len*size;
+        if (new_len < 0) {
+                PyErr_SetString(PyExc_MemoryError,
+                                "not enough memory for output buffer");
+                return 0;
+        }
+        rv = PyString_FromStringAndSize(NULL, new_len);
         if ( rv == 0 )
                 return 0;
         ncp = (signed char *)PyString_AsString(rv);
     
-        for ( i=0; i < len*size; i += size ) {
+        for ( i=0; i < new_len; i += size ) {
                 cval = *cp++;
                 val = st_ulaw2linear16(cval);
         
@@ -1339,7 +1365,7 @@
         unsigned char *cp;
         unsigned char cval;
         signed char *ncp;
-        int len, size, val;
+        int len, new_len, size, val;
         PyObject *rv;
         int i;
 
@@ -1352,12 +1378,18 @@
                 return 0;
         }
     
-        rv = PyString_FromStringAndSize(NULL, len*size);
+        new_len = len*size;
+        if (new_len < 0) {
+                PyErr_SetString(PyExc_MemoryError,
+                                "not enough memory for output buffer");
+                return 0;
+        }
+        rv = PyString_FromStringAndSize(NULL, new_len);
         if ( rv == 0 )
                 return 0;
         ncp = (signed char *)PyString_AsString(rv);
     
-        for ( i=0; i < len*size; i += size ) {
+        for ( i=0; i < new_len; i += size ) {
                 cval = *cp++;
                 val = st_alaw2linear16(cval);
         
@@ -1482,7 +1514,7 @@
 {
         signed char *cp;
         signed char *ncp;
-        int len, size, valpred, step, delta, index, sign, vpdiff;
+        int len, new_len, size, valpred, step, delta, index, sign, vpdiff;
         PyObject *rv, *str, *state;
         int i, inputbuffer = 0, bufferstep;
 
@@ -1504,7 +1536,13 @@
         } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
                 return 0;
     
-        str = PyString_FromStringAndSize(NULL, len*size*2);
+        new_len = len*size*2;
+        if (new_len < 0) {
+                PyErr_SetString(PyExc_MemoryError,
+                                "not enough memory for output buffer");
+                return 0;
+        }
+        str = PyString_FromStringAndSize(NULL, new_len);
         if ( str == 0 )
                 return 0;
         ncp = (signed char *)PyString_AsString(str);
@@ -1512,7 +1550,7 @@
         step = stepsizeTable[index];
         bufferstep = 0;
     
-        for ( i=0; i < len*size*2; i += size ) {
+        for ( i=0; i < new_len; i += size ) {
                 /* Step 1 - get the delta value and compute next index */
                 if ( bufferstep ) {
                         delta = inputbuffer & 0xf;
diff --git a/Modules/binascii.c b/Modules/binascii.c
index 00f950d..fa22146 100644
--- a/Modules/binascii.c
+++ b/Modules/binascii.c
@@ -138,7 +138,7 @@
 #define BASE64_PAD '='
 
 /* Max binary chunk size; limited only by available memory */
-#define BASE64_MAXBIN (INT_MAX/2 - sizeof(PyStringObject) - 3)
+#define BASE64_MAXBIN (PY_SSIZE_T_MAX/2 - sizeof(PyStringObject) - 3)
 
 static unsigned char table_b2a_base64[] =
 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
@@ -195,6 +195,8 @@
 	if ( !PyArg_ParseTuple(args, "t#:a2b_uu", &ascii_data, &ascii_len) )
 		return NULL;
 
+	assert(ascii_len >= 0);
+
 	/* First byte: binary data length (in bytes) */
 	bin_len = (*ascii_data++ - ' ') & 077;
 	ascii_len--;
@@ -348,6 +350,11 @@
 	if ( !PyArg_ParseTuple(args, "t#:a2b_base64", &ascii_data, &ascii_len) )
 		return NULL;
 
+	assert(ascii_len >= 0);
+
+	if (ascii_len > PY_SSIZE_T_MAX - 3)
+		return PyErr_NoMemory();
+
 	bin_len = ((ascii_len+3)/4)*3; /* Upper bound, corrected later */
 
 	/* Allocate the buffer */
@@ -437,6 +444,9 @@
 
 	if ( !PyArg_ParseTuple(args, "s#:b2a_base64", &bin_data, &bin_len) )
 		return NULL;
+
+	assert(bin_len >= 0);
+
 	if ( bin_len > BASE64_MAXBIN ) {
 		PyErr_SetString(Error, "Too much data for base64 line");
 		return NULL;
@@ -492,6 +502,11 @@
 	if ( !PyArg_ParseTuple(args, "t#:a2b_hqx", &ascii_data, &len) )
 		return NULL;
 
+	assert(len >= 0);
+
+	if (len > PY_SSIZE_T_MAX - 2)
+		return PyErr_NoMemory();
+
 	/* Allocate a string that is too big (fixed later) 
 	   Add two to the initial length to prevent interning which
 	   would preclude subsequent resizing.  */
@@ -555,6 +570,11 @@
 	if ( !PyArg_ParseTuple(args, "s#:rlecode_hqx", &in_data, &len) )
 		return NULL;
 
+	assert(len >= 0);
+
+	if (len > PY_SSIZE_T_MAX / 2 - 2)
+		return PyErr_NoMemory();
+
 	/* Worst case: output is twice as big as input (fixed later) */
 	if ( (rv=PyString_FromStringAndSize(NULL, len*2+2)) == NULL )
 		return NULL;
@@ -604,6 +624,11 @@
 	if ( !PyArg_ParseTuple(args, "s#:b2a_hqx", &bin_data, &len) )
 		return NULL;
 
+	assert(len >= 0);
+
+	if (len > PY_SSIZE_T_MAX / 2 - 2)
+		return PyErr_NoMemory();
+
 	/* Allocate a buffer that is at least large enough */
 	if ( (rv=PyString_FromStringAndSize(NULL, len*2+2)) == NULL )
 		return NULL;
@@ -642,9 +667,13 @@
 	if ( !PyArg_ParseTuple(args, "s#:rledecode_hqx", &in_data, &in_len) )
 		return NULL;
 
+	assert(in_len >= 0);
+
 	/* Empty string is a special case */
 	if ( in_len == 0 )
 		return PyString_FromString("");
+    else if (in_len > PY_SSIZE_T_MAX / 2)
+        return PyErr_NoMemory();
 
 	/* Allocate a buffer of reasonable size. Resized when needed */
 	out_len = in_len*2;
@@ -670,6 +699,7 @@
 #define OUTBYTE(b) \
 	do { \
 		 if ( --out_len_left < 0 ) { \
+			  if ( out_len > PY_SSIZE_T_MAX / 2) return PyErr_NoMemory(); \
 			  _PyString_Resize(&rv, 2*out_len); \
 			  if ( rv == NULL ) return NULL; \
 			  out_data = (unsigned char *)PyString_AsString(rv) \
@@ -738,7 +768,7 @@
 	if ( !PyArg_ParseTuple(args, "s#i:crc_hqx", &bin_data, &len, &crc) )
 		return NULL;
 
-	while(len--) {
+	while(len-- > 0) {
 		crc=((crc<<8)&0xff00)^crctab_hqx[((crc>>8)&0xff)^*bin_data++];
 	}
 
@@ -882,7 +912,7 @@
 	/* only want the trailing 32 bits */
 	crc &= 0xFFFFFFFFUL;
 #endif
-	while (len--)
+	while (len-- > 0)
 		crc = crc_32_tab[(crc ^ *bin_data++) & 0xffUL] ^ (crc >> 8);
 		/* Note:  (crc >> 8) MUST zero fill on left */
 
@@ -912,6 +942,10 @@
 	if (!PyArg_ParseTuple(args, "s#:b2a_hex", &argbuf, &arglen))
 		return NULL;
 
+	assert(arglen >= 0);
+	if (arglen > PY_SSIZE_T_MAX / 2)
+		return PyErr_NoMemory();
+
 	retval = PyString_FromStringAndSize(NULL, arglen*2);
 	if (!retval)
 		return NULL;
@@ -969,6 +1003,8 @@
 	if (!PyArg_ParseTuple(args, "s#:a2b_hex", &argbuf, &arglen))
 		return NULL;
 
+	assert(arglen >= 0);
+
 	/* XXX What should we do about strings with an odd length?  Should
 	 * we add an implicit leading zero, or a trailing zero?  For now,
 	 * raise an exception.
diff --git a/Modules/cPickle.c b/Modules/cPickle.c
index b552a40..537276c 100644
--- a/Modules/cPickle.c
+++ b/Modules/cPickle.c
@@ -3432,6 +3432,14 @@
 	if (self->read_func(self, &s, 4) < 0) return -1;
 
 	l = calc_binint(s, 4);
+	if (l < 0) {
+		/* Corrupt or hostile pickle -- we never write one like
+		 * this.
+		 */
+		PyErr_SetString(UnpicklingError,
+				"BINSTRING pickle has negative byte count");
+		return -1;
+	}
 
 	if (self->read_func(self, &s, l) < 0)
 		return -1;
@@ -3499,6 +3507,14 @@
 	if (self->read_func(self, &s, 4) < 0) return -1;
 
 	l = calc_binint(s, 4);
+	if (l < 0) {
+		/* Corrupt or hostile pickle -- we never write one like
+		 * this.
+		 */
+		PyErr_SetString(UnpicklingError,
+				"BINUNICODE pickle has negative byte count");
+		return -1;
+	}
 
 	if (self->read_func(self, &s, l) < 0)
 		return -1;
diff --git a/Modules/cStringIO.c b/Modules/cStringIO.c
index a6fad9c..8fbb4f9 100644
--- a/Modules/cStringIO.c
+++ b/Modules/cStringIO.c
@@ -119,6 +119,7 @@
 static PyObject *
 IO_cgetval(PyObject *self) {
         if (!IO__opencheck(IOOOBJECT(self))) return NULL;
+        assert(IOOOBJECT(self)->pos >= 0);
         return PyString_FromStringAndSize(((IOobject*)self)->buf,
                                           ((IOobject*)self)->pos);
 }
@@ -137,6 +138,7 @@
         }
         else
                   s=self->string_size;
+        assert(self->pos >= 0);
         return PyString_FromStringAndSize(self->buf, s);
 }
 
@@ -157,6 +159,8 @@
         Py_ssize_t l;
 
         if (!IO__opencheck(IOOOBJECT(self))) return -1;
+        assert(IOOOBJECT(self)->pos >= 0);
+        assert(IOOOBJECT(self)->string_size >= 0);
         l = ((IOobject*)self)->string_size - ((IOobject*)self)->pos;  
         if (n < 0 || n > l) {
                 n = l;
@@ -192,12 +196,17 @@
         for (n = ((IOobject*)self)->buf + ((IOobject*)self)->pos,
                s = ((IOobject*)self)->buf + ((IOobject*)self)->string_size; 
              n < s && *n != '\n'; n++);
+
         if (n < s) n++;
 
         *output=((IOobject*)self)->buf + ((IOobject*)self)->pos;
         l = n - ((IOobject*)self)->buf - ((IOobject*)self)->pos;
-	assert(((IOobject*)self)->pos + l < INT_MAX);
-        ((IOobject*)self)->pos += (int)l;
+
+        assert(IOOOBJECT(self)->pos <= PY_SSIZE_T_MAX - l);
+        assert(IOOOBJECT(self)->pos >= 0);
+        assert(IOOOBJECT(self)->string_size >= 0);
+
+        ((IOobject*)self)->pos += l;
         return (int)l;
 }
 
@@ -215,6 +224,7 @@
                 n -= m;
                 self->pos -= m;
         }
+        assert(IOOOBJECT(self)->pos >= 0);
         return PyString_FromStringAndSize(output, n);
 }
 
@@ -277,6 +287,7 @@
 
         if (!IO__opencheck(self)) return NULL;
 
+        assert(self->pos >= 0);
         return PyInt_FromSsize_t(self->pos);
 }
 
diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c
index 9fb9570..8a2b660 100644
--- a/Modules/cjkcodecs/multibytecodec.c
+++ b/Modules/cjkcodecs/multibytecodec.c
@@ -163,13 +163,17 @@
 static int
 expand_encodebuffer(MultibyteEncodeBuffer *buf, Py_ssize_t esize)
 {
-	Py_ssize_t orgpos, orgsize;
+	Py_ssize_t orgpos, orgsize, incsize;
 
 	orgpos = (Py_ssize_t)((char *)buf->outbuf -
 				PyString_AS_STRING(buf->outobj));
 	orgsize = PyString_GET_SIZE(buf->outobj);
-	if (_PyString_Resize(&buf->outobj, orgsize + (
-	    esize < (orgsize >> 1) ? (orgsize >> 1) | 1 : esize)) == -1)
+	incsize = (esize < (orgsize >> 1) ? (orgsize >> 1) | 1 : esize);
+
+	if (orgsize > PY_SSIZE_T_MAX - incsize)
+		return -1;
+
+	if (_PyString_Resize(&buf->outobj, orgsize + incsize) == -1)
 		return -1;
 
 	buf->outbuf = (unsigned char *)PyString_AS_STRING(buf->outobj) +orgpos;
@@ -473,6 +477,12 @@
 	buf.excobj = NULL;
 	buf.inbuf = buf.inbuf_top = *data;
 	buf.inbuf_end = buf.inbuf_top + datalen;
+
+	if (datalen > (PY_SSIZE_T_MAX - 16) / 2) {
+		PyErr_NoMemory();
+		goto errorexit;
+	}
+
 	buf.outobj = PyString_FromStringAndSize(NULL, datalen * 2 + 16);
 	if (buf.outobj == NULL)
 		goto errorexit;
@@ -736,6 +746,11 @@
 	origpending = ctx->pendingsize;
 
 	if (origpending > 0) {
+		if (datalen > PY_SSIZE_T_MAX - ctx->pendingsize) {
+			PyErr_NoMemory();
+			/* inbuf_tmp == NULL */
+			goto errorexit;
+		}
 		inbuf_tmp = PyMem_New(Py_UNICODE, datalen + ctx->pendingsize);
 		if (inbuf_tmp == NULL)
 			goto errorexit;
@@ -798,9 +813,10 @@
 	Py_ssize_t npendings;
 
 	npendings = (Py_ssize_t)(buf->inbuf_end - buf->inbuf);
-	if (npendings + ctx->pendingsize > MAXDECPENDING) {
-		PyErr_SetString(PyExc_UnicodeError, "pending buffer overflow");
-		return -1;
+	if (npendings + ctx->pendingsize > MAXDECPENDING ||
+		npendings > PY_SSIZE_T_MAX - ctx->pendingsize) {
+			PyErr_SetString(PyExc_UnicodeError, "pending buffer overflow");
+			return -1;
 	}
 	memcpy(ctx->pending + ctx->pendingsize, buf->inbuf, npendings);
 	ctx->pendingsize += npendings;
@@ -1003,7 +1019,7 @@
 		  PyObject *args, PyObject *kwargs)
 {
 	MultibyteDecodeBuffer buf;
-	char *data, *wdata;
+	char *data, *wdata = NULL;
 	Py_ssize_t wsize, finalsize = 0, size, origpending;
 	int final = 0;
 
@@ -1019,6 +1035,10 @@
 		wdata = data;
 	}
 	else {
+		if (size > PY_SSIZE_T_MAX - self->pendingsize) {
+			PyErr_NoMemory();
+			goto errorexit;
+		}
 		wsize = size + self->pendingsize;
 		wdata = PyMem_Malloc(wsize);
 		if (wdata == NULL)
@@ -1238,6 +1258,10 @@
 			PyObject *ctr;
 			char *ctrdata;
 
+			if (PyString_GET_SIZE(cres) > PY_SSIZE_T_MAX - self->pendingsize) {
+				PyErr_NoMemory();
+				goto errorexit;
+            }
 			rsize = PyString_GET_SIZE(cres) + self->pendingsize;
 			ctr = PyString_FromStringAndSize(NULL, rsize);
 			if (ctr == NULL)
diff --git a/Modules/datetimemodule.c b/Modules/datetimemodule.c
index a67c35d..34112c0 100644
--- a/Modules/datetimemodule.c
+++ b/Modules/datetimemodule.c
@@ -1113,6 +1113,8 @@
 	char sign;
 	int none;
 
+	assert(buflen >= 1);
+
 	offset = call_utcoffset(tzinfo, tzinfoarg, &none);
 	if (offset == -1 && PyErr_Occurred())
 		return -1;
@@ -1190,6 +1192,11 @@
 	 * a new format.  Since computing the replacements for those codes
 	 * is expensive, don't unless they're actually used.
 	 */
+	if (PyString_Size(format) > INT_MAX - 1) {
+		PyErr_NoMemory();
+		goto Done;
+	}
+
 	totalnew = PyString_Size(format) + 1;	/* realistic if no %z/%Z */
 	newfmt = PyString_FromStringAndSize(NULL, totalnew);
 	if (newfmt == NULL) goto Done;
diff --git a/Modules/md5.c b/Modules/md5.c
index c35d96c..0e1058f 100644
--- a/Modules/md5.c
+++ b/Modules/md5.c
@@ -53,6 +53,7 @@
 
 #include "md5.h"
 #include <string.h>
+#include <limits.h>
 
 #undef BYTE_ORDER	/* 1 = big-endian, -1 = little-endian, 0 = unknown */
 #ifdef ARCH_IS_BIG_ENDIAN
@@ -330,6 +331,18 @@
     if (nbytes <= 0)
 	return;
 
+    /* this special case is handled recursively */
+    if (nbytes > INT_MAX - offset) {
+        int overlap;
+
+        /* handle the append in two steps to prevent overflow */
+        overlap = 64 - offset;
+
+        md5_append(pms, data, overlap);
+        md5_append(pms, data + overlap, nbytes - overlap); 
+        return;
+    }
+
     /* Update the message length. */
     pms->count[1] += nbytes >> 29;
     pms->count[0] += nbits;
diff --git a/Modules/rgbimgmodule.c b/Modules/rgbimgmodule.c
index 0f9ee71..3eb2f55 100644
--- a/Modules/rgbimgmodule.c
+++ b/Modules/rgbimgmodule.c
@@ -269,7 +269,7 @@
 	Py_Int32 *starttab = NULL, *lengthtab = NULL;
 	FILE *inf = NULL;
 	IMAGE image;
-	int y, z, tablen;
+	int y, z, tablen, new_size;
 	int xsize, ysize, zsize;
 	int bpp, rle, cur, badorder;
 	int rlebuflen;
@@ -301,9 +301,15 @@
 	zsize = image.zsize;
 	if (rle) {
 		tablen = ysize * zsize * sizeof(Py_Int32);
+		rlebuflen = (int) (1.05 * xsize +10);
+		if ((tablen / sizeof(Py_Int32)) != (ysize * zsize) ||
+		    rlebuflen < 0) {
+			PyErr_NoMemory();
+			goto finally;
+		}
+
 		starttab = (Py_Int32 *)malloc(tablen);
 		lengthtab = (Py_Int32 *)malloc(tablen);
-		rlebuflen = (int) (1.05 * xsize +10);
 		rledat = (unsigned char *)malloc(rlebuflen);
 		if (!starttab || !lengthtab || !rledat) {
 			PyErr_NoMemory();
@@ -331,8 +337,14 @@
 
 		fseek(inf, 512 + 2 * tablen, SEEK_SET);
 		cur = 512 + 2 * tablen;
+		new_size = xsize * ysize + TAGLEN;
+		if (new_size < 0 || (new_size * sizeof(Py_Int32)) < 0) {
+			PyErr_NoMemory();
+			goto finally;
+		}
+
 		rv = PyString_FromStringAndSize((char *)NULL,
-				      (xsize * ysize + TAGLEN) * sizeof(Py_Int32));
+				      new_size * sizeof(Py_Int32));
 		if (rv == NULL)
 			goto finally;
 
@@ -400,8 +412,14 @@
 			copybw((Py_Int32 *) base, xsize * ysize);
 	}
 	else {
+		new_size = xsize * ysize + TAGLEN;
+		if (new_size < 0 || (new_size * sizeof(Py_Int32)) < 0) {
+			PyErr_NoMemory();
+			goto finally;
+		}
+
 		rv = PyString_FromStringAndSize((char *) 0,
-					   (xsize*ysize+TAGLEN)*sizeof(Py_Int32));
+						new_size*sizeof(Py_Int32));
 		if (rv == NULL)
 			goto finally;
 
@@ -591,10 +609,16 @@
 		return NULL;
 	}
 	tablen = ysize * zsize * sizeof(Py_Int32);
+	rlebuflen = (int) (1.05 * xsize + 10);
+
+	if ((tablen / sizeof(Py_Int32)) != (ysize * zsize) ||
+	    rlebuflen < 0 || (xsize * sizeof(Py_Int32)) < 0) {
+		PyErr_NoMemory();
+		goto finally;
+	}
 
 	starttab = (Py_Int32 *)malloc(tablen);
 	lengthtab = (Py_Int32 *)malloc(tablen);
-	rlebuflen = (int) (1.05 * xsize + 10);
 	rlebuf = (unsigned char *)malloc(rlebuflen);
 	lumbuf = (unsigned char *)malloc(xsize * sizeof(Py_Int32));
 	if (!starttab || !lengthtab || !rlebuf || !lumbuf) {
diff --git a/Modules/stropmodule.c b/Modules/stropmodule.c
index 8b00fed..bc60959 100644
--- a/Modules/stropmodule.c
+++ b/Modules/stropmodule.c
@@ -578,7 +578,7 @@
 	char* e;
 	char* p;
 	char* q;
-	Py_ssize_t i, j;
+	Py_ssize_t i, j, old_j;
 	PyObject* out;
 	char* string;
 	Py_ssize_t stringlen;
@@ -595,12 +595,18 @@
 	}
 
 	/* First pass: determine size of output string */
-	i = j = 0; /* j: current column; i: total of previous lines */
+	i = j = old_j = 0; /* j: current column; i: total of previous lines */
 	e = string + stringlen;
 	for (p = string; p < e; p++) {
-		if (*p == '\t')
+		if (*p == '\t') {
 			j += tabsize - (j%tabsize);
-		else {
+			if (old_j > j) {
+				PyErr_SetString(PyExc_OverflowError,
+						"new string is too long");
+				return NULL;
+			}
+			old_j = j;
+		} else {
 			j++;
 			if (*p == '\n') {
 				i += j;
@@ -609,6 +615,11 @@
 		}
 	}
 
+	if ((i + j) < 0) {
+		PyErr_SetString(PyExc_OverflowError, "new string is too long");
+		return NULL;
+	}
+
 	/* Second pass: create output string and fill it */
 	out = PyString_FromStringAndSize(NULL, i+j);
 	if (out == NULL)