From 9617a725733807e2420ee1753f94280e33a244c1 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Thu, 3 Sep 2026 04:52:08 +0300 Subject: [PATCH 1/2] gh-156864: correctly detect overflows for array's "e" type code --- Lib/test/test_array.py | 6 ++++++ .../Library/2026-09-03-04-51-46.gh-issue-156864.Pbe7Tl.rst | 2 ++ Modules/arraymodule.c | 4 ++-- 3 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-09-03-04-51-46.gh-issue-156864.Pbe7Tl.rst diff --git a/Lib/test/test_array.py b/Lib/test/test_array.py index c931be6df5fdaa2..534748cf1d4876b 100755 --- a/Lib/test/test_array.py +++ b/Lib/test/test_array.py @@ -1607,6 +1607,12 @@ class HalfFloatTest(FPTest, unittest.TestCase): typecode = 'e' minitemsize = 2 + def test_overflows(self): + # Overflows half-float type: + self.assertRaises(OverflowError, array.array, self.typecode, [123456]) + # Overflows also float type: + self.assertRaises(OverflowError, array.array, self.typecode, [1e300]) + class FloatTest(FPTest, unittest.TestCase): typecode = 'f' minitemsize = 4 diff --git a/Misc/NEWS.d/next/Library/2026-09-03-04-51-46.gh-issue-156864.Pbe7Tl.rst b/Misc/NEWS.d/next/Library/2026-09-03-04-51-46.gh-issue-156864.Pbe7Tl.rst new file mode 100644 index 000000000000000..8107976acd83150 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-09-03-04-51-46.gh-issue-156864.Pbe7Tl.rst @@ -0,0 +1,2 @@ +:func:`array.array` setter now correctly detects overflows for the ``'e'`` +type code. Patch by Sergey B Kirpichev. diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index a0181c083a60369..e045739dcd040c3 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -584,8 +584,8 @@ e_getitem(arrayobject *ap, Py_ssize_t i) static int e_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) { - float x; - if (!PyArg_Parse(v, "f;array item must be float", &x)) { + double x; + if (!PyArg_Parse(v, "d;array item must be float", &x)) { return -1; } From 9b4b7cf4852c13df6ed7cc0d2674a27a7c185f10 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Thu, 3 Sep 2026 07:52:03 +0300 Subject: [PATCH 2/2] fix also 'f' and 'Zf' --- Lib/test/test_array.py | 7 ++++++ ...-09-03-04-51-46.gh-issue-156864.Pbe7Tl.rst | 4 +-- Modules/arraymodule.c | 25 +++++++++++++------ 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/Lib/test/test_array.py b/Lib/test/test_array.py index 534748cf1d4876b..ba9c25c835bc39d 100755 --- a/Lib/test/test_array.py +++ b/Lib/test/test_array.py @@ -1617,6 +1617,9 @@ class FloatTest(FPTest, unittest.TestCase): typecode = 'f' minitemsize = 4 + def test_overflows(self): + self.assertRaises(OverflowError, array.array, self.typecode, [1e300]) + class DoubleTest(FPTest, unittest.TestCase): typecode = 'd' minitemsize = 8 @@ -1643,6 +1646,10 @@ class ComplexFloatTest(CFPTest, unittest.TestCase): typecode = 'Zf' minitemsize = 8 + def test_overflows(self): + self.assertRaises(OverflowError, array.array, self.typecode, [1e300]) + self.assertRaises(OverflowError, array.array, self.typecode, [1e300j]) + class ComplexDoubleTest(CFPTest, unittest.TestCase): typecode = 'Zd' minitemsize = 16 diff --git a/Misc/NEWS.d/next/Library/2026-09-03-04-51-46.gh-issue-156864.Pbe7Tl.rst b/Misc/NEWS.d/next/Library/2026-09-03-04-51-46.gh-issue-156864.Pbe7Tl.rst index 8107976acd83150..ee89b830d3d4869 100644 --- a/Misc/NEWS.d/next/Library/2026-09-03-04-51-46.gh-issue-156864.Pbe7Tl.rst +++ b/Misc/NEWS.d/next/Library/2026-09-03-04-51-46.gh-issue-156864.Pbe7Tl.rst @@ -1,2 +1,2 @@ -:func:`array.array` setter now correctly detects overflows for the ``'e'`` -type code. Patch by Sergey B Kirpichev. +:func:`array.array` setter now correctly detects overflows for the ``'e'``, +``'f'`` and ``'Zf'`` type codes. Patch by Sergey B Kirpichev. diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index e045739dcd040c3..ef492d143d56445 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -607,14 +607,16 @@ f_getitem(arrayobject *ap, Py_ssize_t i) static int f_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) { - float x; - if (!PyArg_Parse(v, "f;array item must be float", &x)) + double x; + if (!PyArg_Parse(v, "d;array item must be float", &x)) return -1; CHECK_ARRAY_BOUNDS(ap, i); - if (i >= 0) - ((float *)ap->ob_item)[i] = x; + if (i >= 0) { + return PyFloat_Pack4(x, ap->ob_item + sizeof(float)*i, + PY_LITTLE_ENDIAN); + } return 0; } @@ -651,7 +653,6 @@ static int cf_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) { Py_complex x; - float f[2]; if (!PyArg_Parse(v, "D;array item must be complex", &x)) { return -1; @@ -659,10 +660,18 @@ cf_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) CHECK_ARRAY_BOUNDS(ap, i); - f[0] = (float)x.real; - f[1] = (float)x.imag; if (i >= 0) { - memcpy(ap->ob_item + i*sizeof(f), &f, sizeof(f)); + char f[8]; + int ret = PyFloat_Pack4(x.real, f, PY_LITTLE_ENDIAN); + + if (ret) { + return ret; + } + ret = PyFloat_Pack4(x.imag, f + sizeof(float), PY_LITTLE_ENDIAN); + if (!ret) { + memcpy(ap->ob_item + i*sizeof(f), &f, sizeof(f)); + } + return ret; } return 0; }