Commit 8f422461 authored by Tim Peters's avatar Tim Peters

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).
parent 643d76d7
......@@ -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);
......
......@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment