From ea3912b0da71e16b8a37e04fcf3969dc85c27fa1 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Tue, 13 Jun 2006 21:46:41 +0000 Subject: If a classic class defined a __coerce__() method that just returned its two arguments in reverse, the interpreter would infinitely recourse trying to get a coercion that worked. So put in a recursion check after a coercion is made and the next call to attempt to use the coerced values. Fixes bug #992017 and closes crashers/coerce.py . --- Lib/test/crashers/coerce.py | 9 --------- Misc/NEWS | 3 +++ Objects/classobject.c | 3 +++ 3 files changed, 6 insertions(+), 9 deletions(-) delete mode 100644 Lib/test/crashers/coerce.py diff --git a/Lib/test/crashers/coerce.py b/Lib/test/crashers/coerce.py deleted file mode 100644 index 574956b..0000000 --- a/Lib/test/crashers/coerce.py +++ /dev/null @@ -1,9 +0,0 @@ - -# http://python.org/sf/992017 - -class foo: - def __coerce__(self, other): - return other, self - -if __name__ == '__main__': - foo()+1 # segfault: infinite recursion in C diff --git a/Misc/NEWS b/Misc/NEWS index 82838f3..d7dfb8f 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -12,6 +12,9 @@ What's New in Python 2.5 beta 1? Core and builtins ----------------- +- Bug #992017: A classic class that defined a __coerce__() method that returned + its arguments swapped would infinitely recurse and segfault the interpreter. + - Fix the socket tests so they can be run concurrently. - Removed 5 integers from C frame objects (PyFrameObject). diff --git a/Objects/classobject.c b/Objects/classobject.c index 9e57269..c69ba74 100644 --- a/Objects/classobject.c +++ b/Objects/classobject.c @@ -1368,10 +1368,13 @@ half_binop(PyObject *v, PyObject *w, char *opname, binaryfunc thisfunc, * argument */ result = generic_binary_op(v1, w, opname); } else { + if (Py_EnterRecursiveCall(" after coercion")) + return NULL; if (swapped) result = (thisfunc)(w, v1); else result = (thisfunc)(v1, w); + Py_LeaveRecursiveCall(); } Py_DECREF(coerced); return result; -- cgit v0.12