diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2013-04-06 18:14:43 (GMT) |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2013-04-06 18:14:43 (GMT) |
commit | e8f706eda77db200728fc436dca20f0591eeec27 (patch) | |
tree | 7f47f633fb9714389be706b84bc3ceb0559aae1a /Modules | |
parent | e16f4dc80ac71bea48c60d4620740d74975024c9 (diff) | |
download | cpython-e8f706eda77db200728fc436dca20f0591eeec27.zip cpython-e8f706eda77db200728fc436dca20f0591eeec27.tar.gz cpython-e8f706eda77db200728fc436dca20f0591eeec27.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 'Modules')
-rw-r--r-- | Modules/itertoolsmodule.c | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index 644104e..74c5d98 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -54,12 +54,14 @@ static void groupby_dealloc(groupbyobject *gbo) { PyObject_GC_UnTrack(gbo); + Py_TRASHCAN_SAFE_BEGIN(gbo) Py_XDECREF(gbo->it); Py_XDECREF(gbo->keyfunc); Py_XDECREF(gbo->tgtkey); Py_XDECREF(gbo->currkey); Py_XDECREF(gbo->currvalue); Py_TYPE(gbo)->tp_free(gbo); + Py_TRASHCAN_SAFE_END(gbo) } static int @@ -911,9 +913,11 @@ static void cycle_dealloc(cycleobject *lz) { PyObject_GC_UnTrack(lz); + Py_TRASHCAN_SAFE_BEGIN(lz) Py_XDECREF(lz->saved); Py_XDECREF(lz->it); Py_TYPE(lz)->tp_free(lz); + Py_TRASHCAN_SAFE_END(lz) } static int @@ -1088,9 +1092,11 @@ static void dropwhile_dealloc(dropwhileobject *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 @@ -1111,7 +1117,10 @@ dropwhile_next(dropwhileobject *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; if (lz->start == 1) @@ -1257,9 +1266,11 @@ static void takewhile_dealloc(takewhileobject *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 @@ -1280,7 +1291,10 @@ takewhile_next(takewhileobject *lz) if (lz->stop == 1) return NULL; + if (Py_EnterRecursiveCall(" while iterating")) + return NULL; item = (*Py_TYPE(it)->tp_iternext)(it); + Py_LeaveRecursiveCall(); if (item == NULL) return NULL; @@ -1472,8 +1486,10 @@ static void islice_dealloc(isliceobject *lz) { PyObject_GC_UnTrack(lz); + Py_TRASHCAN_SAFE_BEGIN(lz) Py_XDECREF(lz->it); Py_TYPE(lz)->tp_free(lz); + Py_TRASHCAN_SAFE_END(lz) } static int @@ -1494,7 +1510,10 @@ islice_next(isliceobject *lz) iternext = *Py_TYPE(it)->tp_iternext; while (lz->cnt < lz->next) { + if (Py_EnterRecursiveCall(" while iterating")) + return NULL; item = iternext(it); + Py_LeaveRecursiveCall(); if (item == NULL) return NULL; Py_DECREF(item); @@ -1502,7 +1521,10 @@ islice_next(isliceobject *lz) } if (stop != -1 && lz->cnt >= stop) return NULL; + if (Py_EnterRecursiveCall(" while iterating")) + return NULL; item = iternext(it); + Py_LeaveRecursiveCall(); if (item == NULL) return NULL; lz->cnt++; @@ -1653,9 +1675,11 @@ static void starmap_dealloc(starmapobject *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 @@ -1673,7 +1697,10 @@ starmap_next(starmapobject *lz) PyObject *result; PyObject *it = lz->it; + if (Py_EnterRecursiveCall(" while iterating")) + return NULL; args = (*Py_TYPE(it)->tp_iternext)(it); + Py_LeaveRecursiveCall(); if (args == NULL) return NULL; if (!PyTuple_CheckExact(args)) { @@ -1809,9 +1836,11 @@ static void chain_dealloc(chainobject *lz) { PyObject_GC_UnTrack(lz); + Py_TRASHCAN_SAFE_BEGIN(lz) Py_XDECREF(lz->active); Py_XDECREF(lz->source); Py_TYPE(lz)->tp_free(lz); + Py_TRASHCAN_SAFE_END(lz) } static int @@ -3340,10 +3369,12 @@ static void accumulate_dealloc(accumulateobject *lz) { PyObject_GC_UnTrack(lz); + Py_TRASHCAN_SAFE_BEGIN(lz) Py_XDECREF(lz->binop); Py_XDECREF(lz->total); Py_XDECREF(lz->it); Py_TYPE(lz)->tp_free(lz); + Py_TRASHCAN_SAFE_END(lz) } static int @@ -3514,9 +3545,11 @@ static void compress_dealloc(compressobject *lz) { PyObject_GC_UnTrack(lz); + Py_TRASHCAN_SAFE_BEGIN(lz) Py_XDECREF(lz->data); Py_XDECREF(lz->selectors); Py_TYPE(lz)->tp_free(lz); + Py_TRASHCAN_SAFE_END(lz) } static int @@ -3543,11 +3576,16 @@ compress_next(compressobject *lz) exception first). */ + if (Py_EnterRecursiveCall(" while iterating")) + return NULL; datum = datanext(data); - if (datum == NULL) + if (datum == NULL) { + Py_LeaveRecursiveCall(); return NULL; + } selector = selectornext(selectors); + Py_LeaveRecursiveCall(); if (selector == NULL) { Py_DECREF(datum); return NULL; @@ -3674,9 +3712,11 @@ static void filterfalse_dealloc(filterfalseobject *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 @@ -3697,7 +3737,10 @@ filterfalse_next(filterfalseobject *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; @@ -4261,10 +4304,12 @@ static void zip_longest_dealloc(ziplongestobject *lz) { PyObject_GC_UnTrack(lz); + Py_TRASHCAN_SAFE_BEGIN(lz) Py_XDECREF(lz->ittuple); Py_XDECREF(lz->result); Py_XDECREF(lz->fillvalue); Py_TYPE(lz)->tp_free(lz); + Py_TRASHCAN_SAFE_END(lz) } static int |