]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-114685: Check flags in PyObject_GetBuffer() (GH-114707)
authorSerhiy Storchaka <storchaka@gmail.com>
Wed, 31 Jan 2024 11:11:35 +0000 (13:11 +0200)
committerGitHub <noreply@github.com>
Wed, 31 Jan 2024 11:11:35 +0000 (13:11 +0200)
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.

Lib/test/test_buffer.py
Misc/NEWS.d/next/C API/2024-01-29-12-13-24.gh-issue-114685.B07RME.rst [new file with mode: 0644]
Modules/_testcapi/buffer.c
Objects/abstract.c

index 72a06d6af450e328253cb00dc4084ed96ff897f4..535b795f508a2420802d2f34e463f2b1dbe6eed7 100644 (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):
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 (file)
index 0000000..55b02d1
--- /dev/null
@@ -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.
index 942774156c6c47f95a221166b568e35286d5665d..7e2f6e5e29482c2121cb9272bb3416a3da2f1ff9 100644 (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;
 }
 
index 1ec5c5b8c3dc2f591a6cbfd656f91cf6853090a4..daf04eb4ab2cda37a5a097c1700fd32e350c3289 100644 (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) {