diff -r 22f2784a276e -r 5f0cddb01246 Lib/test/test_iter.py --- a/Lib/test/test_iter.py Fri Dec 05 10:18:30 2014 +0100 +++ b/Lib/test/test_iter.py Sun Dec 07 21:54:17 2014 +0100 @@ -1,5 +1,6 @@ # Test iterators. +import sys import unittest from test.support import run_unittest, TESTFN, unlink, cpython_only import pickle @@ -918,6 +919,31 @@ lst.extend(gen()) self.assertEqual(len(lst), 760) + @cpython_only + def test_iter_overflow(self): + # Test for the issue 22939 + class X(object): + def __getitem__(self, index): + return index + + it = iter(X()) + # Manually set `it_index` to PY_SSIZE_T_MAX without a loop + it.__setstate__(sys.maxsize) + with self.assertRaises(OverflowError): + next(it) + # Check that Overflow error is always raised + with self.assertRaises(OverflowError): + next(it) + + def test_iter_neg_setstate(self): + class X(object): + def __getitem__(self, index): + return index + + it = iter(X()) + it.__setstate__(-42) + self.assertEqual(next(it), 0) + def test_main(): run_unittest(TestCase) diff -r 22f2784a276e -r 5f0cddb01246 Objects/iterobject.c --- a/Objects/iterobject.c Fri Dec 05 10:18:30 2014 +0100 +++ b/Objects/iterobject.c Sun Dec 07 21:54:17 2014 +0100 @@ -54,6 +54,11 @@ seq = it->it_seq; if (seq == NULL) return NULL; + if (it->it_index == PY_SSIZE_T_MAX) { + PyErr_SetString(PyExc_OverflowError, + "iter index too large"); + return NULL; + } result = PySequence_GetItem(seq, it->it_index); if (result != NULL) {