mirror of
https://github.com/python/cpython.git
synced 2026-01-26 21:03:34 +00:00
[3.14] gh-143003: Fix possible shared buffer overflow in bytearray.extend() (GH-143086) (GH-143447)
When __length_hint__() returns 0 for non-empty iterator, the data can be written past the shared 0-terminated buffer, corrupting it. (cherry picked from commit 522563549a49d28e763635c58274a23a6055f041) Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
This commit is contained in:
parent
c889ff6ba5
commit
9f91278412
@ -2013,6 +2013,23 @@ class ByteArrayTest(BaseBytesTest, unittest.TestCase):
|
||||
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.
|
||||
|
||||
@ -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.
|
||||
@ -2182,7 +2182,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) {
|
||||
@ -2192,7 +2191,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 > PY_SSIZE_T_MAX - len - 1)
|
||||
buf_size = PY_SSIZE_T_MAX;
|
||||
else
|
||||
@ -2206,6 +2205,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);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user