diff options
author | Guido van Rossum <guido@python.org> | 2002-06-13 21:32:51 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2002-06-13 21:32:51 (GMT) |
commit | 16b93b3d0e2bf8dc22d11e8625af6d9cc913ec88 (patch) | |
tree | 630dc03abb467a5e3cac738bff939d0c80fb2db9 /Objects/classobject.c | |
parent | 51290d369d7ef7bc9dec6a0082e3aa4f5e434d31 (diff) | |
download | cpython-16b93b3d0e2bf8dc22d11e8625af6d9cc913ec88.zip cpython-16b93b3d0e2bf8dc22d11e8625af6d9cc913ec88.tar.gz cpython-16b93b3d0e2bf8dc22d11e8625af6d9cc913ec88.tar.bz2 |
Fix for SF bug 532646. This is a little simpler than what Neal
suggested there, based upon a better analysis (__getattr__ is a red
herring). Will backport to 2.2.
Diffstat (limited to 'Objects/classobject.c')
-rw-r--r-- | Objects/classobject.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/Objects/classobject.c b/Objects/classobject.c index 4522097..8091f0f 100644 --- a/Objects/classobject.c +++ b/Objects/classobject.c @@ -1879,6 +1879,7 @@ instance_iternext(PyInstanceObject *self) static PyObject * instance_call(PyObject *func, PyObject *arg, PyObject *kw) { + PyThreadState *tstate = PyThreadState_GET(); PyObject *res, *call = PyObject_GetAttrString(func, "__call__"); if (call == NULL) { PyInstanceObject *inst = (PyInstanceObject*) func; @@ -1888,7 +1889,22 @@ instance_call(PyObject *func, PyObject *arg, PyObject *kw) PyString_AsString(inst->in_class->cl_name)); return NULL; } - res = PyObject_Call(call, arg, kw); + /* We must check and increment the recursion depth here. Scenario: + class A: + pass + A.__call__ = A() # that's right + a = A() # ok + a() # infinite recursion + This bounces between instance_call() and PyObject_Call() without + ever hitting eval_frame() (which has the main recursion check). */ + if (tstate->recursion_depth++ > Py_GetRecursionLimit()) { + PyErr_SetString(PyExc_RuntimeError, + "maximum __call__ recursion depth exceeded"); + res = NULL; + } + else + res = PyObject_Call(call, arg, kw); + tstate->recursion_depth--; Py_DECREF(call); return res; } |