diff options
author | Antoine Pitrou <solipsis@pitrou.net> | 2010-06-11 21:46:32 (GMT) |
---|---|---|
committer | Antoine Pitrou <solipsis@pitrou.net> | 2010-06-11 21:46:32 (GMT) |
commit | cc0cfd357611c69a99841f21affa73e829416789 (patch) | |
tree | e7c632a1e6fad23b9e40ea05e384a86c428468bd /Objects | |
parent | 0277555ff236b0b781657516d7cb8851adeae8bb (diff) | |
download | cpython-cc0cfd357611c69a99841f21affa73e829416789.zip cpython-cc0cfd357611c69a99841f21affa73e829416789.tar.gz cpython-cc0cfd357611c69a99841f21affa73e829416789.tar.bz2 |
Merged revisions 81907 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r81907 | antoine.pitrou | 2010-06-11 23:42:26 +0200 (ven., 11 juin 2010) | 5 lines
Issue #8941: decoding big endian UTF-32 data in UCS-2 builds could crash
the interpreter with characters outside the Basic Multilingual Plane
(higher than 0x10000).
........
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/unicodeobject.c | 40 |
1 files changed, 21 insertions, 19 deletions
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index aa0b4c6..de92787 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -2730,11 +2730,11 @@ PyUnicode_DecodeUTF32Stateful(const char *s, PyUnicodeObject *unicode; Py_UNICODE *p; #ifndef Py_UNICODE_WIDE - int i, pairs; + int pairs = 0; #else const int pairs = 0; #endif - const unsigned char *q, *e; + const unsigned char *q, *e, *qq; int bo = 0; /* assume native ordering by default */ const char *errmsg = ""; /* Offsets from q for retrieving bytes in the right order. */ @@ -2745,23 +2745,7 @@ PyUnicode_DecodeUTF32Stateful(const char *s, #endif PyObject *errorHandler = NULL; PyObject *exc = NULL; - /* On narrow builds we split characters outside the BMP into two - codepoints => count how much extra space we need. */ -#ifndef Py_UNICODE_WIDE - for (i = pairs = 0; i < size/4; i++) - if (((Py_UCS4 *)s)[i] >= 0x10000) - pairs++; -#endif - - /* This might be one to much, because of a BOM */ - unicode = _PyUnicode_New((size+3)/4+pairs); - if (!unicode) - return NULL; - if (size == 0) - return (PyObject *)unicode; - - /* Unpack UTF-32 encoded data */ - p = unicode->str; + q = (unsigned char *)s; e = q + size; @@ -2813,6 +2797,24 @@ PyUnicode_DecodeUTF32Stateful(const char *s, iorder[3] = 0; } + /* On narrow builds we split characters outside the BMP into two + codepoints => count how much extra space we need. */ +#ifndef Py_UNICODE_WIDE + for (qq = q; qq < e; qq += 4) + if (qq[iorder[2]] != 0 || qq[iorder[3]] != 0) + pairs++; +#endif + + /* This might be one to much, because of a BOM */ + unicode = _PyUnicode_New((size+3)/4+pairs); + if (!unicode) + return NULL; + if (size == 0) + return (PyObject *)unicode; + + /* Unpack UTF-32 encoded data */ + p = unicode->str; + while (q < e) { Py_UCS4 ch; /* remaining bytes at the end? (size should be divisible by 4) */ |