diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2013-04-06 18:20:30 (GMT) |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2013-04-06 18:20:30 (GMT) |
commit | aac81e2780a181f4076190a28cde3e4bfaab614b (patch) | |
tree | 1886a2923e5959ce59f294558ba2122c3497366c /Python | |
parent | c53fd51278fe37a8d57968267452bf06d8db609c (diff) | |
parent | e8f706eda77db200728fc436dca20f0591eeec27 (diff) | |
download | cpython-aac81e2780a181f4076190a28cde3e4bfaab614b.zip cpython-aac81e2780a181f4076190a28cde3e4bfaab614b.tar.gz cpython-aac81e2780a181f4076190a28cde3e4bfaab614b.tar.bz2 |
Issue #14010: Fix a crash when iterating or deleting deeply nested filters
(builting and in itertools module, i.e. map(), itertools.chain(), etc).
Diffstat (limited to 'Python')
-rw-r--r-- | Python/bltinmodule.c | 30 |
1 files changed, 21 insertions, 9 deletions
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index a486b49..6344c68 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -391,9 +391,11 @@ static void filter_dealloc(filterobject *lz) { PyObject_GC_UnTrack(lz); + Py_TRASHCAN_SAFE_BEGIN(lz) Py_XDECREF(lz->func); Py_XDECREF(lz->it); Py_TYPE(lz)->tp_free(lz); + Py_TRASHCAN_SAFE_END(lz) } static int @@ -414,7 +416,10 @@ filter_next(filterobject *lz) iternext = *Py_TYPE(it)->tp_iternext; for (;;) { + if (Py_EnterRecursiveCall(" while iterating")) + return NULL; item = iternext(it); + Py_LeaveRecursiveCall(); if (item == NULL) return NULL; @@ -1031,9 +1036,11 @@ static void map_dealloc(mapobject *lz) { PyObject_GC_UnTrack(lz); + Py_TRASHCAN_SAFE_BEGIN(lz) Py_XDECREF(lz->iters); Py_XDECREF(lz->func); Py_TYPE(lz)->tp_free(lz); + Py_TRASHCAN_SAFE_END(lz) } static int @@ -2220,9 +2227,11 @@ static void zip_dealloc(zipobject *lz) { PyObject_GC_UnTrack(lz); + Py_TRASHCAN_SAFE_BEGIN(lz) Py_XDECREF(lz->ittuple); Py_XDECREF(lz->result); Py_TYPE(lz)->tp_free(lz); + Py_TRASHCAN_SAFE_END(lz) } static int @@ -2245,15 +2254,15 @@ zip_next(zipobject *lz) if (tuplesize == 0) return NULL; + if (Py_EnterRecursiveCall(" while iterating")) + return NULL; if (Py_REFCNT(result) == 1) { Py_INCREF(result); for (i=0 ; i < tuplesize ; i++) { it = PyTuple_GET_ITEM(lz->ittuple, i); item = (*Py_TYPE(it)->tp_iternext)(it); - if (item == NULL) { - Py_DECREF(result); - return NULL; - } + if (item == NULL) + goto error; olditem = PyTuple_GET_ITEM(result, i); PyTuple_SET_ITEM(result, i, item); Py_DECREF(olditem); @@ -2261,18 +2270,21 @@ zip_next(zipobject *lz) } else { result = PyTuple_New(tuplesize); if (result == NULL) - return NULL; + goto error; for (i=0 ; i < tuplesize ; i++) { it = PyTuple_GET_ITEM(lz->ittuple, i); item = (*Py_TYPE(it)->tp_iternext)(it); - if (item == NULL) { - Py_DECREF(result); - return NULL; - } + if (item == NULL) + goto error; PyTuple_SET_ITEM(result, i, item); } } + Py_LeaveRecursiveCall(); return result; +error: + Py_XDECREF(result); + Py_LeaveRecursiveCall(); + return NULL; } static PyObject * |