summaryrefslogtreecommitdiffstats
path: root/Objects/classobject.c
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2002-06-13 21:32:51 (GMT)
committerGuido van Rossum <guido@python.org>2002-06-13 21:32:51 (GMT)
commit16b93b3d0e2bf8dc22d11e8625af6d9cc913ec88 (patch)
tree630dc03abb467a5e3cac738bff939d0c80fb2db9 /Objects/classobject.c
parent51290d369d7ef7bc9dec6a0082e3aa4f5e434d31 (diff)
downloadcpython-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.c18
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;
}