[pypy-commit] pypy py3.5: Fix segfault in itertools.product.__setstate__
amauryfa
pypy.commits at gmail.com
Sun Oct 9 12:13:07 EDT 2016
Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: py3.5
Changeset: r87667:c03d2d2eff2f
Date: 2016-10-09 17:30 +0200
http://bitbucket.org/pypy/pypy/changeset/c03d2d2eff2f/
Log: Fix segfault in itertools.product.__setstate__ (CPython issue 25021)
diff --git a/pypy/module/itertools/interp_itertools.py b/pypy/module/itertools/interp_itertools.py
--- a/pypy/module/itertools/interp_itertools.py
+++ b/pypy/module/itertools/interp_itertools.py
@@ -1216,6 +1216,7 @@
#
for gear in self.gears:
if len(gear) == 0:
+ self.indices = None
self.lst = None
self.stopped = True
break
@@ -1303,12 +1304,16 @@
for i, gear in enumerate(self.gears):
w_index = indices_w[i]
index = space.int_w(w_index)
+ gear_size = len(gear)
+ if self.indices is None or gear_size == 0:
+ self.stopped = True
+ return
if index < 0:
index = 0
- if index > gear_count - 1:
- index = gear_count - 1
+ if index > gear_size - 1:
+ index = gear_size - 1
self.indices[i] = index
- lst.append(gear[self.indices[i]])
+ lst.append(gear[index])
self.lst = lst
def W_Product__new__(space, w_subtype, __args__):
diff --git a/pypy/module/itertools/test/test_itertools.py b/pypy/module/itertools/test/test_itertools.py
--- a/pypy/module/itertools/test/test_itertools.py
+++ b/pypy/module/itertools/test/test_itertools.py
@@ -820,6 +820,20 @@
assert list(product('ab', '', 'ef')) == []
assert list(product('', 'cd', 'ef')) == []
+ def test_product_setstate(self):
+ # test that indices are properly clamped to the length of the tuples
+ from itertools import product
+ p = product((1, 2),(3,))
+ # will access tuple element 1 if not clamped
+ p.__setstate__((0, 0x1000))
+ assert next(p) == (2, 3)
+ # test that empty tuple in the list will result in an
+ # immediate StopIteration
+ p = product((1, 2), (), (3,))
+ # will access tuple element 1 if not clamped
+ p.__setstate__((0, 0, 0x1000))
+ raises(StopIteration, next, p)
+
def test_permutations(self):
from itertools import permutations
assert list(permutations('AB')) == [('A', 'B'), ('B', 'A')]
More information about the pypy-commit
mailing list