From: Antoine Pitrou Date: Sun, 26 Apr 2015 16:46:40 +0000 (+0200) Subject: Issue #23996: Avoid a crash when a delegated generator raises an unnormalized StopIte... X-Git-Tag: v3.5.0b1~283^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7403e91630456ae2a495ac7621c2152d9a270400;p=python Issue #23996: Avoid a crash when a delegated generator raises an unnormalized StopIteration exception. Patch by Stefan Behnel. --- diff --git a/Misc/NEWS b/Misc/NEWS index 2616bf7d93..e84e142857 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ Release date: tba Core and Builtins ----------------- +- Issue #23996: Avoid a crash when a delegated generator raises an + unnormalized StopIteration exception. Patch by Stefan Behnel. + - Issue #24022: Fix tokenizer crash when processing undecodable source code. - Issue #23309: Avoid a deadlock at shutdown if a daemon thread is aborted diff --git a/Objects/genobject.c b/Objects/genobject.c index 08d30bf4b7..f125847bd7 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -396,13 +396,30 @@ _PyGen_FetchStopIterationValue(PyObject **pvalue) { if (PyErr_ExceptionMatches(PyExc_StopIteration)) { PyErr_Fetch(&et, &ev, &tb); - Py_XDECREF(et); - Py_XDECREF(tb); if (ev) { - value = ((PyStopIterationObject *)ev)->value; - Py_INCREF(value); - Py_DECREF(ev); + /* exception will usually be normalised already */ + if (Py_TYPE(ev) == (PyTypeObject *) et + || PyObject_IsInstance(ev, PyExc_StopIteration)) { + value = ((PyStopIterationObject *)ev)->value; + Py_INCREF(value); + Py_DECREF(ev); + } else if (et == PyExc_StopIteration) { + /* avoid normalisation and take ev as value */ + value = ev; + } else { + /* normalisation required */ + PyErr_NormalizeException(&et, &ev, &tb); + if (!PyObject_IsInstance(ev, PyExc_StopIteration)) { + PyErr_Restore(et, ev, tb); + return -1; + } + value = ((PyStopIterationObject *)ev)->value; + Py_INCREF(value); + Py_DECREF(ev); + } } + Py_XDECREF(et); + Py_XDECREF(tb); } else if (PyErr_Occurred()) { return -1; }