diff options
author | Guido van Rossum <guido@python.org> | 1999-01-12 05:07:47 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 1999-01-12 05:07:47 (GMT) |
commit | e23cde2f8d0084f8ccfb8b6149afe06809f1c81c (patch) | |
tree | 1adb5e1890e725074a385de1ca8949cbfb57c2f3 | |
parent | 5a0ca4e55caa415c57b68cb2cd519c9939d26035 (diff) | |
download | cpython-e23cde2f8d0084f8ccfb8b6149afe06809f1c81c.zip cpython-e23cde2f8d0084f8ccfb8b6149afe06809f1c81c.tar.gz cpython-e23cde2f8d0084f8ccfb8b6149afe06809f1c81c.tar.bz2 |
Avoid overflow if possible in calculations for range(); report
unavoidable overflow as OverflowError.
-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 a4c14ba..d230261 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; |