[Python-checkins] r68588 - in python/branches/release30-maint: Misc/NEWS Objects/stringlib/transmogrify.h

antoine.pitrou python-checkins at python.org
Wed Jan 14 00:12:24 CET 2009


Author: antoine.pitrou
Date: Wed Jan 14 00:12:23 2009
New Revision: 68588

Log:
Merged revisions 68587 via svnmerge from 
svn+ssh://pythondev@svn.python.org/python/branches/py3k

........
  r68587 | antoine.pitrou | 2009-01-13 23:59:11 +0100 (mar., 13 janv. 2009) | 7 lines
  
  Issue #4935: The overflow checking code in the expandtabs() method common
  to str, bytes and bytearray could be optimized away by the compiler (*), letting
  the interpreter segfault instead of raising an error.
  
  (*) or at least it is our interpretation
........


Modified:
   python/branches/release30-maint/   (props changed)
   python/branches/release30-maint/Misc/NEWS
   python/branches/release30-maint/Objects/stringlib/transmogrify.h

Modified: python/branches/release30-maint/Misc/NEWS
==============================================================================
--- python/branches/release30-maint/Misc/NEWS	(original)
+++ python/branches/release30-maint/Misc/NEWS	Wed Jan 14 00:12:23 2009
@@ -12,6 +12,10 @@
 Core and Builtins
 -----------------
 
+- Issue #4935: The overflow checking code in the expandtabs() method common
+  to str, bytes and bytearray could be optimized away by the compiler, letting
+  the interpreter segfault instead of raising an error.
+
 - Issue #4910: Builtin int() function and PyNumber_Long/PyNumber_Int API
   function no longer attempt to call the __long__ slot to convert an object
   to an integer.  Only the __int__ and __trunc__ slots are examined.

Modified: python/branches/release30-maint/Objects/stringlib/transmogrify.h
==============================================================================
--- python/branches/release30-maint/Objects/stringlib/transmogrify.h	(original)
+++ python/branches/release30-maint/Objects/stringlib/transmogrify.h	Wed Jan 14 00:12:23 2009
@@ -22,76 +22,69 @@
 {
     const char *e, *p;
     char *q;
-    Py_ssize_t i, j, old_j;
+    size_t i, j;
     PyObject *u;
     int tabsize = 8;
-
+    
     if (!PyArg_ParseTuple(args, "|i:expandtabs", &tabsize))
-	return NULL;
-
+        return NULL;
+    
     /* First pass: determine size of output string */
-    i = j = old_j = 0;
+    i = j = 0;
     e = STRINGLIB_STR(self) + STRINGLIB_LEN(self);
     for (p = STRINGLIB_STR(self); p < e; p++)
         if (*p == '\t') {
-	    if (tabsize > 0) {
-		j += tabsize - (j % tabsize);
-                /* XXX: this depends on a signed integer overflow to < 0 */
-                /* C compilers, including gcc, do -NOT- guarantee this. */
-		if (old_j > j) {
-		    PyErr_SetString(PyExc_OverflowError,
-				    "result is too long");
-		    return NULL;
-		}
-		old_j = j;
+            if (tabsize > 0) {
+                j += tabsize - (j % tabsize);
+                if (j > PY_SSIZE_T_MAX) {
+                    PyErr_SetString(PyExc_OverflowError,
+                                    "result is too long");
+                    return NULL;
+                }
             }
-	}
+        }
         else {
             j++;
             if (*p == '\n' || *p == '\r') {
                 i += j;
-                old_j = j = 0;
-                /* XXX: this depends on a signed integer overflow to < 0 */
-                /* C compilers, including gcc, do -NOT- guarantee this. */
-                if (i < 0) {
+                j = 0;
+                if (i > PY_SSIZE_T_MAX) {
                     PyErr_SetString(PyExc_OverflowError,
                                     "result is too long");
                     return NULL;
                 }
             }
         }
-
-    if ((i + j) < 0) {
-        /* XXX: this depends on a signed integer overflow to < 0 */
-        /* C compilers, including gcc, do -NOT- guarantee this. */
+    
+    if ((i + j) > PY_SSIZE_T_MAX) {
         PyErr_SetString(PyExc_OverflowError, "result is too long");
         return NULL;
     }
-
+    
     /* Second pass: create output string and fill it */
     u = STRINGLIB_NEW(NULL, i + j);
     if (!u)
         return NULL;
-
+    
     j = 0;
     q = STRINGLIB_STR(u);
-
+    
     for (p = STRINGLIB_STR(self); p < e; p++)
         if (*p == '\t') {
-	    if (tabsize > 0) {
-		i = tabsize - (j % tabsize);
-		j += i;
-		while (i--)
-		    *q++ = ' ';
-	    }
-	}
-	else {
+            if (tabsize > 0) {
+                i = tabsize - (j % tabsize);
+                j += i;
+                while (i--)
+                    *q++ = ' ';
+            }
+        }
+        else {
             j++;
-	    *q++ = *p;
+            *q++ = *p;
             if (*p == '\n' || *p == '\r')
                 j = 0;
         }
-
+    
     return u;
 }
 


More information about the Python-checkins mailing list