summaryrefslogtreecommitdiffstats
path: root/Modules/itertoolsmodule.c
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2013-01-25 11:19:31 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2013-01-25 11:19:31 (GMT)
commita3e9128aba49b99451b19b49982b7b48e4f7ffe6 (patch)
tree768d8e543f44a9747172e84fe97094a42cf6bb0f /Modules/itertoolsmodule.c
parent2f2dd992a3b73ee320834916e678be7762c06383 (diff)
downloadcpython-a3e9128aba49b99451b19b49982b7b48e4f7ffe6.zip
cpython-a3e9128aba49b99451b19b49982b7b48e4f7ffe6.tar.gz
cpython-a3e9128aba49b99451b19b49982b7b48e4f7ffe6.tar.bz2
Issue #13454: Fix a crash when deleting an iterator created by itertools.tee()
if all other iterators were very advanced before.
Diffstat (limited to 'Modules/itertoolsmodule.c')
-rw-r--r--Modules/itertoolsmodule.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c
index 77e76fe..574eb68 100644
--- a/Modules/itertoolsmodule.c
+++ b/Modules/itertoolsmodule.c
@@ -401,14 +401,31 @@ teedataobject_traverse(teedataobject *tdo, visitproc visit, void * arg)
return 0;
}
+static void
+teedataobject_safe_decref(PyObject *obj)
+{
+ while (obj && Py_TYPE(obj) == &teedataobject_type &&
+ Py_REFCNT(obj) == 1) {
+ PyObject *nextlink = ((teedataobject *)obj)->nextlink;
+ ((teedataobject *)obj)->nextlink = NULL;
+ Py_DECREF(obj);
+ obj = nextlink;
+ }
+ Py_XDECREF(obj);
+}
+
static int
teedataobject_clear(teedataobject *tdo)
{
int i;
+ PyObject *tmp;
+
Py_CLEAR(tdo->it);
for (i=0 ; i<tdo->numread ; i++)
Py_CLEAR(tdo->values[i]);
- Py_CLEAR(tdo->nextlink);
+ tmp = tdo->nextlink;
+ tdo->nextlink = NULL;
+ teedataobject_safe_decref(tmp);
return 0;
}
@@ -475,6 +492,8 @@ tee_next(teeobject *to)
if (to->index >= LINKCELLS) {
link = teedataobject_jumplink(to->dataobj);
+ if (link == NULL)
+ return NULL;
Py_DECREF(to->dataobj);
to->dataobj = (teedataobject *)link;
to->index = 0;