From: Serhiy Storchaka Date: Wed, 31 Jan 2024 11:11:35 +0000 (+0200) Subject: gh-114685: Check flags in PyObject_GetBuffer() (GH-114707) X-Git-Tag: v3.13.0a4~239 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b7688ef71eddcaf14f71b1c22ff2f164f34b2c74;p=thirdparty%2FPython%2Fcpython.git gh-114685: Check flags in PyObject_GetBuffer() (GH-114707) PyObject_GetBuffer() now raises a SystemError if called with PyBUF_READ or PyBUF_WRITE as flags. These flags should only be used with the PyMemoryView_* C API. --- diff --git a/Lib/test/test_buffer.py b/Lib/test/test_buffer.py index 72a06d6af450..535b795f508a 100644 --- a/Lib/test/test_buffer.py +++ b/Lib/test/test_buffer.py @@ -4585,6 +4585,12 @@ class TestPythonBufferProtocol(unittest.TestCase): buf.__release_buffer__(mv) self.assertEqual(buf.references, 0) + @unittest.skipIf(_testcapi is None, "requires _testcapi") + def test_c_buffer_invalid_flags(self): + buf = _testcapi.testBuf() + self.assertRaises(SystemError, buf.__buffer__, PyBUF_READ) + self.assertRaises(SystemError, buf.__buffer__, PyBUF_WRITE) + def test_inheritance(self): class A(bytearray): def __buffer__(self, flags): diff --git a/Misc/NEWS.d/next/C API/2024-01-29-12-13-24.gh-issue-114685.B07RME.rst b/Misc/NEWS.d/next/C API/2024-01-29-12-13-24.gh-issue-114685.B07RME.rst new file mode 100644 index 000000000000..55b02d1d8e1e --- /dev/null +++ b/Misc/NEWS.d/next/C API/2024-01-29-12-13-24.gh-issue-114685.B07RME.rst @@ -0,0 +1,3 @@ +:c:func:`PyObject_GetBuffer` now raises a :exc:`SystemError` if called with +:c:macro:`PyBUF_READ` or :c:macro:`PyBUF_WRITE` as flags. These flags should +only be used with the ``PyMemoryView_*`` C API. diff --git a/Modules/_testcapi/buffer.c b/Modules/_testcapi/buffer.c index 942774156c6c..7e2f6e5e2948 100644 --- a/Modules/_testcapi/buffer.c +++ b/Modules/_testcapi/buffer.c @@ -54,8 +54,10 @@ static int testbuf_getbuf(testBufObject *self, Py_buffer *view, int flags) { int buf = PyObject_GetBuffer(self->obj, view, flags); - Py_SETREF(view->obj, Py_NewRef(self)); - self->references++; + if (buf == 0) { + Py_SETREF(view->obj, Py_NewRef(self)); + self->references++; + } return buf; } diff --git a/Objects/abstract.c b/Objects/abstract.c index 1ec5c5b8c3dc..daf04eb4ab2c 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -425,6 +425,12 @@ PyObject_AsWriteBuffer(PyObject *obj, int PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags) { + if (flags != PyBUF_SIMPLE) { /* fast path */ + if (flags == PyBUF_READ || flags == PyBUF_WRITE) { + PyErr_BadInternalCall(); + return -1; + } + } PyBufferProcs *pb = Py_TYPE(obj)->tp_as_buffer; if (pb == NULL || pb->bf_getbuffer == NULL) {