From: Jeremy Hylton Date: Wed, 17 Sep 2003 03:32:41 +0000 (+0000) Subject: Backport: Double-fix of crash in Unicode freelist handling. X-Git-Tag: 2.2~14 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=886849a282e8eb337997b1f8e8757dfcd709e84f;p=thirdparty%2FPython%2Fcpython.git Backport: Double-fix of crash in Unicode freelist handling. --- diff --git a/Misc/NEWS b/Misc/NEWS index 1bffad04dd91..ecf9f45e2cee 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -2,6 +2,11 @@ What's New in Python 2.2.4? Release date: XX-XXX-XXXX =========================== +- Fixed a bug in the cache of length-one Unicode strings that could + lead to a seg fault. The specific problem occurred when an earlier, + non-fatal error left an uninitialized Unicode object in the + freelist. + - The email package handles some RFC 2231 parameters with missing CHARSET fields better. It also includes a patch to parameter parsing when semicolons appear inside quotes. diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 7ebde3cb9349..6aa490cf8ac2 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -132,7 +132,12 @@ int unicode_resize(register PyUnicodeObject *unicode, instead ! */ if (unicode == unicode_empty || (unicode->length == 1 && - unicode->str[0] < 256 && + /* MvL said unicode->str[] may be signed. Python generally assumes + * an int contains at least 32 bits, and we don't use more than + * 32 bits even in a UCS4 build, so casting to unsigned int should + * be correct. + */ + (unsigned int)unicode->str[0] < 256U && unicode_latin1[unicode->str[0]] == unicode)) { PyErr_SetString(PyExc_SystemError, "can't resize shared unicode objects"); @@ -211,6 +216,14 @@ PyUnicodeObject *_PyUnicode_New(int length) PyErr_NoMemory(); goto onError; } + /* Initialize the first element to guard against cases where + * the caller fails before initializing str -- unicode_resize() + * reads str[0], and the Keep-Alive optimization can keep memory + * allocated for str alive across a call to unicode_dealloc(unicode). + * We don't want unicode_resize to read uninitialized memory in + * that case. + */ + unicode->str[0] = 0; unicode->str[length] = 0; unicode->length = length; unicode->hash = -1;