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):
--- /dev/null
+: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.
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;
}
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) {