]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
If a classic class defined a __coerce__() method that just returned its two
authorBrett Cannon <bcannon@gmail.com>
Tue, 13 Jun 2006 21:46:41 +0000 (21:46 +0000)
committerBrett Cannon <bcannon@gmail.com>
Tue, 13 Jun 2006 21:46:41 +0000 (21:46 +0000)
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 [deleted file]
Misc/NEWS
Objects/classobject.c

diff --git a/Lib/test/crashers/coerce.py b/Lib/test/crashers/coerce.py
deleted file mode 100644 (file)
index 574956b..0000000
+++ /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
index 82838f3d00200e5ced664783ac5d3379a2d69d98..d7dfb8fc624b1f937e3cf8491f78c832d9f50b1a 100644 (file)
--- 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).
index 9e57269d24d0f573bb47656b26ac13d3d788f457..c69ba744e62f62d736cc5a62ee5b64589daaa59e 100644 (file)
@@ -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;