diff options
| author | Guido van Rossum <guido@python.org> | 1999-01-12 05:07:47 +0000 |
|---|---|---|
| committer | Guido van Rossum <guido@python.org> | 1999-01-12 05:07:47 +0000 |
| commit | 28a1946bc5e8ffa5b81e40e2b86cfff98410ee8a (patch) | |
| tree | bf1198e43f0b0a6bbbf95886b82cbbc2f2da1811 /Python | |
| parent | b4fedd592831c69bac5cb3df3f35490ec88f58d3 (diff) | |
| download | cpython-28a1946bc5e8ffa5b81e40e2b86cfff98410ee8a.tar.gz | |
Avoid overflow if possible in calculations for range(); report
unavoidable overflow as OverflowError.
Diffstat (limited to 'Python')
| -rw-r--r-- | Python/bltinmodule.c | 35 |
1 files changed, 28 insertions, 7 deletions
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index a4c14ba635..d23026182e 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -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; |
