@@ -201,6 +201,11 @@ PyTypeObject _PyManagedBuffer_Type = {
201201 return -1; \
202202 }
203203
204+ /* See gh-92888. These macros signal that we need to check the memoryview
205+ again due to possible read after frees. */
206+ #define CHECK_RELEASED_AGAIN (mv ) CHECK_RELEASED(mv)
207+ #define CHECK_RELEASED_INT_AGAIN (mv ) CHECK_RELEASED_INT(mv)
208+
204209#define CHECK_LIST_OR_TUPLE (v ) \
205210 if (!PyList_Check(v) && !PyTuple_Check(v)) { \
206211 PyErr_SetString(PyExc_TypeError, \
@@ -389,8 +394,9 @@ copy_rec(const Py_ssize_t *shape, Py_ssize_t ndim, Py_ssize_t itemsize,
389394
390395/* Faster copying of one-dimensional arrays. */
391396static int
392- copy_single (Py_buffer * dest ,Py_buffer * src )
397+ copy_single (PyMemoryViewObject * self , const Py_buffer * dest ,const Py_buffer * src )
393398{
399+ CHECK_RELEASED_INT_AGAIN (self );
394400char * mem = NULL ;
395401
396402assert (dest -> ndim == 1 );
@@ -1685,7 +1691,7 @@ pylong_as_zu(PyObject *item)
16851691 module syntax. This function is very sensitive to small changes. With this
16861692 layout gcc automatically generates a fast jump table. */
16871693static inline PyObject *
1688- unpack_single (const char * ptr ,const char * fmt )
1694+ unpack_single (PyMemoryViewObject * self , const char * ptr ,const char * fmt )
16891695{
16901696unsigned long long llu ;
16911697unsigned long lu ;
@@ -1697,6 +1703,8 @@ unpack_single(const char *ptr, const char *fmt)
16971703unsignedchar uc ;
16981704void * p ;
16991705
1706+ CHECK_RELEASED_AGAIN (self );
1707+
17001708switch (fmt [0 ]) {
17011709
17021710/* signed integers and fast path for 'B' */
@@ -1775,7 +1783,7 @@ unpack_single(const char *ptr, const char *fmt)
17751783/* Pack a single item. 'fmt' can be any native format character in
17761784 struct module syntax. */
17771785static int
1778- pack_single (char * ptr ,PyObject * item ,const char * fmt )
1786+ pack_single (PyMemoryViewObject * self , char * ptr ,PyObject * item ,const char * fmt )
17791787{
17801788unsigned long long llu ;
17811789unsigned long lu ;
@@ -1792,6 +1800,7 @@ pack_single(char *ptr, PyObject *item, const char *fmt)
17921800ld = pylong_as_ld (item );
17931801if (ld == -1 && PyErr_Occurred ())
17941802 gotoerr_occurred ;
1803+ CHECK_RELEASED_INT_AGAIN (self );
17951804switch (fmt [0 ]) {
17961805case 'b' :
17971806if (ld < SCHAR_MIN || ld > SCHAR_MAX ) gotoerr_range ;
@@ -1812,6 +1821,7 @@ pack_single(char *ptr, PyObject *item, const char *fmt)
18121821lu = pylong_as_lu (item );
18131822if (lu == (unsigned long )-1 && PyErr_Occurred ())
18141823 gotoerr_occurred ;
1824+ CHECK_RELEASED_INT_AGAIN (self );
18151825switch (fmt [0 ]) {
18161826case 'B' :
18171827if (lu > UCHAR_MAX ) gotoerr_range ;
@@ -1832,12 +1842,14 @@ pack_single(char *ptr, PyObject *item, const char *fmt)
18321842lld = pylong_as_lld (item );
18331843if (lld == -1 && PyErr_Occurred ())
18341844 gotoerr_occurred ;
1845+ CHECK_RELEASED_INT_AGAIN (self );
18351846PACK_SINGLE (ptr ,lld ,long long );
18361847break ;
18371848case 'Q' :
18381849llu = pylong_as_llu (item );
18391850if (llu == (unsigned long long )-1 && PyErr_Occurred ())
18401851 gotoerr_occurred ;
1852+ CHECK_RELEASED_INT_AGAIN (self );
18411853PACK_SINGLE (ptr ,llu ,unsigned long long);
18421854break ;
18431855
@@ -1846,12 +1858,14 @@ pack_single(char *ptr, PyObject *item, const char *fmt)
18461858zd = pylong_as_zd (item );
18471859if (zd == -1 && PyErr_Occurred ())
18481860 gotoerr_occurred ;
1861+ CHECK_RELEASED_INT_AGAIN (self );
18491862PACK_SINGLE (ptr ,zd ,Py_ssize_t );
18501863break ;
18511864case 'N' :
18521865zu = pylong_as_zu (item );
18531866if (zu == (size_t )-1 && PyErr_Occurred ())
18541867 gotoerr_occurred ;
1868+ CHECK_RELEASED_INT_AGAIN (self );
18551869PACK_SINGLE (ptr ,zu ,size_t );
18561870break ;
18571871
@@ -1860,6 +1874,7 @@ pack_single(char *ptr, PyObject *item, const char *fmt)
18601874d = PyFloat_AsDouble (item );
18611875if (d == -1.0 && PyErr_Occurred ())
18621876 gotoerr_occurred ;
1877+ CHECK_RELEASED_INT_AGAIN (self );
18631878if (fmt [0 ]== 'f' ) {
18641879PACK_SINGLE (ptr ,d ,float );
18651880 }
@@ -1873,6 +1888,7 @@ pack_single(char *ptr, PyObject *item, const char *fmt)
18731888ld = PyObject_IsTrue (item );
18741889if (ld < 0 )
18751890return -1 ;/* preserve original error */
1891+ CHECK_RELEASED_INT_AGAIN (self );
18761892PACK_SINGLE (ptr ,ld ,_Bool );
18771893break ;
18781894
@@ -1890,6 +1906,7 @@ pack_single(char *ptr, PyObject *item, const char *fmt)
18901906p = PyLong_AsVoidPtr (item );
18911907if (p == NULL && PyErr_Occurred ())
18921908 gotoerr_occurred ;
1909+ CHECK_RELEASED_INT_AGAIN (self );
18931910PACK_SINGLE (ptr ,p ,void * );
18941911break ;
18951912
@@ -2056,7 +2073,7 @@ adjust_fmt(const Py_buffer *view)
20562073
20572074/* Base case for multi-dimensional unpacking. Assumption: ndim == 1. */
20582075static PyObject *
2059- tolist_base (const char * ptr ,const Py_ssize_t * shape ,
2076+ tolist_base (PyMemoryViewObject * self , const char * ptr ,const Py_ssize_t * shape ,
20602077const Py_ssize_t * strides ,const Py_ssize_t * suboffsets ,
20612078const char * fmt )
20622079{
@@ -2069,7 +2086,7 @@ tolist_base(const char *ptr, const Py_ssize_t *shape,
20692086
20702087for (i = 0 ;i < shape [0 ];ptr += strides [0 ],i ++ ) {
20712088const char * xptr = ADJUST_PTR (ptr ,suboffsets ,0 );
2072- item = unpack_single (xptr ,fmt );
2089+ item = unpack_single (self , xptr ,fmt );
20732090if (item == NULL ) {
20742091Py_DECREF (lst );
20752092return NULL ;
@@ -2083,7 +2100,7 @@ tolist_base(const char *ptr, const Py_ssize_t *shape,
20832100/* Unpack a multi-dimensional array into a nested list.
20842101 Assumption: ndim >= 1. */
20852102static PyObject *
2086- tolist_rec (const char * ptr ,Py_ssize_t ndim ,const Py_ssize_t * shape ,
2103+ tolist_rec (PyMemoryViewObject * self , const char * ptr ,Py_ssize_t ndim ,const Py_ssize_t * shape ,
20872104const Py_ssize_t * strides ,const Py_ssize_t * suboffsets ,
20882105const char * fmt )
20892106{
@@ -2095,15 +2112,15 @@ tolist_rec(const char *ptr, Py_ssize_t ndim, const Py_ssize_t *shape,
20952112assert (strides != NULL );
20962113
20972114if (ndim == 1 )
2098- return tolist_base (ptr ,shape ,strides ,suboffsets ,fmt );
2115+ return tolist_base (self , ptr ,shape ,strides ,suboffsets ,fmt );
20992116
21002117lst = PyList_New (shape [0 ]);
21012118if (lst == NULL )
21022119return NULL ;
21032120
21042121for (i = 0 ;i < shape [0 ];ptr += strides [0 ],i ++ ) {
21052122const char * xptr = ADJUST_PTR (ptr ,suboffsets ,0 );
2106- item = tolist_rec (xptr ,ndim - 1 ,shape + 1 ,
2123+ item = tolist_rec (self , xptr ,ndim - 1 ,shape + 1 ,
21072124strides + 1 ,suboffsets ?suboffsets + 1 :NULL ,
21082125fmt );
21092126if (item == NULL ) {
@@ -2137,15 +2154,15 @@ memoryview_tolist_impl(PyMemoryViewObject *self)
21372154if (fmt == NULL )
21382155return NULL ;
21392156if (view -> ndim == 0 ) {
2140- return unpack_single (view -> buf ,fmt );
2157+ return unpack_single (self , view -> buf ,fmt );
21412158 }
21422159else if (view -> ndim == 1 ) {
2143- return tolist_base (view -> buf ,view -> shape ,
2160+ return tolist_base (self , view -> buf ,view -> shape ,
21442161view -> strides ,view -> suboffsets ,
21452162fmt );
21462163 }
21472164else {
2148- return tolist_rec (view -> buf ,view -> ndim ,view -> shape ,
2165+ return tolist_rec (self , view -> buf ,view -> ndim ,view -> shape ,
21492166view -> strides ,view -> suboffsets ,
21502167fmt );
21512168 }
@@ -2353,7 +2370,7 @@ memory_item(PyMemoryViewObject *self, Py_ssize_t index)
23532370char * ptr = ptr_from_index (view ,index );
23542371if (ptr == NULL )
23552372return NULL ;
2356- return unpack_single (ptr ,fmt );
2373+ return unpack_single (self , ptr ,fmt );
23572374 }
23582375
23592376PyErr_SetString (PyExc_NotImplementedError ,
@@ -2384,7 +2401,7 @@ memory_item_multi(PyMemoryViewObject *self, PyObject *tup)
23842401ptr = ptr_from_tuple (view ,tup );
23852402if (ptr == NULL )
23862403return NULL ;
2387- return unpack_single (ptr ,fmt );
2404+ return unpack_single (self , ptr ,fmt );
23882405}
23892406
23902407static inline int
@@ -2471,7 +2488,7 @@ memory_subscript(PyMemoryViewObject *self, PyObject *key)
24712488const char * fmt = adjust_fmt (view );
24722489if (fmt == NULL )
24732490return NULL ;
2474- return unpack_single (view -> buf ,fmt );
2491+ return unpack_single (self , view -> buf ,fmt );
24752492 }
24762493else if (key == Py_Ellipsis ) {
24772494Py_INCREF (self );
@@ -2546,7 +2563,7 @@ memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value)
25462563if (key == Py_Ellipsis ||
25472564 (PyTuple_Check (key )&& PyTuple_GET_SIZE (key )== 0 )) {
25482565ptr = (char * )view -> buf ;
2549- return pack_single (ptr ,value ,fmt );
2566+ return pack_single (self , ptr ,value ,fmt );
25502567 }
25512568else {
25522569PyErr_SetString (PyExc_TypeError ,
@@ -2568,7 +2585,7 @@ memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value)
25682585ptr = ptr_from_index (view ,index );
25692586if (ptr == NULL )
25702587return -1 ;
2571- return pack_single (ptr ,value ,fmt );
2588+ return pack_single (self , ptr ,value ,fmt );
25722589 }
25732590/* one-dimensional: fast path */
25742591if (PySlice_Check (key )&& view -> ndim == 1 ) {
@@ -2591,7 +2608,7 @@ memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value)
25912608 gotoend_block ;
25922609dest .len = dest .shape [0 ]* dest .itemsize ;
25932610
2594- ret = copy_single (& dest ,& src );
2611+ ret = copy_single (self , & dest ,& src );
25952612
25962613end_block :
25972614PyBuffer_Release (& src );
@@ -2607,7 +2624,7 @@ memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value)
26072624ptr = ptr_from_tuple (view ,key );
26082625if (ptr == NULL )
26092626return -1 ;
2610- return pack_single (ptr ,value ,fmt );
2627+ return pack_single (self , ptr ,value ,fmt );
26112628 }
26122629if (PySlice_Check (key )|| is_multislice (key )) {
26132630/* Call memory_subscript() to produce a sliced lvalue, then copy
@@ -3208,7 +3225,7 @@ memoryiter_next(memoryiterobject *it)
32083225if (ptr == NULL ) {
32093226return NULL ;
32103227 }
3211- return unpack_single (ptr ,it -> it_fmt );
3228+ return unpack_single (seq , ptr ,it -> it_fmt );
32123229 }
32133230
32143231it -> it_seq = NULL ;