try: hash(C2())
except TypeError: pass
else: raise TestFailed, "hash(C2()) should raise an exception"
+
+
+# Test for SF bug 532646
+
+class A:
+ pass
+A.__call__ = A()
+a = A()
+try:
+ a() # This should not segfault
+except RuntimeError:
+ pass
+else:
+ raise TestFailed, "how could this not have overflowed the stack?"
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;
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;
}