From 3fae84fe58d3da70ceca28f01647a38a590547b6 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Tue, 19 Nov 2024 20:37:53 +0300 Subject: [PATCH] [3.13] gh-126980: Fix `bytearray.__buffer__` crash on `PyBUF_{READ,WRITE}` (GH-126981) (#127023) (cherry picked from commit 3932e1db5353bbcf3e3c1133cc9d2cde654cb645) Co-authored-by: Victor Stinner --- Lib/test/test_buffer.py | 8 ++++++++ .../2024-11-18-23-18-17.gh-issue-126980.r8QHdi.rst | 3 +++ Objects/bytearrayobject.c | 8 ++++---- 3 files changed, 15 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-11-18-23-18-17.gh-issue-126980.r8QHdi.rst diff --git a/Lib/test/test_buffer.py b/Lib/test/test_buffer.py index e1048411710..d20280ca834 100644 --- a/Lib/test/test_buffer.py +++ b/Lib/test/test_buffer.py @@ -4439,6 +4439,14 @@ class TestBufferProtocol(unittest.TestCase): x = ndarray([1,2,3], shape=[3], flags=ND_GETBUF_FAIL) self.assertRaises(BufferError, memoryview, x) + def test_bytearray_release_buffer_read_flag(self): + # See https://github.com/python/cpython/issues/126980 + obj = bytearray(b'abc') + with self.assertRaises(SystemError): + obj.__buffer__(inspect.BufferFlags.READ) + with self.assertRaises(SystemError): + obj.__buffer__(inspect.BufferFlags.WRITE) + @support.cpython_only def test_pybuffer_size_from_format(self): # basic tests diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-11-18-23-18-17.gh-issue-126980.r8QHdi.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-11-18-23-18-17.gh-issue-126980.r8QHdi.rst new file mode 100644 index 00000000000..84484e7c300 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2024-11-18-23-18-17.gh-issue-126980.r8QHdi.rst @@ -0,0 +1,3 @@ +Fix :meth:`~object.__buffer__` of :class:`bytearray` crashing when +:attr:`~inspect.BufferFlags.READ` or :attr:`~inspect.BufferFlags.WRITE` are +passed as flags. diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 80679f93cd4..a67f41bbfc7 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -44,15 +44,15 @@ _getbytevalue(PyObject* arg, int *value) static int bytearray_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags) { - void *ptr; if (view == NULL) { PyErr_SetString(PyExc_BufferError, "bytearray_getbuffer: view==NULL argument is obsolete"); return -1; } - ptr = (void *) PyByteArray_AS_STRING(obj); - /* cannot fail if view != NULL and readonly == 0 */ - (void)PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags); + void *ptr = (void *) PyByteArray_AS_STRING(obj); + if (PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags) < 0) { + return -1; + } obj->ob_exports++; return 0; }