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/Objects/bufferobject.c b/Objects/bufferobject.c
index 86515ab..88c0e41 100644
--- a/Objects/bufferobject.c
+++ b/Objects/bufferobject.c
@@ -207,7 +207,10 @@
 				"size must be zero or positive");
 		return NULL;
 	}
-	/* XXX: check for overflow in multiply */
+	if (sizeof(*b) > PY_SSIZE_T_MAX - size) {
+		/* unlikely */
+		return PyErr_NoMemory();
+	}
 	/* Inline PyObject_New */
 	o = (PyObject *)PyObject_MALLOC(sizeof(*b) + size);
 	if ( o == NULL )
@@ -397,6 +400,8 @@
 	if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
 		return NULL;
 
+	assert(count <= PY_SIZE_MAX - size);
+
  	ob = PyString_FromStringAndSize(NULL, size + count);
 	if ( ob == NULL )
 		return NULL;
diff --git a/Objects/listobject.c b/Objects/listobject.c
index c1cacaf..9ec7b29 100644
--- a/Objects/listobject.c
+++ b/Objects/listobject.c
@@ -45,7 +45,16 @@
 	 * system realloc().
 	 * The growth pattern is:  0, 4, 8, 16, 25, 35, 46, 58, 72, 88, ...
 	 */
-	new_allocated = (newsize >> 3) + (newsize < 9 ? 3 : 6) + newsize;
+	new_allocated = (newsize >> 3) + (newsize < 9 ? 3 : 6);
+
+	/* check for integer overflow */
+	if (new_allocated > PY_SIZE_MAX - newsize) {
+		PyErr_NoMemory();
+		return -1;
+	} else {
+		new_allocated += newsize;
+	}
+
 	if (newsize == 0)
 		new_allocated = 0;
 	items = self->ob_item;
@@ -92,8 +101,9 @@
 		return NULL;
 	}
 	nbytes = size * sizeof(PyObject *);
-	/* Check for overflow */
-	if (nbytes / sizeof(PyObject *) != (size_t)size)
+	/* Check for overflow without an actual overflow,
+	 *  which can cause compiler to optimise out */
+	if (size > PY_SIZE_MAX / sizeof(PyObject *))
 		return PyErr_NoMemory();
 	if (num_free_lists) {
 		num_free_lists--;
@@ -1372,6 +1382,10 @@
 	 * we don't care what's in the block.
 	 */
 	merge_freemem(ms);
+	if (need > PY_SSIZE_T_MAX / sizeof(PyObject*)) {
+		PyErr_NoMemory();
+		return -1;
+	}
 	ms->a = (PyObject **)PyMem_Malloc(need * sizeof(PyObject*));
 	if (ms->a) {
 		ms->alloced = need;
@@ -2537,6 +2551,8 @@
 				step = -step;
 			}
 
+			assert(slicelength <= PY_SIZE_MAX / sizeof(PyObject*));
+
 			garbage = (PyObject**)
 				PyMem_MALLOC(slicelength*sizeof(PyObject*));
 			if (!garbage) {
diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c
index 840570e..03add6b 100644
--- a/Objects/obmalloc.c
+++ b/Objects/obmalloc.c
@@ -526,9 +526,9 @@
 		numarenas = maxarenas ? maxarenas << 1 : INITIAL_ARENA_OBJECTS;
 		if (numarenas <= maxarenas)
 			return NULL;	/* overflow */
-		nbytes = numarenas * sizeof(*arenas);
-		if (nbytes / sizeof(*arenas) != numarenas)
+		if (numarenas > PY_SIZE_MAX / sizeof(*arenas))
 			return NULL;	/* overflow */
+		nbytes = numarenas * sizeof(*arenas);
 		arenaobj = (struct arena_object *)realloc(arenas, nbytes);
 		if (arenaobj == NULL)
 			return NULL;