Skip to content

Commit 886849a

Browse files
committed
Backport: Double-fix of crash in Unicode freelist handling.
1 parent 1c3f4b8 commit 886849a

File tree

2 files changed

+19
-1
lines changed

2 files changed

+19
-1
lines changed

Misc/NEWS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ What's New in Python 2.2.4?
22
Release date: XX-XXX-XXXX
33
===========================
44

5+
- Fixed a bug in the cache of length-one Unicode strings that could
6+
lead to a seg fault. The specific problem occurred when an earlier,
7+
non-fatal error left an uninitialized Unicode object in the
8+
freelist.
9+
510
- The email package handles some RFC 2231 parameters with missing
611
CHARSET fields better. It also includes a patch to parameter
712
parsing when semicolons appear inside quotes.

Objects/unicodeobject.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,12 @@ int unicode_resize(register PyUnicodeObject *unicode,
132132
instead ! */
133133
if (unicode == unicode_empty ||
134134
(unicode->length == 1 &&
135-
unicode->str[0] < 256 &&
135+
/* MvL said unicode->str[] may be signed. Python generally assumes
136+
* an int contains at least 32 bits, and we don't use more than
137+
* 32 bits even in a UCS4 build, so casting to unsigned int should
138+
* be correct.
139+
*/
140+
(unsigned int)unicode->str[0] < 256U &&
136141
unicode_latin1[unicode->str[0]] == unicode)) {
137142
PyErr_SetString(PyExc_SystemError,
138143
"can't resize shared unicode objects");
@@ -211,6 +216,14 @@ PyUnicodeObject *_PyUnicode_New(int length)
211216
PyErr_NoMemory();
212217
goto onError;
213218
}
219+
/* Initialize the first element to guard against cases where
220+
* the caller fails before initializing str -- unicode_resize()
221+
* reads str[0], and the Keep-Alive optimization can keep memory
222+
* allocated for str alive across a call to unicode_dealloc(unicode).
223+
* We don't want unicode_resize to read uninitialized memory in
224+
* that case.
225+
*/
226+
unicode->str[0] = 0;
214227
unicode->str[length] = 0;
215228
unicode->length = length;
216229
unicode->hash = -1;

0 commit comments

Comments
 (0)