[Python-checkins] cpython (merge 3.4 -> default): Issue #23996: Avoid a crash when a delegated generator raises an unnormalized

antoine.pitrou python-checkins at python.org
Sun Apr 26 18:49:47 CEST 2015


https://hg.python.org/cpython/rev/9d0c6c66b0ac
changeset:   95811:9d0c6c66b0ac
parent:      95808:2d3ed019bc9f
parent:      95810:15c80f63ea1c
user:        Antoine Pitrou <solipsis at pitrou.net>
date:        Sun Apr 26 18:48:16 2015 +0200
summary:
  Issue #23996: Avoid a crash when a delegated generator raises an unnormalized StopIteration exception.  Patch by Stefan Behnel.

files:
  Misc/NEWS           |   3 +++
  Objects/genobject.c |  27 ++++++++++++++++++++++-----
  2 files changed, 25 insertions(+), 5 deletions(-)


diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -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 --git a/Objects/genobject.c b/Objects/genobject.c
--- a/Objects/genobject.c
+++ b/Objects/genobject.c
@@ -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;
     }

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list