]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Avoid overflow if possible in calculations for range(); report
authorGuido van Rossum <guido@python.org>
Tue, 12 Jan 1999 05:07:47 +0000 (05:07 +0000)
committerGuido van Rossum <guido@python.org>
Tue, 12 Jan 1999 05:07:47 +0000 (05:07 +0000)
unavoidable overflow as OverflowError.

Python/bltinmodule.c

index a4c14ba635cd2307d1fa9b6d11bbff77defde9c0..d23026182e5d799197fd71992bb08fec1563c620 100644 (file)
@@ -1415,13 +1415,34 @@ builtin_range(self, args)
                PyErr_SetString(PyExc_ValueError, "zero step for range()");
                return NULL;
        }
-       /* XXX ought to check overflow of subtraction */
-       if (istep > 0)
-               n = (ihigh - ilow + istep - 1) / istep;
-       else
-               n = (ihigh - ilow + istep + 1) / istep;
-       if (n < 0)
-               n = 0;
+       /* A bit convoluted because this might overflow; due to Tim Peters */
+       if (istep > 0) {
+               if (ihigh <= ilow)
+                       n = 0;
+               else {
+                       unsigned long hi = (unsigned long)ihigh;
+                       unsigned long lo = (unsigned long)ilow;
+                       unsigned long diff = hi - lo - 1;
+                       n = (long)(diff / istep + 1);
+               }
+       }
+       else {
+               /* But any errors in this branch are my own --Guido */
+               if (ihigh >= ilow)
+                       n = 0;
+               else {
+                       /* Swap lo and hi; use abs(istep) */
+                       unsigned long hi = (unsigned long)ilow;
+                       unsigned long lo = (unsigned long)ihigh;
+                       unsigned long diff = hi - lo - 1;
+                       n = (long)(diff / (-istep) + 1);
+               }
+       }
+       if (n < 0) {
+               PyErr_SetString(PyExc_OverflowError,
+                               "range() has more than sys.maxint items");
+               return NULL;
+       }
        v = PyList_New(n);
        if (v == NULL)
                return NULL;