summaryrefslogtreecommitdiffstats
path: root/Objects/rangeobject.c
diff options
context:
space:
mode:
authorTim Peters <tim.peters@gmail.com>2004-08-08 07:17:39 (GMT)
committerTim Peters <tim.peters@gmail.com>2004-08-08 07:17:39 (GMT)
commitfeec4533e21a612e9a5b665c27b1a3eb84e04bb3 (patch)
treee721c83b44443f2cbda66a7acab7ddd4cd30a9d6 /Objects/rangeobject.c
parentd976ab7caf098eecf44173bbce8101f13ce79d86 (diff)
downloadcpython-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.c17
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,