summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaymond Hettinger <python@rcn.com>2009-06-12 18:40:16 (GMT)
committerRaymond Hettinger <python@rcn.com>2009-06-12 18:40:16 (GMT)
commit94f55837775f00eade742fa015d818633ab68318 (patch)
treef61f92b50485609d21e7c9c7912cccf065873387
parent83eacca7a601df925a36455119633167a9093cdb (diff)
downloadcpython-94f55837775f00eade742fa015d818633ab68318.zip
cpython-94f55837775f00eade742fa015d818633ab68318.tar.gz
cpython-94f55837775f00eade742fa015d818633ab68318.tar.bz2
Fix SystemError and a wasps nest of ref counting issues.
-rw-r--r--Lib/test/test_range.py7
-rw-r--r--Misc/NEWS2
-rw-r--r--Objects/rangeobject.c32
3 files changed, 33 insertions, 8 deletions
diff --git a/Lib/test/test_range.py b/Lib/test/test_range.py
index 43fadf0..7650103 100644
--- a/Lib/test/test_range.py
+++ b/Lib/test/test_range.py
@@ -71,6 +71,13 @@ class RangeTest(unittest.TestCase):
self.assertEquals(list(pickle.loads(pickle.dumps(r, proto))),
list(r))
+ def test_odd_bug(self):
+ # This used to raise a "SystemError: NULL result without error"
+ # because the range validation step was eating the exception
+ # before NULL was returned.
+ with self.assertRaises(TypeError):
+ range([], 1, -1)
+
def test_main():
test.support.run_unittest(RangeTest)
diff --git a/Misc/NEWS b/Misc/NEWS
index f12c6d1..627dcf4 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,8 @@ What's New in Python 3.1 Release Candidate 2?
Core and Builtins
-----------------
+- Fixed SystemError triggered by "range([], 1, -1)".
+
- Issue #5924: On Windows, a large PYTHONPATH environment variable
(more than 255 characters) would be completely ignored.
diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c
index 01114bb..f8174ca 100644
--- a/Objects/rangeobject.c
+++ b/Objects/rangeobject.c
@@ -59,26 +59,42 @@ range_new(PyTypeObject *type, PyObject *args, PyObject *kw)
if (PyTuple_Size(args) <= 1) {
if (!PyArg_UnpackTuple(args, "range", 1, 1, &stop))
- goto Fail;
+ return NULL;
stop = PyNumber_Index(stop);
if (!stop)
- goto Fail;
+ return NULL;
start = PyLong_FromLong(0);
+ if (!start) {
+ Py_DECREF(stop);
+ return NULL;
+ }
step = PyLong_FromLong(1);
- if (!start || !step)
- goto Fail;
+ if (!step) {
+ Py_DECREF(stop);
+ Py_DECREF(start);
+ return NULL;
+ }
}
else {
if (!PyArg_UnpackTuple(args, "range", 2, 3,
&start, &stop, &step))
- goto Fail;
+ return NULL;
/* Convert borrowed refs to owned refs */
start = PyNumber_Index(start);
+ if (!start)
+ return NULL;
stop = PyNumber_Index(stop);
- step = validate_step(step);
- if (!start || !stop || !step)
- goto Fail;
+ if (!stop) {
+ Py_DECREF(start);
+ return NULL;
+ }
+ step = validate_step(step); /* Caution, this can clear exceptions */
+ if (!step) {
+ Py_DECREF(start);
+ Py_DECREF(stop);
+ return NULL;
+ }
}
obj = PyObject_New(rangeobject, &PyRange_Type);