diff Objects/unicodeobject.c @ 30439:30e495efe90a legacy-trunk

Double-fix of crash in Unicode freelist handling. If a length-1 Unicode string was in the freelist and it was uninitialized or pointed to a very large (magnitude) negative number, the check unicode_latin1[unicode->str[0]] == unicode could cause a segmentation violation, e.g. unicode->str[0] is 0xcbcbcbcb. Fix this in two ways: 1. Change guard befor unicode_latin1[] to test against 256U. If I understand correctly, the unsigned long used to store UCS4 on my box was getting converted to a signed long to compare with the signed constant 256. 2. Change _PyUnicode_New() to make sure the first element of str is always initialized to zero. There are several places in the code where the caller can exit with an error before initializing any of str, which would leave junk in str[0]. Also, silence a compiler warning on pointer vs. int arithmetic. Bug fix candidate.
author Jeremy Hylton <jeremy@alum.mit.edu>
date Tue, 16 Sep 2003 19:41:39 +0000
parents cd0c3f916b34
children 76e998aee644
line wrap: on
line diff
--- a/Objects/unicodeobject.c	Tue Sep 16 07:11:46 2003 +0000
+++ b/Objects/unicodeobject.c	Tue Sep 16 19:41:39 2003 +0000
@@ -132,7 +132,8 @@
        instead ! */
     if (unicode == unicode_empty || 
 	(unicode->length == 1 && 
-	 unicode->str[0] < 256 &&
+         /* XXX Is unicode->str[] always unsigned? */
+	 unicode->str[0] < 256U &&
 	 unicode_latin1[unicode->str[0]] == unicode)) {
         PyErr_SetString(PyExc_SystemError,
                         "can't resize shared unicode objects");
@@ -211,6 +212,10 @@
 	PyErr_NoMemory();
 	goto onError;
     }
+    /* Initialize the first element to guard against cases where
+       the caller fails before initializing str.
+    */
+    unicode->str[0] = 0;
     unicode->str[length] = 0;
     unicode->length = length;
     unicode->hash = -1;
@@ -2527,7 +2532,7 @@
 	else {
 	    startinpos = s-starts;
 	    endinpos = startinpos + 1;
-	    outpos = p-PyUnicode_AS_UNICODE(v);
+	    outpos = p - (Py_UNICODE *)PyUnicode_AS_UNICODE(v);
 	    if (unicode_decode_call_errorhandler(
 		 errors, &errorHandler,
 		 "ascii", "ordinal not in range(128)",