https://github.com/python/cpython/commit/522563549a49d28e763635c58274a23a6055f041
commit: 522563549a49d28e763635c58274a23a6055f041
branch: main
author: Serhiy Storchaka <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2025-12-28T12:30:36Z
summary:
gh-143003: Fix possible shared buffer overflow in bytearray.extend() (GH-143086)
When __length_hint__() returns 0 for non-empty iterator, the data can be
written past the shared 0-terminated buffer, corrupting it.
files:
A
Misc/NEWS.d/next/Core_and_Builtins/2025-12-23-00-13-02.gh-issue-143003.92g5qW.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 e0baeece34c7b3..c42c0d4f5e9bc2 100644
--- a/Lib/test/test_bytes.py
+++ b/Lib/test/test_bytes.py
@@ -2104,6 +2104,23 @@ def make_case():
with self.assertRaises(BufferError):
ba.rsplit(evil)
+ def test_extend_empty_buffer_overflow(self):
+ # gh-143003
+ class EvilIter:
+ def __iter__(self):
+ return self
+ def __next__(self):
+ return next(source)
+ def __length_hint__(self):
+ return 0
+
+ # Use ASCII digits so float() takes the fast path that expects a NUL
terminator.
+ source = iter(b'42')
+ ba = bytearray()
+ ba.extend(EvilIter())
+
+ self.assertRaises(ValueError, float, bytearray())
+
def test_hex_use_after_free(self):
# Prevent UAF in bytearray.hex(sep) with re-entrant sep.__len__.
# Regression test for https://github.com/python/cpython/issues/143195.
diff --git
a/Misc/NEWS.d/next/Core_and_Builtins/2025-12-23-00-13-02.gh-issue-143003.92g5qW.rst
b/Misc/NEWS.d/next/Core_and_Builtins/2025-12-23-00-13-02.gh-issue-143003.92g5qW.rst
new file mode 100644
index 00000000000000..30df3c53abd29f
--- /dev/null
+++
b/Misc/NEWS.d/next/Core_and_Builtins/2025-12-23-00-13-02.gh-issue-143003.92g5qW.rst
@@ -0,0 +1,2 @@
+Fix an overflow of the shared empty buffer in :meth:`bytearray.extend` when
+``__length_hint__()`` returns 0 for non-empty iterator.
diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c
index 5262ac20c07300..7f09769e12f05f 100644
--- a/Objects/bytearrayobject.c
+++ b/Objects/bytearrayobject.c
@@ -2223,7 +2223,6 @@ bytearray_extend_impl(PyByteArrayObject *self, PyObject
*iterable_of_ints)
Py_DECREF(bytearray_obj);
return NULL;
}
- buf[len++] = value;
Py_DECREF(item);
if (len >= buf_size) {
@@ -2233,7 +2232,7 @@ bytearray_extend_impl(PyByteArrayObject *self, PyObject
*iterable_of_ints)
Py_DECREF(bytearray_obj);
return PyErr_NoMemory();
}
- addition = len >> 1;
+ addition = len ? len >> 1 : 1;
if (addition > PyByteArray_SIZE_MAX - len)
buf_size = PyByteArray_SIZE_MAX;
else
@@ -2247,6 +2246,7 @@ bytearray_extend_impl(PyByteArrayObject *self, PyObject
*iterable_of_ints)
have invalidated it. */
buf = PyByteArray_AS_STRING(bytearray_obj);
}
+ buf[len++] = value;
}
Py_DECREF(it);
_______________________________________________
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]