From 16b93b3d0e2bf8dc22d11e8625af6d9cc913ec88 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Thu, 13 Jun 2002 21:32:51 +0000 Subject: 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. --- Objects/classobject.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'Objects/classobject.c') diff --git a/Objects/classobject.c b/Objects/classobject.c index 4522097ac8..8091f0fbd7 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; } -- cgit v1.2.1