diff options
author | Tim Peters <tim.peters@gmail.com> | 2004-08-08 07:17:39 (GMT) |
---|---|---|
committer | Tim Peters <tim.peters@gmail.com> | 2004-08-08 07:17:39 (GMT) |
commit | feec4533e21a612e9a5b665c27b1a3eb84e04bb3 (patch) | |
tree | e721c83b44443f2cbda66a7acab7ddd4cd30a9d6 /Objects/rangeobject.c | |
parent | d976ab7caf098eecf44173bbce8101f13ce79d86 (diff) | |
download | cpython-feec4533e21a612e9a5b665c27b1a3eb84e04bb3.zip cpython-feec4533e21a612e9a5b665c27b1a3eb84e04bb3.tar.gz cpython-feec4533e21a612e9a5b665c27b1a3eb84e04bb3.tar.bz2 |
Bug 1003935: xrange overflows
Added XXX comment about why the undocumented PyRange_New() API function
is too broken to be worth the considerable pain of repairing.
Changed range_new() to stop using PyRange_New(). This fixes a variety
of bogus errors. Nothing in the core uses PyRange_New() now.
Documented that xrange() is intended to be simple and fast, and that
CPython restricts its arguments, and length of its result sequence, to
native C longs.
Added some tests that failed before the patch, and repaired a test that
relied on a bogus OverflowError getting raised.
Diffstat (limited to 'Objects/rangeobject.c')
-rw-r--r-- | Objects/rangeobject.c | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c index dbfab9f..dabb8d4 100644 --- a/Objects/rangeobject.c +++ b/Objects/rangeobject.c @@ -9,6 +9,13 @@ typedef struct { long len; } rangeobject; +/* XXX PyRange_New should be deprecated. It's not documented. It's not + * used in the core. Its error-checking is akin to Swiss cheese: accepts + * step == 0; accepts len < 0; ignores that (len - 1) * step may overflow; + * raises a baffling "integer addition" exception if it thinks the last + * item is "too big"; and doesn't compute whether "last item is too big" + * correctly even if the multiplication doesn't overflow. + */ PyObject * PyRange_New(long start, long len, long step, int reps) { @@ -79,6 +86,7 @@ get_len_of_range(long lo, long hi, long step) static PyObject * range_new(PyTypeObject *type, PyObject *args, PyObject *kw) { + rangeobject *obj; long ilow = 0, ihigh = 0, istep = 1; long n; @@ -107,7 +115,14 @@ range_new(PyTypeObject *type, PyObject *args, PyObject *kw) "xrange() result has too many items"); return NULL; } - return PyRange_New(ilow, n, istep, 1); + + obj = PyObject_New(rangeobject, &PyRange_Type); + if (obj == NULL) + return NULL; + obj->start = ilow; + obj->len = n; + obj->step = istep; + return (PyObject *) obj; } PyDoc_STRVAR(range_doc, |