$OpenBSD: patch-Objects_stringobject_c,v 1.1 2008/08/06 03:23:31 djm Exp $
--- Objects/stringobject.c.orig	Wed Nov  7 12:19:49 2007
+++ Objects/stringobject.c	Tue Aug  5 18:18:52 2008
@@ -54,6 +54,11 @@ PyString_FromStringAndSize(const char *str, Py_ssize_t
 {
 	register PyStringObject *op;
 	assert(size >= 0);
+	if (size < 0) {
+		PyErr_SetString(PyExc_SystemError,
+		    "Negative size passed to PyString_FromStringAndSize");
+		return NULL;
+	}
 	if (size == 0 && (op = nullstring) != NULL) {
 #ifdef COUNT_ALLOCS
 		null_strings++;
@@ -71,6 +76,11 @@ PyString_FromStringAndSize(const char *str, Py_ssize_t
 		return (PyObject *)op;
 	}
 
+	if (size > PY_SSIZE_T_MAX - sizeof(PyStringObject)) {
+		PyErr_SetString(PyExc_OverflowError, "string is too large");
+		return NULL;
+	}
+
 	/* Inline PyObject_NewVar */
 	op = (PyStringObject *)PyObject_MALLOC(sizeof(PyStringObject) + size);
 	if (op == NULL)
@@ -106,7 +116,7 @@ PyString_FromString(const char *str)
 
 	assert(str != NULL);
 	size = strlen(str);
-	if (size > PY_SSIZE_T_MAX) {
+	if (size > PY_SSIZE_T_MAX - sizeof(PyStringObject)) {
 		PyErr_SetString(PyExc_OverflowError,
 			"string is too long for a Python string");
 		return NULL;
@@ -967,14 +977,24 @@ string_concat(register PyStringObject *a, register PyO
 		Py_INCREF(a);
 		return (PyObject *)a;
 	}
+	/* Check that string sizes are not negative, to prevent an
+	   overflow in cases where we are passed incorrectly-created
+	   strings with negative lengths (due to a bug in other code).
+	*/
 	size = a->ob_size + b->ob_size;
-	if (size < 0) {
+	if (a->ob_size < 0 || b->ob_size < 0 ||
+	    a->ob_size > PY_SSIZE_T_MAX - b->ob_size) {
 		PyErr_SetString(PyExc_OverflowError,
 				"strings are too large to concat");
 		return NULL;
 	}
 	  
 	/* Inline PyObject_NewVar */
+	if (size > PY_SSIZE_T_MAX - sizeof(PyStringObject)) {
+		PyErr_SetString(PyExc_OverflowError,
+				"strings are too large to concat");
+		return NULL;
+	}
 	op = (PyStringObject *)PyObject_MALLOC(sizeof(PyStringObject) + size);
 	if (op == NULL)
 		return PyErr_NoMemory();
