diff options
author | Neal Norwitz <nnorwitz@gmail.com> | 2008-08-24 07:08:55 (GMT) |
---|---|---|
committer | Neal Norwitz <nnorwitz@gmail.com> | 2008-08-24 07:08:55 (GMT) |
commit | 3ce5d9207e66d61d4b0502cf47ed2d2bcdd2212f (patch) | |
tree | c29add3a6b61f321009d73a91464f45b5d10862a /Objects/unicodeobject.c | |
parent | 06db799a53cba0396908d291bbe4bcc6c1c50daa (diff) | |
download | cpython-3ce5d9207e66d61d4b0502cf47ed2d2bcdd2212f.zip cpython-3ce5d9207e66d61d4b0502cf47ed2d2bcdd2212f.tar.gz cpython-3ce5d9207e66d61d4b0502cf47ed2d2bcdd2212f.tar.bz2 |
Closes release blocker #3627.
Merged revisions 65335 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
TESTED=./python -E -tt ./Lib/test/regrtest.py -uall (both debug and opt)
........
r65335 | neal.norwitz | 2008-07-31 10:17:14 -0700 (Thu, 31 Jul 2008) | 1 line
Security patches from Apple: prevent int overflow when allocating memory
........
Diffstat (limited to 'Objects/unicodeobject.c')
-rw-r--r-- | Objects/unicodeobject.c | 62 |
1 files changed, 49 insertions, 13 deletions
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index c85a063..847b61d 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -311,6 +311,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 (free_list) { unicode = free_list; @@ -1860,6 +1865,9 @@ PyObject *PyUnicode_EncodeUTF7(const Py_UNICODE *s, if (size == 0) return PyBytes_FromStringAndSize(NULL, 0); + if (cbAllocated / 5 != size) + return PyErr_NoMemory(); + v = PyByteArray_FromStringAndSize(NULL, cbAllocated); if (v == NULL) return NULL; @@ -2452,8 +2460,9 @@ PyUnicode_EncodeUTF32(const Py_UNICODE *s, { PyObject *v, *result; unsigned char *p; + Py_ssize_t nsize, bytesize; #ifndef Py_UNICODE_WIDE - int i, pairs; + Py_ssize_t i, pairs; #else const int pairs = 0; #endif @@ -2481,8 +2490,11 @@ PyUnicode_EncodeUTF32(const Py_UNICODE *s, 0xDC00 <= s[i+1] && s[i+1] <= 0xDFFF) pairs++; #endif - v = PyByteArray_FromStringAndSize(NULL, - 4 * (size - pairs + (byteorder == 0))); + nsize = (size - pairs + (byteorder == 0)); + bytesize = nsize * 4; + if (bytesize / 4 != nsize) + return PyErr_NoMemory(); + v = PyByteArray_FromStringAndSize(NULL, bytesize); if (v == NULL) return NULL; @@ -2726,8 +2738,9 @@ PyUnicode_EncodeUTF16(const Py_UNICODE *s, { PyObject *v, *result; 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 @@ -2750,8 +2763,15 @@ PyUnicode_EncodeUTF16(const Py_UNICODE *s, if (s[i] >= 0x10000) pairs++; #endif - v = PyByteArray_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 = PyByteArray_FromStringAndSize(NULL, bytesize); if (v == NULL) return NULL; @@ -3082,6 +3102,12 @@ PyObject *PyUnicode_EncodeUnicodeEscape(const Py_UNICODE *s, PyObject *repr, *result; char *p; +#ifdef Py_UNICODE_WIDE + const Py_ssize_t expandsize = 10; +#else + const Py_ssize_t expandsize = 6; +#endif + /* XXX(nnorwitz): rather than over-allocating, it would be better to choose a different scheme. Perhaps scan the first N-chars of the string and allocate based on that size. @@ -3100,12 +3126,12 @@ PyObject *PyUnicode_EncodeUnicodeEscape(const Py_UNICODE *s, escape. */ + if (size > (PY_SSIZE_T_MAX - 2 - 1) / expandsize) + return PyErr_NoMemory(); + repr = PyByteArray_FromStringAndSize(NULL, -#ifdef Py_UNICODE_WIDE - + 10*size -#else - + 6*size -#endif + 2 + + expandsize*size + 1); if (repr == NULL) return NULL; @@ -3353,10 +3379,15 @@ PyObject *PyUnicode_EncodeRawUnicodeEscape(const Py_UNICODE *s, char *q; #ifdef Py_UNICODE_WIDE - repr = PyByteArray_FromStringAndSize(NULL, 10 * size); + const Py_ssize_t expandsize = 10; #else - repr = PyByteArray_FromStringAndSize(NULL, 6 * size); + const Py_ssize_t expandsize = 6; #endif + + if (size > PY_SSIZE_T_MAX / expandsize) + return PyErr_NoMemory(); + + repr = PyByteArray_FromStringAndSize(NULL, expandsize * size); if (repr == NULL) return NULL; if (size == 0) @@ -5747,6 +5778,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) |