Security patches from Apple: prevent int overflow when allocating memory

This commit is contained in:
Neal Norwitz 2008-07-31 17:08:14 +00:00
parent 83ac0144fa
commit 4f3be8a0a9
13 changed files with 244 additions and 26 deletions

View file

@ -240,6 +240,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;
@ -1095,6 +1100,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);
@ -1693,8 +1701,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
@ -1717,8 +1726,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;
@ -2046,6 +2062,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.
@ -2061,13 +2082,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;
@ -2320,12 +2340,16 @@ PyObject *PyUnicode_EncodeRawUnicodeEscape(const Py_UNICODE *s,
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)
@ -4761,6 +4785,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)