Skip to content

Commit 4bf21e2

Browse files
committed
Issue #13546: Fixed an overflow issue that could crash the intepreter when
calling sys.setrecursionlimit((1<<31)-1). 2.7 only.
1 parent a94b578 commit 4bf21e2

3 files changed

Lines changed: 19 additions & 2 deletions

File tree

Lib/test/test_sys.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,18 @@ def test_recursionlimit(self):
224224
self.assertEqual(sys.getrecursionlimit(), 10000)
225225
sys.setrecursionlimit(oldlimit)
226226

227+
self.assertRaises(OverflowError, sys.setrecursionlimit, 1 << 31)
228+
try:
229+
sys.setrecursionlimit((1 << 31) - 5)
230+
try:
231+
# issue13546: isinstance(e, ValueError) used to fail
232+
# when the recursion limit is close to 1<<31
233+
raise ValueError()
234+
except ValueError, e:
235+
pass
236+
finally:
237+
sys.setrecursionlimit(oldlimit)
238+
227239
def test_getwindowsversion(self):
228240
# Raise SkipTest if sys doesn't have getwindowsversion attribute
229241
test.test_support.get_attribute(sys, "getwindowsversion")

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ What's New in Python 2.7.3?
99
Core and Builtins
1010
-----------------
1111

12+
- Issue #13546: Fixed an overflow issue that could crash the intepreter when
13+
calling sys.setrecursionlimit((1<<31)-1).
14+
1215
- Issue #13333: The UTF-7 decoder now accepts lone surrogates (the encoder
1316
already accepts them).
1417

Python/errors.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,11 @@ PyErr_GivenExceptionMatches(PyObject *err, PyObject *exc)
111111
PyErr_Fetch(&exception, &value, &tb);
112112
/* Temporarily bump the recursion limit, so that in the most
113113
common case PyObject_IsSubclass will not raise a recursion
114-
error we have to ignore anyway. */
114+
error we have to ignore anyway. Don't do it when the limit
115+
is already insanely high, to avoid overflow */
115116
reclimit = Py_GetRecursionLimit();
116-
Py_SetRecursionLimit(reclimit + 5);
117+
if (reclimit < (1 << 30))
118+
Py_SetRecursionLimit(reclimit + 5);
117119
res = PyObject_IsSubclass(err, exc);
118120
Py_SetRecursionLimit(reclimit);
119121
/* This function must not fail, so print the error here */

0 commit comments

Comments
 (0)