From 4bf21e28dfb42c2da3d440c2c0d9898cb3196fe1 Mon Sep 17 00:00:00 2001 From: Amaury Forgeot d'Arc Date: Wed, 7 Dec 2011 21:46:48 +0100 Subject: Issue #13546: Fixed an overflow issue that could crash the intepreter when calling sys.setrecursionlimit((1<<31)-1). 2.7 only. --- Lib/test/test_sys.py | 12 ++++++++++++ Misc/NEWS | 3 +++ Python/errors.c | 6 ++++-- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index 49f5388..6c5fc24 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -224,6 +224,18 @@ class SysModuleTest(unittest.TestCase): self.assertEqual(sys.getrecursionlimit(), 10000) sys.setrecursionlimit(oldlimit) + self.assertRaises(OverflowError, sys.setrecursionlimit, 1 << 31) + try: + sys.setrecursionlimit((1 << 31) - 5) + try: + # issue13546: isinstance(e, ValueError) used to fail + # when the recursion limit is close to 1<<31 + raise ValueError() + except ValueError, e: + pass + finally: + sys.setrecursionlimit(oldlimit) + def test_getwindowsversion(self): # Raise SkipTest if sys doesn't have getwindowsversion attribute test.test_support.get_attribute(sys, "getwindowsversion") diff --git a/Misc/NEWS b/Misc/NEWS index bf63153..6a089e3 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -9,6 +9,9 @@ What's New in Python 2.7.3? Core and Builtins ----------------- +- Issue #13546: Fixed an overflow issue that could crash the intepreter when + calling sys.setrecursionlimit((1<<31)-1). + - Issue #13333: The UTF-7 decoder now accepts lone surrogates (the encoder already accepts them). diff --git a/Python/errors.c b/Python/errors.c index 4294f2f..64ba05d 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -111,9 +111,11 @@ PyErr_GivenExceptionMatches(PyObject *err, PyObject *exc) PyErr_Fetch(&exception, &value, &tb); /* Temporarily bump the recursion limit, so that in the most common case PyObject_IsSubclass will not raise a recursion - error we have to ignore anyway. */ + error we have to ignore anyway. Don't do it when the limit + is already insanely high, to avoid overflow */ reclimit = Py_GetRecursionLimit(); - Py_SetRecursionLimit(reclimit + 5); + if (reclimit < (1 << 30)) + Py_SetRecursionLimit(reclimit + 5); res = PyObject_IsSubclass(err, exc); Py_SetRecursionLimit(reclimit); /* This function must not fail, so print the error here */ -- cgit v0.12