changeset: 95811:9d0c6c66b0ac parent: 95808:2d3ed019bc9f parent: 95810:15c80f63ea1c user: Antoine Pitrou date: Sun Apr 26 18:48:16 2015 +0200 files: Misc/NEWS Objects/genobject.c description: Issue #23996: Avoid a crash when a delegated generator raises an unnormalized StopIteration exception. Patch by Stefan Behnel. diff -r 2d3ed019bc9f -r 9d0c6c66b0ac Misc/NEWS --- a/Misc/NEWS Sun Apr 26 12:10:27 2015 +0300 +++ b/Misc/NEWS Sun Apr 26 18:48:16 2015 +0200 @@ -10,6 +10,9 @@ 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 #9951: Added a hex() method to bytes, bytearray, and memoryview. diff -r 2d3ed019bc9f -r 9d0c6c66b0ac Objects/genobject.c --- a/Objects/genobject.c Sun Apr 26 12:10:27 2015 +0300 +++ b/Objects/genobject.c Sun Apr 26 18:48:16 2015 +0200 @@ -396,13 +396,30 @@ if (PyErr_ExceptionMatches(PyExc_StopIteration)) { PyErr_Fetch(&et, &ev, &tb); + if (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); - if (ev) { - value = ((PyStopIterationObject *)ev)->value; - Py_INCREF(value); - Py_DECREF(ev); - } } else if (PyErr_Occurred()) { return -1; }