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).
This commit is contained in:
Antoine Pitrou 2010-06-11 21:42:26 +00:00
parent c6660cf4d6
commit cca3a3f396
3 changed files with 50 additions and 19 deletions

View file

@ -2207,11 +2207,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. */
@ -2222,23 +2222,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;
@ -2290,6 +2274,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) */