@@ -193,6 +193,11 @@ PyTypeObject _PyManagedBuffer_Type = {
193193 return -1; \
194194 }
195195
196+ /* See gh-92888. These macros signal that we need to check the memoryview
197+ again due to possible read after frees. */
198+ #define CHECK_RELEASED_AGAIN (mv ) CHECK_RELEASED(mv)
199+ #define CHECK_RELEASED_INT_AGAIN (mv ) CHECK_RELEASED_INT(mv)
200+
196201#define CHECK_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,
381386
382387/* Faster copying of one-dimensional arrays. */
383388static int
384- copy_single (const Py_buffer * dest ,const Py_buffer * src )
389+ copy_single (PyMemoryViewObject * self , const Py_buffer * dest ,const Py_buffer * src )
385390{
391+ CHECK_RELEASED_INT_AGAIN (self );
386392char * mem = NULL ;
387393
388394assert (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. */
16791685static inline PyObject *
1680- unpack_single (const char * ptr ,const char * fmt )
1686+ unpack_single (PyMemoryViewObject * self , const char * ptr ,const char * fmt )
16811687{
16821688unsigned long long llu ;
16831689unsigned long lu ;
@@ -1689,6 +1695,8 @@ unpack_single(const char *ptr, const char *fmt)
16891695unsignedchar uc ;
16901696void * p ;
16911697
1698+ CHECK_RELEASED_AGAIN (self );
1699+
16921700switch (fmt [0 ]) {
16931701
16941702/* 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. */
17691777static int
1770- pack_single (char * ptr ,PyObject * item ,const char * fmt )
1778+ pack_single (PyMemoryViewObject * self , char * ptr ,PyObject * item ,const char * fmt )
17711779{
17721780unsigned long long llu ;
17731781unsigned long lu ;
@@ -1784,6 +1792,7 @@ pack_single(char *ptr, PyObject *item, const char *fmt)
17841792ld = pylong_as_ld (item );
17851793if (ld == -1 && PyErr_Occurred ())
17861794 gotoerr_occurred ;
1795+ CHECK_RELEASED_INT_AGAIN (self );
17871796switch (fmt [0 ]) {
17881797case 'b' :
17891798if (ld < SCHAR_MIN || ld > SCHAR_MAX ) gotoerr_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 gotoerr_occurred ;
1816+ CHECK_RELEASED_INT_AGAIN (self );
18071817switch (fmt [0 ]) {
18081818case 'B' :
18091819if (lu > UCHAR_MAX ) gotoerr_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 gotoerr_occurred ;
1837+ CHECK_RELEASED_INT_AGAIN (self );
18271838PACK_SINGLE (ptr ,lld ,long long );
18281839break ;
18291840case 'Q' :
18301841llu = pylong_as_llu (item );
18311842if (llu == (unsigned long long )-1 && PyErr_Occurred ())
18321843 gotoerr_occurred ;
1844+ CHECK_RELEASED_INT_AGAIN (self );
18331845PACK_SINGLE (ptr ,llu ,unsigned long 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 gotoerr_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 gotoerr_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 gotoerr_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 gotoerr_occurred ;
1901+ CHECK_RELEASED_INT_AGAIN (self );
18851902PACK_SINGLE (ptr ,p ,void * );
18861903break ;
18871904
@@ -2048,7 +2065,7 @@ adjust_fmt(const Py_buffer *view)
20482065
20492066/* Base case for multi-dimensional unpacking. Assumption: ndim == 1. */
20502067static PyObject *
2051- tolist_base (const char * ptr ,const Py_ssize_t * shape ,
2068+ tolist_base (PyMemoryViewObject * self , const char * ptr ,const Py_ssize_t * shape ,
20522069const Py_ssize_t * strides ,const Py_ssize_t * suboffsets ,
20532070const char * fmt )
20542071{
@@ -2061,7 +2078,7 @@ tolist_base(const char *ptr, const Py_ssize_t *shape,
20612078
20622079for (i = 0 ;i < shape [0 ];ptr += strides [0 ],i ++ ) {
20632080const char * 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 );
20672084return NULL ;
@@ -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. */
20772094static PyObject *
2078- tolist_rec (const char * ptr ,Py_ssize_t ndim ,const Py_ssize_t * shape ,
2095+ tolist_rec (PyMemoryViewObject * self , const char * ptr ,Py_ssize_t ndim ,const Py_ssize_t * shape ,
20792096const Py_ssize_t * strides ,const Py_ssize_t * suboffsets ,
20802097const char * fmt )
20812098{
@@ -2087,15 +2104,15 @@ tolist_rec(const char *ptr, Py_ssize_t ndim, const Py_ssize_t *shape,
20872104assert (strides != NULL );
20882105
20892106if (ndim == 1 )
2090- return tolist_base (ptr ,shape ,strides ,suboffsets ,fmt );
2107+ return tolist_base (self , ptr ,shape ,strides ,suboffsets ,fmt );
20912108
20922109lst = PyList_New (shape [0 ]);
20932110if (lst == NULL )
20942111return NULL ;
20952112
20962113for (i = 0 ;i < shape [0 ];ptr += strides [0 ],i ++ ) {
20972114const char * 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 )
21302147return NULL ;
21312148if (view -> ndim == 0 ) {
2132- return unpack_single (view -> buf ,fmt );
2149+ return unpack_single (self , view -> buf ,fmt );
21332150 }
21342151else if (view -> ndim == 1 ) {
2135- return tolist_base (view -> buf ,view -> shape ,
2152+ return tolist_base (self , view -> buf ,view -> shape ,
21362153view -> strides ,view -> suboffsets ,
21372154fmt );
21382155 }
21392156else {
2140- return tolist_rec (view -> buf ,view -> ndim ,view -> shape ,
2157+ return tolist_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 )
23472364return NULL ;
2348- return unpack_single (ptr ,fmt );
2365+ return unpack_single (self , ptr ,fmt );
23492366 }
23502367
23512368PyErr_SetString (PyExc_NotImplementedError ,
@@ -2376,7 +2393,7 @@ memory_item_multi(PyMemoryViewObject *self, PyObject *tup)
23762393ptr = ptr_from_tuple (view ,tup );
23772394if (ptr == NULL )
23782395return NULL ;
2379- return unpack_single (ptr ,fmt );
2396+ return unpack_single (self , ptr ,fmt );
23802397}
23812398
23822399static inline int
@@ -2463,7 +2480,7 @@ memory_subscript(PyMemoryViewObject *self, PyObject *key)
24632480const char * fmt = adjust_fmt (view );
24642481if (fmt == NULL )
24652482return NULL ;
2466- return unpack_single (view -> buf ,fmt );
2483+ return unpack_single (self , view -> buf ,fmt );
24672484 }
24682485else if (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- return pack_single (ptr ,value ,fmt );
2558+ return pack_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- return pack_single (ptr ,value ,fmt );
2580+ return pack_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 gotoend_block ;
25842601dest .len = dest .shape [0 ]* dest .itemsize ;
25852602
2586- ret = copy_single (& dest ,& src );
2603+ ret = copy_single (self , & dest ,& src );
25872604
25882605end_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- return pack_single (ptr ,value ,fmt );
2619+ return pack_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 ) {
32013218return NULL ;
32023219 }
3203- return unpack_single (ptr ,it -> it_fmt );
3220+ return unpack_single (seq , ptr ,it -> it_fmt );
32043221 }
32053222
32063223it -> it_seq = NULL ;