https://github.com/python/cpython/commit/5a63d3568197ac470561e95cbc744c1bc679f80d
commit: 5a63d3568197ac470561e95cbc744c1bc679f80d
branch: main
author: Gregory P. Smith <[email protected]>
committer: gpshead <[email protected]>
date: 2026-10-21T22:20:54-07:00
summary:
gh-160179: Leave bytearray empty when __init__() fails midway (GH-160180)
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.
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 05faad4532b867..9c36fbed9eb19a 100644
--- a/Lib/test/test_bytes.py
+++ b/Lib/test/test_bytes.py
@@ -2499,6 +2499,16 @@ def test_reinit_with_view(self):
self.assertRaises(BufferError, a.__init__, "x", "ascii")
self.assertEqual(a, 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 4a2f088a246c3e..dfd041b0152bdd 100644
--- a/Objects/bytearrayobject.c
+++ b/Objects/bytearrayobject.c
@@ -1084,7 +1084,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:
@@ -1112,6 +1116,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]