summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2013-04-06 18:20:30 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2013-04-06 18:20:30 (GMT)
commitaac81e2780a181f4076190a28cde3e4bfaab614b (patch)
tree1886a2923e5959ce59f294558ba2122c3497366c /Python
parentc53fd51278fe37a8d57968267452bf06d8db609c (diff)
parente8f706eda77db200728fc436dca20f0591eeec27 (diff)
downloadcpython-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.c30
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 *