summaryrefslogtreecommitdiffstats
path: root/Objects/memoryobject.c
diff options
context:
space:
mode:
authorJelle Zijlstra <jelle.zijlstra@gmail.com>2023-05-08 16:52:41 (GMT)
committerGitHub <noreply@github.com>2023-05-08 16:52:41 (GMT)
commit405eacc1b87a42e19fd176131e70537f0539e05e (patch)
treee5507b3b2b1c4266ef74b388aaf024386c37cfa0 /Objects/memoryobject.c
parent874010c6cab2e079069767619af2e0eab05ad0b2 (diff)
downloadcpython-405eacc1b87a42e19fd176131e70537f0539e05e.zip
cpython-405eacc1b87a42e19fd176131e70537f0539e05e.tar.gz
cpython-405eacc1b87a42e19fd176131e70537f0539e05e.tar.bz2
gh-104223: Fix issues with inheriting from buffer classes (#104227)
Co-authored-by: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com>
Diffstat (limited to 'Objects/memoryobject.c')
-rw-r--r--Objects/memoryobject.c45
1 files changed, 44 insertions, 1 deletions
diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c
index f008a8c..b016804 100644
--- a/Objects/memoryobject.c
+++ b/Objects/memoryobject.c
@@ -193,6 +193,20 @@ PyTypeObject _PyManagedBuffer_Type = {
return -1; \
}
+#define CHECK_RESTRICTED(mv) \
+ if (((PyMemoryViewObject *)(mv))->flags & _Py_MEMORYVIEW_RESTRICTED) { \
+ PyErr_SetString(PyExc_ValueError, \
+ "cannot create new view on restricted memoryview"); \
+ return NULL; \
+ }
+
+#define CHECK_RESTRICTED_INT(mv) \
+ if (((PyMemoryViewObject *)(mv))->flags & _Py_MEMORYVIEW_RESTRICTED) { \
+ PyErr_SetString(PyExc_ValueError, \
+ "cannot create new view on restricted memoryview"); \
+ return -1; \
+ }
+
/* See gh-92888. These macros signal that we need to check the memoryview
again due to possible read after frees. */
#define CHECK_RELEASED_AGAIN(mv) CHECK_RELEASED(mv)
@@ -781,7 +795,7 @@ PyMemoryView_FromBuffer(const Py_buffer *info)
using the given flags.
If the object is a memoryview, the new memoryview must be registered
with the same managed buffer. Otherwise, a new managed buffer is created. */
-PyObject *
+static PyObject *
PyMemoryView_FromObjectAndFlags(PyObject *v, int flags)
{
_PyManagedBufferObject *mbuf;
@@ -789,6 +803,7 @@ PyMemoryView_FromObjectAndFlags(PyObject *v, int flags)
if (PyMemoryView_Check(v)) {
PyMemoryViewObject *mv = (PyMemoryViewObject *)v;
CHECK_RELEASED(mv);
+ CHECK_RESTRICTED(mv);
return mbuf_add_view(mv->mbuf, &mv->view);
}
else if (PyObject_CheckBuffer(v)) {
@@ -806,6 +821,30 @@ PyMemoryView_FromObjectAndFlags(PyObject *v, int flags)
Py_TYPE(v)->tp_name);
return NULL;
}
+
+/* Create a memoryview from an object that implements the buffer protocol,
+ using the given flags.
+ If the object is a memoryview, the new memoryview must be registered
+ with the same managed buffer. Otherwise, a new managed buffer is created. */
+PyObject *
+_PyMemoryView_FromBufferProc(PyObject *v, int flags, getbufferproc bufferproc)
+{
+ _PyManagedBufferObject *mbuf = mbuf_alloc();
+ if (mbuf == NULL)
+ return NULL;
+
+ int res = bufferproc(v, &mbuf->master, flags);
+ if (res < 0) {
+ mbuf->master.obj = NULL;
+ Py_DECREF(mbuf);
+ return NULL;
+ }
+
+ PyObject *ret = mbuf_add_view(mbuf, NULL);
+ Py_DECREF(mbuf);
+ return ret;
+}
+
/* Create a memoryview from an object that implements the buffer protocol.
If the object is a memoryview, the new memoryview must be registered
with the same managed buffer. Otherwise, a new managed buffer is created. */
@@ -1397,6 +1436,7 @@ memoryview_cast_impl(PyMemoryViewObject *self, PyObject *format,
Py_ssize_t ndim = 1;
CHECK_RELEASED(self);
+ CHECK_RESTRICTED(self);
if (!MV_C_CONTIGUOUS(self->flags)) {
PyErr_SetString(PyExc_TypeError,
@@ -1452,6 +1492,7 @@ memoryview_toreadonly_impl(PyMemoryViewObject *self)
/*[clinic end generated code: output=2c7e056f04c99e62 input=dc06d20f19ba236f]*/
{
CHECK_RELEASED(self);
+ CHECK_RESTRICTED(self);
/* Even if self is already readonly, we still need to create a new
* object for .release() to work correctly.
*/
@@ -1474,6 +1515,7 @@ memory_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags)
int baseflags = self->flags;
CHECK_RELEASED_INT(self);
+ CHECK_RESTRICTED_INT(self);
/* start with complete information */
*view = *base;
@@ -2535,6 +2577,7 @@ memory_subscript(PyMemoryViewObject *self, PyObject *key)
return memory_item(self, index);
}
else if (PySlice_Check(key)) {
+ CHECK_RESTRICTED(self);
PyMemoryViewObject *sliced;
sliced = (PyMemoryViewObject *)mbuf_add_view(self->mbuf, view);