$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();