summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2024-01-31 11:11:35 (GMT)
committerGitHub <noreply@github.com>2024-01-31 11:11:35 (GMT)
commitb7688ef71eddcaf14f71b1c22ff2f164f34b2c74 (patch)
tree08f81ce254f5876bd674d680c5e20050cf6f7c49
parent7a93db44257c0404dc407ff2ddc997f4bb8890ed (diff)
downloadcpython-b7688ef71eddcaf14f71b1c22ff2f164f34b2c74.zip
cpython-b7688ef71eddcaf14f71b1c22ff2f164f34b2c74.tar.gz
cpython-b7688ef71eddcaf14f71b1c22ff2f164f34b2c74.tar.bz2
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.
-rw-r--r--Lib/test/test_buffer.py6
-rw-r--r--Misc/NEWS.d/next/C API/2024-01-29-12-13-24.gh-issue-114685.B07RME.rst3
-rw-r--r--Modules/_testcapi/buffer.c6
-rw-r--r--Objects/abstract.c6
4 files changed, 19 insertions, 2 deletions
diff --git a/Lib/test/test_buffer.py b/Lib/test/test_buffer.py
index 72a06d6..535b795 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 0000000..55b02d1
--- /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 9427741..7e2f6e5 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 1ec5c5b..daf04eb 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) {