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.
This commit is contained in:
Serhiy Storchaka 2024-01-31 13:11:35 +02:00 committed by GitHub
parent 7a93db4425
commit b7688ef71e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 19 additions and 2 deletions

View File

@ -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):

View File

@ -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.

View File

@ -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;
}

View File

@ -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) {