Closes release blocker #3627.

Merged revisions 65335 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk

TESTED=./python -E -tt ./Lib/test/regrtest.py -uall (both debug and opt)

........
  r65335 | neal.norwitz | 2008-07-31 10:17:14 -0700 (Thu, 31 Jul 2008) | 1 line

  Security patches from Apple:  prevent int overflow when allocating memory
........
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index c85a063..847b61d 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -311,6 +311,11 @@
         return unicode_empty;
     }
 
+    /* Ensure we won't overflow the size. */
+    if (length > ((PY_SSIZE_T_MAX / sizeof(Py_UNICODE)) - 1)) {
+        return (PyUnicodeObject *)PyErr_NoMemory();
+    }
+
     /* Unicode freelist & memory allocation */
     if (free_list) {
         unicode = free_list;
@@ -1860,6 +1865,9 @@
     if (size == 0)
        return PyBytes_FromStringAndSize(NULL, 0);
 
+    if (cbAllocated / 5 != size)
+        return PyErr_NoMemory();
+
     v = PyByteArray_FromStringAndSize(NULL, cbAllocated);
     if (v == NULL)
         return NULL;
@@ -2452,8 +2460,9 @@
 {
     PyObject *v, *result;
     unsigned char *p;
+    Py_ssize_t nsize, bytesize;
 #ifndef Py_UNICODE_WIDE
-    int i, pairs;
+    Py_ssize_t i, pairs;
 #else
     const int pairs = 0;
 #endif
@@ -2481,8 +2490,11 @@
 	    0xDC00 <= s[i+1] && s[i+1] <= 0xDFFF)
 	    pairs++;
 #endif
-    v = PyByteArray_FromStringAndSize(NULL,
-		  4 * (size - pairs + (byteorder == 0)));
+    nsize = (size - pairs + (byteorder == 0));
+    bytesize = nsize * 4;
+    if (bytesize / 4 != nsize)
+	return PyErr_NoMemory();
+    v = PyByteArray_FromStringAndSize(NULL, bytesize);
     if (v == NULL)
         return NULL;
 
@@ -2726,8 +2738,9 @@
 {
     PyObject *v, *result;
     unsigned char *p;
+    Py_ssize_t nsize, bytesize;
 #ifdef Py_UNICODE_WIDE
-    int i, pairs;
+    Py_ssize_t i, pairs;
 #else
     const int pairs = 0;
 #endif
@@ -2750,8 +2763,15 @@
 	if (s[i] >= 0x10000)
 	    pairs++;
 #endif
-    v = PyByteArray_FromStringAndSize(NULL,
-		  2 * (size + pairs + (byteorder == 0)));
+    /* 2 * (size + pairs + (byteorder == 0)) */
+    if (size > PY_SSIZE_T_MAX ||
+        size > PY_SSIZE_T_MAX - pairs - (byteorder == 0))
+	return PyErr_NoMemory();
+    nsize = size + pairs + (byteorder == 0);
+    bytesize = nsize * 2;
+    if (bytesize / 2 != nsize)
+	return PyErr_NoMemory();
+    v = PyByteArray_FromStringAndSize(NULL, bytesize);
     if (v == NULL)
         return NULL;
 
@@ -3082,6 +3102,12 @@
     PyObject *repr, *result;
     char *p;
 
+#ifdef Py_UNICODE_WIDE
+    const Py_ssize_t expandsize = 10;
+#else
+    const Py_ssize_t expandsize = 6;
+#endif
+
     /* XXX(nnorwitz): rather than over-allocating, it would be
        better to choose a different scheme.  Perhaps scan the
        first N-chars of the string and allocate based on that size.
@@ -3100,12 +3126,12 @@
        escape.
     */
 
+    if (size > (PY_SSIZE_T_MAX - 2 - 1) / expandsize)
+	return PyErr_NoMemory();
+
     repr = PyByteArray_FromStringAndSize(NULL,
-#ifdef Py_UNICODE_WIDE
-        + 10*size
-#else
-        + 6*size
-#endif
+        2
+        + expandsize*size
         + 1);
     if (repr == NULL)
         return NULL;
@@ -3353,10 +3379,15 @@
     char *q;
 
 #ifdef Py_UNICODE_WIDE
-    repr = PyByteArray_FromStringAndSize(NULL, 10 * size);
+    const Py_ssize_t expandsize = 10;
 #else
-    repr = PyByteArray_FromStringAndSize(NULL, 6 * size);
+    const Py_ssize_t expandsize = 6;
 #endif
+    
+    if (size > PY_SSIZE_T_MAX / expandsize)
+	return PyErr_NoMemory();
+    
+    repr = PyByteArray_FromStringAndSize(NULL, expandsize * size);
     if (repr == NULL)
         return NULL;
     if (size == 0)
@@ -5747,6 +5778,11 @@
         return self;
     }
 
+    if (left > PY_SSIZE_T_MAX - self->length ||
+        right > PY_SSIZE_T_MAX - (left + self->length)) {
+        PyErr_SetString(PyExc_OverflowError, "padded string is too long");
+        return NULL;
+    }
     u = _PyUnicode_New(left + self->length + right);
     if (u) {
         if (left)