diff options
author | Brett Cannon <bcannon@gmail.com> | 2007-09-07 04:18:30 (GMT) |
---|---|---|
committer | Brett Cannon <bcannon@gmail.com> | 2007-09-07 04:18:30 (GMT) |
commit | 1e534b5425d836cb58a73d24f0be791d67bf3503 (patch) | |
tree | 1f9fc8b8802c5ba236c026fc6cbe785d7f9bf20b /Objects/exceptions.c | |
parent | 68a6da99e6dc127d817143f74e98d665117f99c2 (diff) | |
download | cpython-1e534b5425d836cb58a73d24f0be791d67bf3503.zip cpython-1e534b5425d836cb58a73d24f0be791d67bf3503.tar.gz cpython-1e534b5425d836cb58a73d24f0be791d67bf3503.tar.bz2 |
Fix a crasher where Python code managed to infinitely recurse in C code without
ever going back out to Python code in PyObject_Call(). Required introducing a
static RuntimeError instance so that normalizing an exception there is no
reliance on a recursive call that would put the exception system over the
recursion check itself.
Diffstat (limited to 'Objects/exceptions.c')
-rw-r--r-- | Objects/exceptions.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 3d79383..64f655c 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -1912,6 +1912,12 @@ SimpleExtendsException(PyExc_Warning, UnicodeWarning, */ PyObject *PyExc_MemoryErrorInst=NULL; +/* Pre-computed RuntimeError instance for when recursion depth is reached. + Meant to be used when normalizing the exception for exceeding the recursion + depth will cause its own infinite recursion. +*/ +PyObject *PyExc_RecursionErrorInst = NULL; + /* module global functions */ static PyMethodDef functions[] = { /* Sentinel */ @@ -2079,6 +2085,29 @@ _PyExc_Init(void) if (!PyExc_MemoryErrorInst) Py_FatalError("Cannot pre-allocate MemoryError instance\n"); + PyExc_RecursionErrorInst = BaseException_new(&_PyExc_RuntimeError, NULL, NULL); + if (!PyExc_RecursionErrorInst) + Py_FatalError("Cannot pre-allocate RuntimeError instance for " + "recursion errors"); + else { + PyBaseExceptionObject *err_inst = + (PyBaseExceptionObject *)PyExc_RecursionErrorInst; + PyObject *args_tuple; + PyObject *exc_message; + exc_message = PyString_FromString("maximum recursion depth exceeded"); + if (!exc_message) + Py_FatalError("cannot allocate argument for RuntimeError " + "pre-allocation"); + args_tuple = PyTuple_Pack(1, exc_message); + if (!args_tuple) + Py_FatalError("cannot allocate tuple for RuntimeError " + "pre-allocation"); + Py_DECREF(exc_message); + if (BaseException_init(err_inst, args_tuple, NULL)) + Py_FatalError("init of pre-allocated RuntimeError failed"); + Py_DECREF(args_tuple); + } + Py_DECREF(bltinmod); #if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__) |