]> granicus.if.org Git - python/commitdiff
Merged revisions 68589 via svnmerge from
authorAntoine Pitrou <solipsis@pitrou.net>
Tue, 13 Jan 2009 23:25:47 +0000 (23:25 +0000)
committerAntoine Pitrou <solipsis@pitrou.net>
Tue, 13 Jan 2009 23:25:47 +0000 (23:25 +0000)
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.
........

Misc/NEWS
Objects/stringlib/transmogrify.h

index b60384119fea6a6dbab87c3509ab0041b1dc4d1b..055149259f395cc4f05fda81ab44f2bb1576ccdc 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,10 @@ What's New in Python 2.6.2
 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
index fe478c358cd6cb5f12aad257fbe51656b1c143e3..7dc81776ab395e4c9886817b699fba778d8eadbe 100644 (file)
@@ -22,76 +22,69 @@ stringlib_expandtabs(PyObject *self, PyObject *args)
 {
     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;
 }