[Python-checkins] cpython (merge 3.2 -> 3.3): Issue #13454: Fix a crash when deleting an iterator created by itertools.tee()

serhiy.storchaka python-checkins at python.org
Fri Jan 25 12:35:13 CET 2013


http://hg.python.org/cpython/rev/eff2a7346243
changeset: 81701:eff2a7346243
branch: 3.3
parent: 81698:43907b88ce93
parent: 81700:f7e14a1af609
user: Serhiy Storchaka <storchaka at gmail.com>
date: Fri Jan 25 13:24:47 2013 +0200
summary:
 Issue #13454: Fix a crash when deleting an iterator created by itertools.tee()
if all other iterators were very advanced before.
files:
 Lib/test/test_itertools.py | 8 ++++++++
 Misc/NEWS | 3 +++
 Modules/itertoolsmodule.c | 21 ++++++++++++++++++++-
 3 files changed, 31 insertions(+), 1 deletions(-)
diff --git a/Lib/test/test_itertools.py b/Lib/test/test_itertools.py
--- a/Lib/test/test_itertools.py
+++ b/Lib/test/test_itertools.py
@@ -1267,6 +1267,14 @@
 self.pickletest(a, compare=ans)
 self.pickletest(b, compare=ans)
 
+ # Issue 13454: Crash when deleting backward iterator from tee()
+ def test_tee_del_backward(self):
+ forward, backward = tee(range(20000000))
+ for i in forward:
+ pass
+
+ del backward
+
 def test_StopIteration(self):
 self.assertRaises(StopIteration, next, zip())
 
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -150,6 +150,9 @@
 Library
 -------
 
+- Issue #13454: Fix a crash when deleting an iterator created by itertools.tee()
+ if all other iterators were very advanced before.
+
 - Issue #12411: Fix to cgi.parse_multipart to correctly use bytes boundaries
 and bytes data. Patch by Jonas Wagner.
 
diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c
--- a/Modules/itertoolsmodule.c
+++ b/Modules/itertoolsmodule.c
@@ -473,14 +473,31 @@
 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;
 }
 
@@ -617,6 +634,8 @@
 
 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;
-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /