summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorTim Peters <tim.peters@gmail.com>2000-09-09 06:13:41 (GMT)
committerTim Peters <tim.peters@gmail.com>2000-09-09 06:13:41 (GMT)
commit8f422461b4c19b8a66beae218311917e688f03ce (patch)
treeb6a577d50d437b8e2d388f5892fcd1f645d2c84c /Objects
parent643d76d735726352dd40433b663d48617e27e200 (diff)
downloadcpython-8f422461b4c19b8a66beae218311917e688f03ce.zip
cpython-8f422461b4c19b8a66beae218311917e688f03ce.tar.gz
cpython-8f422461b4c19b8a66beae218311917e688f03ce.tar.bz2
Fix for bug 113934. string*n and unicode*n did no overflow checking at
all, either to see whether the # of chars fit in an int, or that the amount of memory needed fit in a size_t. Checking these is expensive, but the alternative is silently wrong answers (as in the bug report) or core dumps (which were easy to provoke using Unicode strings).
Diffstat (limited to 'Objects')
-rw-r--r--Objects/stringobject.c19
-rw-r--r--Objects/unicodeobject.c21
2 files changed, 36 insertions, 4 deletions
diff --git a/Objects/stringobject.c b/Objects/stringobject.c
index f7c3f4b..eee3551 100644
--- a/Objects/stringobject.c
+++ b/Objects/stringobject.c
@@ -393,16 +393,31 @@ string_repeat(register PyStringObject *a, register int n)
register int i;
register int size;
register PyStringObject *op;
+ size_t nbytes;
if (n < 0)
n = 0;
+ /* watch out for overflows: the size can overflow int,
+ * and the # of bytes needed can overflow size_t
+ */
size = a->ob_size * n;
+ if (n && size / n != a->ob_size) {
+ PyErr_SetString(PyExc_OverflowError,
+ "repeated string is too long");
+ return NULL;
+ }
if (size == a->ob_size) {
Py_INCREF(a);
return (PyObject *)a;
}
- /* PyObject_NewVar is inlined */
+ nbytes = size * sizeof(char);
+ if (nbytes / sizeof(char) != (size_t)size ||
+ nbytes + sizeof(PyStringObject) <= nbytes) {
+ PyErr_SetString(PyExc_OverflowError,
+ "repeated string is too long");
+ return NULL;
+ }
op = (PyStringObject *)
- PyObject_MALLOC(sizeof(PyStringObject) + size * sizeof(char));
+ PyObject_MALLOC(sizeof(PyStringObject) + nbytes);
if (op == NULL)
return PyErr_NoMemory();
PyObject_INIT_VAR(op, &PyString_Type, size);
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 8ed6380..76bb92a 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -3993,6 +3993,8 @@ unicode_repeat(PyUnicodeObject *str, int len)
{
PyUnicodeObject *u;
Py_UNICODE *p;
+ int nchars;
+ size_t nbytes;
if (len < 0)
len = 0;
@@ -4002,8 +4004,23 @@ unicode_repeat(PyUnicodeObject *str, int len)
Py_INCREF(str);
return (PyObject*) str;
}
-
- u = _PyUnicode_New(len * str->length);
+
+ /* ensure # of chars needed doesn't overflow int and # of bytes
+ * needed doesn't overflow size_t
+ */
+ nchars = len * str->length;
+ if (len && nchars / len != str->length) {
+ PyErr_SetString(PyExc_OverflowError,
+ "repeated string is too long");
+ return NULL;
+ }
+ nbytes = (nchars + 1) * sizeof(Py_UNICODE);
+ if (nbytes / sizeof(Py_UNICODE) != (size_t)(nchars + 1)) {
+ PyErr_SetString(PyExc_OverflowError,
+ "repeated string is too long");
+ return NULL;
+ }
+ u = _PyUnicode_New(nchars);
if (!u)
return NULL;