$OpenBSD: patch-Objects_unicodeobject_c,v 1.1 2008/08/06 03:23:31 djm Exp $
--- Objects/unicodeobject.c.orig	Sat Nov  3 09:46:38 2007
+++ Objects/unicodeobject.c	Tue Aug  5 18:18:52 2008
@@ -239,6 +239,11 @@ PyUnicodeObject *_PyUnicode_New(Py_ssize_t length)
         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 (unicode_freelist) {
         unicode = unicode_freelist;
@@ -970,7 +975,7 @@ PyObject *PyUnicode_DecodeUTF7(const char *s,
     while (s < e) {
         Py_UNICODE ch;
         restart:
-        ch = *s;
+        ch = (unsigned char) *s;
 
         if (inShift) {
             if ((ch == '-') || !B64CHAR(ch)) {
@@ -1091,6 +1096,9 @@ PyObject *PyUnicode_EncodeUTF7(const Py_UNICODE *s,
     char * out;
     char * start;
 
+    if (cbAllocated / 5 != size)
+        return PyErr_NoMemory();
+
     if (size == 0)
 		return PyString_FromStringAndSize(NULL, 0);
 
@@ -1689,8 +1697,9 @@ PyUnicode_EncodeUTF16(const Py_UNICODE *s,
 {
     PyObject *v;
     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
@@ -1713,8 +1722,15 @@ PyUnicode_EncodeUTF16(const Py_UNICODE *s,
 	if (s[i] >= 0x10000)
 	    pairs++;
 #endif
-    v = PyString_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 = PyString_FromStringAndSize(NULL, bytesize);
     if (v == NULL)
         return NULL;
 
@@ -2042,6 +2058,11 @@ PyObject *unicodeescape_string(const Py_UNICODE *s,
     char *p;
 
     static const char *hexdigit = "0123456789abcdef";
+#ifdef Py_UNICODE_WIDE
+    const Py_ssize_t expandsize = 10;
+#else
+    const Py_ssize_t expandsize = 6;
+#endif
 
     /* Initial allocation is based on the longest-possible unichr
        escape.
@@ -2057,13 +2078,12 @@ PyObject *unicodeescape_string(const Py_UNICODE *s,
        escape.
     */
 
+    if (size > (PY_SSIZE_T_MAX - 2 - 1) / expandsize)
+	return PyErr_NoMemory();
+
     repr = PyString_FromStringAndSize(NULL,
         2
-#ifdef Py_UNICODE_WIDE
-        + 10*size
-#else
-        + 6*size
-#endif
+        + expandsize*size
         + 1);
     if (repr == NULL)
         return NULL;
@@ -2304,12 +2324,16 @@ PyObject *PyUnicode_EncodeRawUnicodeEscape(const Py_UN
     char *q;
 
     static const char *hexdigit = "0123456789abcdef";
-
 #ifdef Py_UNICODE_WIDE
-    repr = PyString_FromStringAndSize(NULL, 10 * size);
+    const Py_ssize_t expandsize = 10;
 #else
-    repr = PyString_FromStringAndSize(NULL, 6 * size);
+    const Py_ssize_t expandsize = 6;
 #endif
+    
+    if (size > PY_SSIZE_T_MAX / expandsize)
+	return PyErr_NoMemory();
+    
+    repr = PyString_FromStringAndSize(NULL, expandsize * size);
     if (repr == NULL)
         return NULL;
     if (size == 0)
@@ -4719,6 +4743,11 @@ PyUnicodeObject *pad(PyUnicodeObject *self,
         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)
