summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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;