From decb25e8f0051cafcbe7d38171371cf47185165b Mon Sep 17 00:00:00 2001 From: Priyanshu Singh Date: Mon, 26 Jan 2026 17:43:49 +0530 Subject: [PATCH] gh-144128: Fix crash in array.fromlist with reentrant __index__ (#144138) Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> Co-authored-by: Peter Bierma Co-authored-by: Victor Stinner --- Lib/test/test_array.py | 17 +++++++++++++++ ...-01-22-10-18-17.gh-issue-144128.akwY06.rst | 2 ++ Modules/arraymodule.c | 21 +++++++++++++------ 3 files changed, 34 insertions(+), 6 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-01-22-10-18-17.gh-issue-144128.akwY06.rst diff --git a/Lib/test/test_array.py b/Lib/test/test_array.py index 83b3c978da35..b49df029f032 100755 --- a/Lib/test/test_array.py +++ b/Lib/test/test_array.py @@ -67,6 +67,23 @@ class MiscTest(unittest.TestCase): a += a self.assertEqual(len(a), 0) + def test_fromlist_reentrant_index_mutation(self): + + class Evil: + def __init__(self, lst): + self.lst = lst + def __index__(self): + self.lst.clear() + return "not an int" + + for typecode in ('I', 'L', 'Q'): + with self.subTest(typecode=typecode): + lst = [] + lst.append(Evil(lst)) + a = array.array(typecode) + with self.assertRaises(TypeError): + a.fromlist(lst) + # Machine format codes. # diff --git a/Misc/NEWS.d/next/Library/2026-01-22-10-18-17.gh-issue-144128.akwY06.rst b/Misc/NEWS.d/next/Library/2026-01-22-10-18-17.gh-issue-144128.akwY06.rst new file mode 100644 index 000000000000..4010695aec98 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-01-22-10-18-17.gh-issue-144128.akwY06.rst @@ -0,0 +1,2 @@ +Fix a crash in :meth:`array.array.fromlist` when an element's :meth:`~object.__index__` method mutates +the input list during conversion. diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index 729e085c19f0..5769a796b189 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -408,10 +408,13 @@ II_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) int do_decref = 0; /* if nb_int was called */ if (!PyLong_Check(v)) { - v = _PyNumber_Index(v); - if (NULL == v) { + Py_INCREF(v); + PyObject *res = _PyNumber_Index(v); + Py_DECREF(v); + if (NULL == res) { return -1; } + v = res; do_decref = 1; } x = PyLong_AsUnsignedLong(v); @@ -468,10 +471,13 @@ LL_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) int do_decref = 0; /* if nb_int was called */ if (!PyLong_Check(v)) { - v = _PyNumber_Index(v); - if (NULL == v) { + Py_INCREF(v); + PyObject *res = _PyNumber_Index(v); + Py_DECREF(v); + if (NULL == res) { return -1; } + v = res; do_decref = 1; } x = PyLong_AsUnsignedLong(v); @@ -521,10 +527,13 @@ QQ_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) int do_decref = 0; /* if nb_int was called */ if (!PyLong_Check(v)) { - v = _PyNumber_Index(v); - if (NULL == v) { + Py_INCREF(v); + PyObject *res = _PyNumber_Index(v); + Py_DECREF(v); + if (NULL == res) { return -1; } + v = res; do_decref = 1; } x = PyLong_AsUnsignedLongLong(v); -- 2.47.3