From 94c2263005e2597a26ef76af8bfd47168d6de42e Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Thu, 4 Jun 2015 10:16:51 -0400 Subject: Issue 24374: Plug refleak in set_coroutine_wrapper --- Lib/test/test_coroutines.py | 4 ++-- Python/ceval.c | 50 +++++++++++++++++---------------------------- 2 files changed, 21 insertions(+), 33 deletions(-) diff --git a/Lib/test/test_coroutines.py b/Lib/test/test_coroutines.py index 670852d..e3a3304 100644 --- a/Lib/test/test_coroutines.py +++ b/Lib/test/test_coroutines.py @@ -1006,10 +1006,10 @@ class SysSetCoroWrapperTest(unittest.TestCase): sys.set_coroutine_wrapper(wrapper) try: - with self.assertRaisesRegex( + with silence_coro_gc(), self.assertRaisesRegex( RuntimeError, "coroutine wrapper.*\.wrapper at 0x.*attempted to " - "recursively wrap co_flags & CO_GENERATOR) { PyObject *gen; + PyObject *coro_wrapper = tstate->coroutine_wrapper; + int is_coro = co->co_flags & (CO_COROUTINE | CO_ITERABLE_COROUTINE); + + if (is_coro && tstate->in_coroutine_wrapper) { + assert(coro_wrapper != NULL); + PyErr_Format(PyExc_RuntimeError, + "coroutine wrapper %.200R attempted " + "to recursively wrap %.200R", + coro_wrapper, + co); + goto fail; + } /* Don't need to keep the reference to f_back, it will be set * when the generator is resumed. */ @@ -3936,8 +3946,13 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, if (gen == NULL) return NULL; - if (co->co_flags & (CO_COROUTINE | CO_ITERABLE_COROUTINE)) - return apply_coroutine_wrapper(gen); + if (is_coro && coro_wrapper != NULL) { + PyObject *wrapped; + tstate->in_coroutine_wrapper = 1; + wrapped = PyObject_CallFunction(coro_wrapper, "N", gen); + tstate->in_coroutine_wrapper = 0; + return wrapped; + } return gen; } @@ -5232,33 +5247,6 @@ unicode_concatenate(PyObject *v, PyObject *w, return res; } -static PyObject * -apply_coroutine_wrapper(PyObject *gen) -{ - PyObject *wrapped; - PyThreadState *tstate = PyThreadState_GET(); - PyObject *wrapper = tstate->coroutine_wrapper; - - if (tstate->in_coroutine_wrapper) { - assert(wrapper != NULL); - PyErr_Format(PyExc_RuntimeError, - "coroutine wrapper %.200R attempted " - "to recursively wrap %.200R", - wrapper, - gen); - return NULL; - } - - if (wrapper == NULL) { - return gen; - } - - tstate->in_coroutine_wrapper = 1; - wrapped = PyObject_CallFunction(wrapper, "N", gen); - tstate->in_coroutine_wrapper = 0; - return wrapped; -} - #ifdef DYNAMIC_EXECUTION_PROFILE static PyObject * -- cgit v0.12