From c75894a36b13f2dd1bfdd72695dd904260b7ef78 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sat, 18 Jan 2025 11:17:42 +0100 Subject: [PATCH] [3.13] gh-128961: Fix exhausted array iterator crash in __setstate__() (GH-128962) (#128976) (cherry picked from commit 4dade055f4e18a7e91bc70293abb4db745ad16ca) Co-authored-by: Tomasz Pytel --- Lib/test/test_array.py | 8 ++++++++ ...2025-01-17-21-33-11.gh-issue-128961.XwvyIZ.rst | 1 + Modules/arraymodule.c | 15 ++++++++++----- 3 files changed, 19 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2025-01-17-21-33-11.gh-issue-128961.XwvyIZ.rst diff --git a/Lib/test/test_array.py b/Lib/test/test_array.py index 47cbe60bfca4e4..f0e32befd6628d 100755 --- a/Lib/test/test_array.py +++ b/Lib/test/test_array.py @@ -1665,5 +1665,13 @@ def test_tolist(self, size): self.assertEqual(ls[:8], list(example[:8])) self.assertEqual(ls[-8:], list(example[-8:])) + def test_gh_128961(self): + a = array.array('i') + it = iter(a) + list(it) + it.__setstate__(0) + self.assertRaises(StopIteration, next, it) + + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Library/2025-01-17-21-33-11.gh-issue-128961.XwvyIZ.rst b/Misc/NEWS.d/next/Library/2025-01-17-21-33-11.gh-issue-128961.XwvyIZ.rst new file mode 100644 index 00000000000000..9c985df77743da --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-01-17-21-33-11.gh-issue-128961.XwvyIZ.rst @@ -0,0 +1 @@ +Fix a crash when setting state on an exhausted :class:`array.array` iterator. diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index 679222c3f03d23..600302e1183f99 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -3074,11 +3074,16 @@ array_arrayiterator___setstate__(arrayiterobject *self, PyObject *state) Py_ssize_t index = PyLong_AsSsize_t(state); if (index == -1 && PyErr_Occurred()) return NULL; - if (index < 0) - index = 0; - else if (index > Py_SIZE(self->ao)) - index = Py_SIZE(self->ao); /* iterator exhausted */ - self->index = index; + arrayobject *ao = self->ao; + if (ao != NULL) { + if (index < 0) { + index = 0; + } + else if (index > Py_SIZE(ao)) { + index = Py_SIZE(ao); /* iterator exhausted */ + } + self->index = index; + } Py_RETURN_NONE; }