diff -r 22f2784a276e -r 3eb3619911b9 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 Fri Dec 05 11:44:23 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,19 @@ class TestCase(unittest.TestCase): lst.extend(gen()) self.assertEqual(len(lst), 760) + 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) + next(it) + with self.assertRaises(OverflowError): + next(it) + def test_main(): run_unittest(TestCase) diff -r 22f2784a276e -r 3eb3619911b9 Objects/iterobject.c --- a/Objects/iterobject.c Fri Dec 05 10:18:30 2014 +0100 +++ b/Objects/iterobject.c Fri Dec 05 11:44:23 2014 +0100 @@ -54,9 +54,14 @@ iter_iternext(PyObject *iterator) seq = it->it_seq; if (seq == NULL) return NULL; - + if (it->it_index < 0) { + PyErr_SetString(PyExc_OverflowError, + "iter index too large"); + return NULL; + } result = PySequence_GetItem(seq, it->it_index); if (result != NULL) { + /* Overflow will be catched at the next call */ it->it_index++; return result; }