[Python-checkins] cpython (2.7): fix expandtabs overflow detection to be consistent and not rely on signed

benjamin.peterson python-checkins at python.org
Mon Mar 31 01:54:06 CEST 2014


http://hg.python.org/cpython/rev/a2254f4338e6
changeset:   90056:a2254f4338e6
branch:      2.7
user:        Benjamin Peterson <benjamin at python.org>
date:        Sun Mar 30 19:47:57 2014 -0400
summary:
  fix expandtabs overflow detection to be consistent and not rely on signed overflow

files:
  Objects/stringlib/transmogrify.h |  38 ++++++++++----------
  1 files changed, 19 insertions(+), 19 deletions(-)


diff --git a/Objects/stringlib/transmogrify.h b/Objects/stringlib/transmogrify.h
--- a/Objects/stringlib/transmogrify.h
+++ b/Objects/stringlib/transmogrify.h
@@ -15,7 +15,7 @@
 {
     const char *e, *p;
     char *q;
-    size_t i, j;
+    Py_ssize_t i, j;
     PyObject *u;
     int tabsize = 8;
     
@@ -25,34 +25,30 @@
     /* First pass: determine size of output string */
     i = j = 0;
     e = STRINGLIB_STR(self) + STRINGLIB_LEN(self);
-    for (p = STRINGLIB_STR(self); p < e; p++)
+    for (p = STRINGLIB_STR(self); p < e; p++) {
         if (*p == '\t') {
             if (tabsize > 0) {
-                j += tabsize - (j % tabsize);
-                if (j > PY_SSIZE_T_MAX) {
-                    PyErr_SetString(PyExc_OverflowError,
-                                    "result is too long");
-                    return NULL;
-                }
+                Py_ssize_t incr = tabsize - (j % tabsize);
+                if (j > PY_SSIZE_T_MAX - incr)
+                    goto overflow;
+                j += incr;
             }
         }
         else {
+            if (j > PY_SSIZE_T_MAX - 1)
+                goto overflow;
             j++;
             if (*p == '\n' || *p == '\r') {
+                if (i > PY_SSIZE_T_MAX - j)
+                    goto overflow;
                 i += j;
                 j = 0;
-                if (i > PY_SSIZE_T_MAX) {
-                    PyErr_SetString(PyExc_OverflowError,
-                                    "result is too long");
-                    return NULL;
-                }
             }
         }
+    }
     
-    if ((i + j) > PY_SSIZE_T_MAX) {
-        PyErr_SetString(PyExc_OverflowError, "result is too long");
-        return NULL;
-    }
+    if (i > PY_SSIZE_T_MAX - j)
+        goto overflow;
     
     /* Second pass: create output string and fill it */
     u = STRINGLIB_NEW(NULL, i + j);
@@ -62,7 +58,7 @@
     j = 0;
     q = STRINGLIB_STR(u);
     
-    for (p = STRINGLIB_STR(self); p < e; p++)
+    for (p = STRINGLIB_STR(self); p < e; p++) {
         if (*p == '\t') {
             if (tabsize > 0) {
                 i = tabsize - (j % tabsize);
@@ -77,8 +73,12 @@
             if (*p == '\n' || *p == '\r')
                 j = 0;
         }
-    
+    }
+
     return u;
+  overflow:
+    PyErr_SetString(PyExc_OverflowError, "result too long");
+    return NULL;
 }
 
 Py_LOCAL_INLINE(PyObject *)

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list