diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2013-01-25 11:19:31 (GMT) |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2013-01-25 11:19:31 (GMT) |
commit | a3e9128aba49b99451b19b49982b7b48e4f7ffe6 (patch) | |
tree | 768d8e543f44a9747172e84fe97094a42cf6bb0f /Modules/itertoolsmodule.c | |
parent | 2f2dd992a3b73ee320834916e678be7762c06383 (diff) | |
download | cpython-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.c | 21 |
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; |