From: Benjamin Peterson Date: Fri, 15 Jul 2011 19:15:40 +0000 (-0500) Subject: port 8d05f697acd4 (#11627) X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c3349cd22e9877a0516d8baa71530f87bf5ac430;p=python port 8d05f697acd4 (#11627) --- diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index a19c82d066..5526fb77eb 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -464,6 +464,14 @@ class ExceptionTests(unittest.TestCase): self.assertTrue(e is RuntimeError, e) self.assertIn("maximum recursion depth exceeded", str(v)) + def test_new_returns_invalid_instance(self): + # See issue #11627. + class MyException(Exception): + def __new__(cls, *args): + return object() + + with self.assertRaises(TypeError): + raise MyException # Helper class used by TestSameStrAndUnicodeMsg diff --git a/Misc/NEWS b/Misc/NEWS index 4f1f1cf061..867ef9ce6c 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -9,6 +9,9 @@ What's New in Python 2.7.3? Core and Builtins ----------------- +- Issue #11627: Fix segfault when __new__ on a exception returns a non-exception + class. + - Issue #12149: Update the method cache after a type's dictionnary gets cleared by the garbage collector. This fixes a segfault when an instance and its type get caught in a reference cycle, and the instance's diff --git a/Python/ceval.c b/Python/ceval.c index 10dd3a1f29..06ada97274 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -3515,9 +3515,17 @@ do_raise(PyObject *type, PyObject *value, PyObject *tb) Py_DECREF(tmp); } - if (PyExceptionClass_Check(type)) + if (PyExceptionClass_Check(type)) { PyErr_NormalizeException(&type, &value, &tb); - + if (!PyExceptionInstance_Check(value)) { + PyErr_Format(PyExc_TypeError, + "calling %s() should have returned an instance of " + "BaseException, not '%s'", + ((PyTypeObject *)type)->tp_name, + Py_TYPE(value)->tp_name); + goto raise_error; + } + } else if (PyExceptionInstance_Check(type)) { /* Raising an instance. The value should be a dummy. */ if (value != Py_None) {