diff options
author | Antoine Pitrou <solipsis@pitrou.net> | 2015-04-26 16:48:16 (GMT) |
---|---|---|
committer | Antoine Pitrou <solipsis@pitrou.net> | 2015-04-26 16:48:16 (GMT) |
commit | 7503509f196044e60d7506115a5919ad3eff6c58 (patch) | |
tree | 2606ccd9d3e4c7fc987651f3403de2f461076896 /Objects/genobject.c | |
parent | a7edf1e57cfae67e5734457be812cdd55a32a062 (diff) | |
parent | 7403e91630456ae2a495ac7621c2152d9a270400 (diff) | |
download | cpython-7503509f196044e60d7506115a5919ad3eff6c58.zip cpython-7503509f196044e60d7506115a5919ad3eff6c58.tar.gz cpython-7503509f196044e60d7506115a5919ad3eff6c58.tar.bz2 |
Issue #23996: Avoid a crash when a delegated generator raises an unnormalized StopIteration exception. Patch by Stefan Behnel.
Diffstat (limited to 'Objects/genobject.c')
-rw-r--r-- | Objects/genobject.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/Objects/genobject.c b/Objects/genobject.c index 4be739a..87060f3 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; } |