@@ -193,6 +193,11 @@ PyTypeObject _PyManagedBuffer_Type = {
193193 return -1; \
194194 }
195195196+/* See gh-92888. These macros signal that we need to check the memoryview
197+ again due to possible read after frees. */
198+#defineCHECK_RELEASED_AGAIN(mv) CHECK_RELEASED(mv)
199+#defineCHECK_RELEASED_INT_AGAIN(mv) CHECK_RELEASED_INT(mv)
200+196201#defineCHECK_LIST_OR_TUPLE(v) \
197202 if (!PyList_Check(v) && !PyTuple_Check(v)) { \
198203 PyErr_SetString(PyExc_TypeError, \
@@ -381,8 +386,9 @@ copy_rec(const Py_ssize_t *shape, Py_ssize_t ndim, Py_ssize_t itemsize,
381386382387/* Faster copying of one-dimensional arrays. */
383388staticint
384-copy_single(constPy_buffer*dest, constPy_buffer*src)
389+copy_single(PyMemoryViewObject*self, constPy_buffer*dest, constPy_buffer*src)
385390{
391+CHECK_RELEASED_INT_AGAIN(self);
386392char*mem=NULL;
387393388394assert(dest->ndim==1);
@@ -1677,7 +1683,7 @@ pylong_as_zu(PyObject *item)
16771683 module syntax. This function is very sensitive to small changes. With this
16781684 layout gcc automatically generates a fast jump table. */
16791685staticinlinePyObject*
1680-unpack_single(constchar*ptr, constchar*fmt)
1686+unpack_single(PyMemoryViewObject*self, constchar*ptr, constchar*fmt)
16811687{
16821688unsigned long longllu;
16831689unsigned longlu;
@@ -1689,6 +1695,8 @@ unpack_single(const char *ptr, const char *fmt)
16891695unsigned charuc;
16901696void*p;
169116971698+CHECK_RELEASED_AGAIN(self);
1699+16921700switch (fmt[0]) {
1693170116941702/* signed integers and fast path for 'B' */
@@ -1767,7 +1775,7 @@ unpack_single(const char *ptr, const char *fmt)
17671775/* Pack a single item. 'fmt' can be any native format character in
17681776 struct module syntax. */
17691777staticint
1770-pack_single(char*ptr, PyObject*item, constchar*fmt)
1778+pack_single(PyMemoryViewObject*self, char*ptr, PyObject*item, constchar*fmt)
17711779{
17721780unsigned long longllu;
17731781unsigned longlu;
@@ -1784,6 +1792,7 @@ pack_single(char *ptr, PyObject *item, const char *fmt)
17841792ld=pylong_as_ld(item);
17851793if (ld==-1&&PyErr_Occurred())
17861794 goto err_occurred;
1795+CHECK_RELEASED_INT_AGAIN(self);
17871796switch (fmt[0]) {
17881797case'b':
17891798if (ld<SCHAR_MIN||ld>SCHAR_MAX) goto err_range;
@@ -1804,6 +1813,7 @@ pack_single(char *ptr, PyObject *item, const char *fmt)
18041813lu=pylong_as_lu(item);
18051814if (lu== (unsigned long)-1&&PyErr_Occurred())
18061815 goto err_occurred;
1816+CHECK_RELEASED_INT_AGAIN(self);
18071817switch (fmt[0]) {
18081818case'B':
18091819if (lu>UCHAR_MAX) goto err_range;
@@ -1824,12 +1834,14 @@ pack_single(char *ptr, PyObject *item, const char *fmt)
18241834lld=pylong_as_lld(item);
18251835if (lld==-1&&PyErr_Occurred())
18261836 goto err_occurred;
1837+CHECK_RELEASED_INT_AGAIN(self);
18271838PACK_SINGLE(ptr, lld, longlong);
18281839break;
18291840case'Q':
18301841llu=pylong_as_llu(item);
18311842if (llu== (unsigned long long)-1&&PyErr_Occurred())
18321843 goto err_occurred;
1844+CHECK_RELEASED_INT_AGAIN(self);
18331845PACK_SINGLE(ptr, llu, unsignedlong long);
18341846break;
18351847@@ -1838,12 +1850,14 @@ pack_single(char *ptr, PyObject *item, const char *fmt)
18381850zd=pylong_as_zd(item);
18391851if (zd==-1&&PyErr_Occurred())
18401852 goto err_occurred;
1853+CHECK_RELEASED_INT_AGAIN(self);
18411854PACK_SINGLE(ptr, zd, Py_ssize_t);
18421855break;
18431856case'N':
18441857zu=pylong_as_zu(item);
18451858if (zu== (size_t)-1&&PyErr_Occurred())
18461859 goto err_occurred;
1860+CHECK_RELEASED_INT_AGAIN(self);
18471861PACK_SINGLE(ptr, zu, size_t);
18481862break;
18491863@@ -1852,6 +1866,7 @@ pack_single(char *ptr, PyObject *item, const char *fmt)
18521866d=PyFloat_AsDouble(item);
18531867if (d==-1.0&&PyErr_Occurred())
18541868 goto err_occurred;
1869+CHECK_RELEASED_INT_AGAIN(self);
18551870if (fmt[0] =='f') {
18561871PACK_SINGLE(ptr, d, float);
18571872 }
@@ -1865,6 +1880,7 @@ pack_single(char *ptr, PyObject *item, const char *fmt)
18651880ld=PyObject_IsTrue(item);
18661881if (ld<0)
18671882return-1; /* preserve original error */
1883+CHECK_RELEASED_INT_AGAIN(self);
18681884PACK_SINGLE(ptr, ld, _Bool);
18691885break;
18701886@@ -1882,6 +1898,7 @@ pack_single(char *ptr, PyObject *item, const char *fmt)
18821898p=PyLong_AsVoidPtr(item);
18831899if (p==NULL&&PyErr_Occurred())
18841900 goto err_occurred;
1901+CHECK_RELEASED_INT_AGAIN(self);
18851902PACK_SINGLE(ptr, p, void*);
18861903break;
18871904@@ -2048,7 +2065,7 @@ adjust_fmt(const Py_buffer *view)
2048206520492066/* Base case for multi-dimensional unpacking. Assumption: ndim == 1. */
20502067staticPyObject*
2051-tolist_base(constchar*ptr, constPy_ssize_t*shape,
2068+tolist_base(PyMemoryViewObject*self, constchar*ptr, constPy_ssize_t*shape,
20522069constPy_ssize_t*strides, constPy_ssize_t*suboffsets,
20532070constchar*fmt)
20542071{
@@ -2061,7 +2078,7 @@ tolist_base(const char *ptr, const Py_ssize_t *shape,
2061207820622079for (i=0; i<shape[0]; ptr+=strides[0], i++) {
20632080constchar*xptr=ADJUST_PTR(ptr, suboffsets, 0);
2064-item=unpack_single(xptr, fmt);
2081+item=unpack_single(self, xptr, fmt);
20652082if (item==NULL) {
20662083Py_DECREF(lst);
20672084returnNULL;
@@ -2075,7 +2092,7 @@ tolist_base(const char *ptr, const Py_ssize_t *shape,
20752092/* Unpack a multi-dimensional array into a nested list.
20762093 Assumption: ndim >= 1. */
20772094staticPyObject*
2078-tolist_rec(constchar*ptr, Py_ssize_tndim, constPy_ssize_t*shape,
2095+tolist_rec(PyMemoryViewObject*self, constchar*ptr, Py_ssize_tndim, constPy_ssize_t*shape,
20792096constPy_ssize_t*strides, constPy_ssize_t*suboffsets,
20802097constchar*fmt)
20812098{
@@ -2087,15 +2104,15 @@ tolist_rec(const char *ptr, Py_ssize_t ndim, const Py_ssize_t *shape,
20872104assert(strides!=NULL);
2088210520892106if (ndim==1)
2090-returntolist_base(ptr, shape, strides, suboffsets, fmt);
2107+returntolist_base(self, ptr, shape, strides, suboffsets, fmt);
2091210820922109lst=PyList_New(shape[0]);
20932110if (lst==NULL)
20942111returnNULL;
2095211220962113for (i=0; i<shape[0]; ptr+=strides[0], i++) {
20972114constchar*xptr=ADJUST_PTR(ptr, suboffsets, 0);
2098-item=tolist_rec(xptr, ndim-1, shape+1,
2115+item=tolist_rec(self, xptr, ndim-1, shape+1,
20992116strides+1, suboffsets ? suboffsets+1 : NULL,
21002117fmt);
21012118if (item==NULL) {
@@ -2129,15 +2146,15 @@ memoryview_tolist_impl(PyMemoryViewObject *self)
21292146if (fmt==NULL)
21302147returnNULL;
21312148if (view->ndim==0) {
2132-returnunpack_single(view->buf, fmt);
2149+returnunpack_single(self, view->buf, fmt);
21332150 }
21342151elseif (view->ndim==1) {
2135-returntolist_base(view->buf, view->shape,
2152+returntolist_base(self, view->buf, view->shape,
21362153view->strides, view->suboffsets,
21372154fmt);
21382155 }
21392156else {
2140-returntolist_rec(view->buf, view->ndim, view->shape,
2157+returntolist_rec(self, view->buf, view->ndim, view->shape,
21412158view->strides, view->suboffsets,
21422159fmt);
21432160 }
@@ -2345,7 +2362,7 @@ memory_item(PyMemoryViewObject *self, Py_ssize_t index)
23452362char*ptr=ptr_from_index(view, index);
23462363if (ptr==NULL)
23472364returnNULL;
2348-returnunpack_single(ptr, fmt);
2365+returnunpack_single(self, ptr, fmt);
23492366 }
2350236723512368PyErr_SetString(PyExc_NotImplementedError,
@@ -2376,7 +2393,7 @@ memory_item_multi(PyMemoryViewObject *self, PyObject *tup)
23762393ptr=ptr_from_tuple(view, tup);
23772394if (ptr==NULL)
23782395returnNULL;
2379-returnunpack_single(ptr, fmt);
2396+returnunpack_single(self, ptr, fmt);
23802397}
2381239823822399staticinlineint
@@ -2463,7 +2480,7 @@ memory_subscript(PyMemoryViewObject *self, PyObject *key)
24632480constchar*fmt=adjust_fmt(view);
24642481if (fmt==NULL)
24652482returnNULL;
2466-returnunpack_single(view->buf, fmt);
2483+returnunpack_single(self, view->buf, fmt);
24672484 }
24682485elseif (key==Py_Ellipsis) {
24692486Py_INCREF(self);
@@ -2538,7 +2555,7 @@ memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value)
25382555if (key==Py_Ellipsis||
25392556 (PyTuple_Check(key) &&PyTuple_GET_SIZE(key)==0)) {
25402557ptr= (char*)view->buf;
2541-returnpack_single(ptr, value, fmt);
2558+returnpack_single(self, ptr, value, fmt);
25422559 }
25432560else {
25442561PyErr_SetString(PyExc_TypeError,
@@ -2560,7 +2577,7 @@ memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value)
25602577ptr=ptr_from_index(view, index);
25612578if (ptr==NULL)
25622579return-1;
2563-returnpack_single(ptr, value, fmt);
2580+returnpack_single(self, ptr, value, fmt);
25642581 }
25652582/* one-dimensional: fast path */
25662583if (PySlice_Check(key) &&view->ndim==1) {
@@ -2583,7 +2600,7 @@ memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value)
25832600 goto end_block;
25842601dest.len=dest.shape[0] *dest.itemsize;
258526022586-ret=copy_single(&dest, &src);
2603+ret=copy_single(self, &dest, &src);
2587260425882605end_block:
25892606PyBuffer_Release(&src);
@@ -2599,7 +2616,7 @@ memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value)
25992616ptr=ptr_from_tuple(view, key);
26002617if (ptr==NULL)
26012618return-1;
2602-returnpack_single(ptr, value, fmt);
2619+returnpack_single(self, ptr, value, fmt);
26032620 }
26042621if (PySlice_Check(key) ||is_multislice(key)) {
26052622/* Call memory_subscript() to produce a sliced lvalue, then copy
@@ -3200,7 +3217,7 @@ memoryiter_next(memoryiterobject *it)
32003217if (ptr==NULL) {
32013218returnNULL;
32023219 }
3203-returnunpack_single(ptr, it->it_fmt);
3220+returnunpack_single(seq, ptr, it->it_fmt);
32043221 }
3205322232063223it->it_seq=NULL;