summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1999-01-12 05:07:47 (GMT)
committerGuido van Rossum <guido@python.org>1999-01-12 05:07:47 (GMT)
commite23cde2f8d0084f8ccfb8b6149afe06809f1c81c (patch)
tree1adb5e1890e725074a385de1ca8949cbfb57c2f3
parent5a0ca4e55caa415c57b68cb2cd519c9939d26035 (diff)
downloadcpython-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.c35
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;