]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.11] gh-112625: Protect bytearray from being freed by misbehaving iterator inside...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Mon, 4 Dec 2023 08:37:25 +0000 (09:37 +0100)
committerGitHub <noreply@github.com>
Mon, 4 Dec 2023 08:37:25 +0000 (10:37 +0200)
(cherry picked from commit 0e732d0997cff08855d98c17af4dd5527f10e419)

Co-authored-by: chilaxan <chilaxan@gmail.com>
Lib/test/test_builtin.py
Misc/NEWS.d/next/Core and Builtins/2023-12-03-19-34-51.gh-issue-112625.QWTlwS.rst [new file with mode: 0644]
Objects/bytearrayobject.c

index d6edc2b431d32a7afd60f3d0776c71dfd785f3e4..a34f6daaad69238f34c81540b2d98c29223d8bbe 100644 (file)
@@ -1987,6 +1987,23 @@ class BuiltinTest(unittest.TestCase):
         bad_iter = map(int, "X")
         self.assertRaises(ValueError, array.extend, bad_iter)
 
+    def test_bytearray_join_with_misbehaving_iterator(self):
+        # Issue #112625
+        array = bytearray(b',')
+        def iterator():
+            array.clear()
+            yield b'A'
+            yield b'B'
+        self.assertRaises(BufferError, array.join, iterator())
+
+    def test_bytearray_join_with_custom_iterator(self):
+        # Issue #112625
+        array = bytearray(b',')
+        def iterator():
+            yield b'A'
+            yield b'B'
+        self.assertEqual(bytearray(b'A,B'), array.join(iterator()))
+
     def test_construct_singletons(self):
         for const in None, Ellipsis, NotImplemented:
             tp = type(const)
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-12-03-19-34-51.gh-issue-112625.QWTlwS.rst b/Misc/NEWS.d/next/Core and Builtins/2023-12-03-19-34-51.gh-issue-112625.QWTlwS.rst
new file mode 100644 (file)
index 0000000..4970e10
--- /dev/null
@@ -0,0 +1 @@
+Fixes a bug where a bytearray object could be cleared while iterating over an argument in the ``bytearray.join()`` method that could result in reading memory after it was freed.
index 6d46ebe2a4480878311cbc7f8bdd02b59fad4de3..1c5020308421204e83580da955049a1bee366177 100644 (file)
@@ -2008,7 +2008,10 @@ static PyObject *
 bytearray_join(PyByteArrayObject *self, PyObject *iterable_of_bytes)
 /*[clinic end generated code: output=a8516370bf68ae08 input=aba6b1f9b30fcb8e]*/
 {
-    return stringlib_bytes_join((PyObject*)self, iterable_of_bytes);
+    self->ob_exports++; // this protects `self` from being cleared/resized if `iterable_of_bytes` is a custom iterator
+    PyObject* ret = stringlib_bytes_join((PyObject*)self, iterable_of_bytes);
+    self->ob_exports--; // unexport `self`
+    return ret;
 }
 
 /*[clinic input]