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

antoine.pitrou python-checkins at python.org
Wed Jan 14 00:25:47 CET 2009


Author: antoine.pitrou
Date: Wed Jan 14 00:25:47 2009
New Revision: 68594

Log:
Merged revisions 68589 via svnmerge from 
svn+ssh://pythondev@svn.python.org/python/trunk

........
  r68589 | antoine.pitrou | 2009-01-14 00:13:52 +0100 (mer., 14 janv. 2009) | 5 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.
........


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

Modified: python/branches/release26-maint/Misc/NEWS
==============================================================================
--- python/branches/release26-maint/Misc/NEWS	(original)
+++ python/branches/release26-maint/Misc/NEWS	Wed Jan 14 00:25:47 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 #1180193: When importing a module from a .pyc (or .pyo) file with
   an existing .py counterpart, override the co_filename attributes of all
   code objects if the original filename is obsolete (which can happen if the

Modified: python/branches/release26-maint/Objects/stringlib/transmogrify.h
==============================================================================
--- python/branches/release26-maint/Objects/stringlib/transmogrify.h	(original)
+++ python/branches/release26-maint/Objects/stringlib/transmogrify.h	Wed Jan 14 00:25:47 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