https://github.com/python/cpython/commit/8cf3fecd6fc8e8bac1e41eea836ac729ed73756c
commit: 8cf3fecd6fc8e8bac1e41eea836ac729ed73756c
branch: 3.14
author: Gregory P. Smith <[email protected]>
committer: gpshead <[email protected]>
date: 2026-10-22T05:54:51Z
summary:
[3.14] gh-160179: Leave bytearray empty when __init__() fails midway
(GH-160180) (#160204)
The list/tuple fast path and the buffer path resized the object before
filling it and did not undo the resize on error, leaving stale bytes.
(cherry picked from commit 5a63d3568197ac470561e95cbc744c1bc679f80d)
files:
A
Misc/NEWS.d/next/Core_and_Builtins/2026-10-22-00-30-02.gh-issue-160179.dQ2e7m.rst
M Lib/test/test_bytes.py
M Objects/bytearrayobject.c
diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py
index 0e4127588ad9e3..d180de1884a2f6 100644
--- a/Lib/test/test_bytes.py
+++ b/Lib/test/test_bytes.py
@@ -2151,6 +2151,16 @@ def __len__(self):
self.assertRaises(BufferError, ba.hex, S(b':'))
+ def test_reinit_error(self):
+ # A failed __init__() must not leave uninitialized bytes in the
+ # object: it must be empty afterwards.
+ for source in ([256] * 100, (-1,) * 100, [0] * 50 + [1000],
+ (1, 2, 1 << 100)):
+ with self.subTest(source=source):
+ a = bytearray(b"abc")
+ self.assertRaises(ValueError, a.__init__, source)
+ self.assertEqual(a, b"")
+
class AssortedBytesTest(unittest.TestCase):
#
diff --git
a/Misc/NEWS.d/next/Core_and_Builtins/2026-10-22-00-30-02.gh-issue-160179.dQ2e7m.rst
b/Misc/NEWS.d/next/Core_and_Builtins/2026-10-22-00-30-02.gh-issue-160179.dQ2e7m.rst
new file mode 100644
index 00000000000000..5377e59a60ea48
--- /dev/null
+++
b/Misc/NEWS.d/next/Core_and_Builtins/2026-10-22-00-30-02.gh-issue-160179.dQ2e7m.rst
@@ -0,0 +1,3 @@
+Fix :meth:`!bytearray.__init__` leaving uninitialized memory in the object
+when it fails on a :class:`list` or :class:`tuple` containing an integer not
+in ``range(256)``. The object is now empty after the failed call.
diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c
index e8d47e50d7f7a8..5486c0353d7173 100644
--- a/Objects/bytearrayobject.c
+++ b/Objects/bytearrayobject.c
@@ -1000,7 +1000,11 @@ bytearray___init___impl(PyByteArrayObject *self,
PyObject *arg,
if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
if (PyBuffer_ToContiguous(PyByteArray_AS_STRING(self),
&view, size, 'C') < 0)
+ {
+ /* Don't expose the uninitialized bytes: reset to empty */
+ (void)PyByteArray_Resize((PyObject *)self, 0);
goto fail;
+ }
PyBuffer_Release(&view);
return 0;
fail:
@@ -1028,6 +1032,8 @@ bytearray___init___impl(PyByteArrayObject *self, PyObject
*arg,
}
int rc = _getbytevalue(items[i], &value);
if (!rc) {
+ /* Don't expose the uninitialized bytes: reset to empty */
+ (void)PyByteArray_Resize((PyObject *)self, 0);
return -1;
}
s[i] = value;
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]