Skip to content

Commit 94f5583

Browse files
committed
Fix SystemError and a wasps nest of ref counting issues.
1 parent 83eacca commit 94f5583

3 files changed

Lines changed: 33 additions & 8 deletions

File tree

Lib/test/test_range.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,13 @@ def test_pickling(self):
7171
self.assertEquals(list(pickle.loads(pickle.dumps(r, proto))),
7272
list(r))
7373

74+
def test_odd_bug(self):
75+
# This used to raise a "SystemError: NULL result without error"
76+
# because the range validation step was eating the exception
77+
# before NULL was returned.
78+
with self.assertRaises(TypeError):
79+
range([], 1, -1)
80+
7481
def test_main():
7582
test.support.run_unittest(RangeTest)
7683

Misc/NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ What's New in Python 3.1 Release Candidate 2?
1212
Core and Builtins
1313
-----------------
1414

15+
- Fixed SystemError triggered by "range([], 1, -1)".
16+
1517
- Issue #5924: On Windows, a large PYTHONPATH environment variable
1618
(more than 255 characters) would be completely ignored.
1719

Objects/rangeobject.c

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,26 +59,42 @@ range_new(PyTypeObject *type, PyObject *args, PyObject *kw)
5959

6060
if (PyTuple_Size(args) <= 1) {
6161
if (!PyArg_UnpackTuple(args, "range", 1, 1, &stop))
62-
goto Fail;
62+
return NULL;
6363
stop = PyNumber_Index(stop);
6464
if (!stop)
65-
goto Fail;
65+
return NULL;
6666
start = PyLong_FromLong(0);
67+
if (!start) {
68+
Py_DECREF(stop);
69+
return NULL;
70+
}
6771
step = PyLong_FromLong(1);
68-
if (!start || !step)
69-
goto Fail;
72+
if (!step) {
73+
Py_DECREF(stop);
74+
Py_DECREF(start);
75+
return NULL;
76+
}
7077
}
7178
else {
7279
if (!PyArg_UnpackTuple(args, "range", 2, 3,
7380
&start, &stop, &step))
74-
goto Fail;
81+
return NULL;
7582

7683
/* Convert borrowed refs to owned refs */
7784
start = PyNumber_Index(start);
85+
if (!start)
86+
return NULL;
7887
stop = PyNumber_Index(stop);
79-
step = validate_step(step);
80-
if (!start || !stop || !step)
81-
goto Fail;
88+
if (!stop) {
89+
Py_DECREF(start);
90+
return NULL;
91+
}
92+
step = validate_step(step); /* Caution, this can clear exceptions */
93+
if (!step) {
94+
Py_DECREF(start);
95+
Py_DECREF(stop);
96+
return NULL;
97+
}
8298
}
8399

84100
obj = PyObject_New(rangeobject, &PyRange_Type);

0 commit comments

Comments
 (0)