Skip to content

Commit 102764a

Browse files
committed
Issue python#25021: Correctly make sure that product.__setstate__ does not access
invalid memory.
1 parent a82f77f commit 102764a

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

Lib/test/test_itertools.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -959,6 +959,16 @@ def test_product_pickling(self):
959959
self.assertEqual(list(copy.deepcopy(product(*args))), result)
960960
self.pickletest(product(*args))
961961

962+
def test_product_issue_25021(self):
963+
# test that indices are properly clamped to the length of the tuples
964+
p = product((1, 2),(3,))
965+
p.__setstate__((0, 0x1000)) # will access tuple element 1 if not clamped
966+
self.assertEqual(next(p), (2, 3))
967+
# test that empty tuple in the list will result in an immediate StopIteration
968+
p = product((1, 2), (), (3,))
969+
p.__setstate__((0, 0, 0x1000)) # will access tuple element 1 if not clamped
970+
self.assertRaises(StopIteration, next, p)
971+
962972
def test_repeat(self):
963973
self.assertEqual(list(repeat(object='a', times=3)), ['a', 'a', 'a'])
964974
self.assertEqual(lzip(range(3),repeat('a')),

Modules/itertoolsmodule.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2205,13 +2205,21 @@ product_setstate(productobject *lz, PyObject *state)
22052205
{
22062206
PyObject* indexObject = PyTuple_GET_ITEM(state, i);
22072207
Py_ssize_t index = PyLong_AsSsize_t(indexObject);
2208+
PyObject* pool;
2209+
Py_ssize_t poolsize;
22082210
if (index < 0 && PyErr_Occurred())
22092211
return NULL; /* not an integer */
2212+
pool = PyTuple_GET_ITEM(lz->pools, i);
2213+
poolsize = PyTuple_GET_SIZE(pool);
2214+
if (poolsize == 0) {
2215+
lz->stopped = 1;
2216+
Py_RETURN_NONE;
2217+
}
22102218
/* clamp the index */
22112219
if (index < 0)
22122220
index = 0;
2213-
else if (index > n-1)
2214-
index = n-1;
2221+
else if (index > poolsize-1)
2222+
index = poolsize-1;
22152223
lz->indices[i] = index;
22162224
}
22172225

0 commit comments

Comments
 (0)