@@ -1657,24 +1657,15 @@ static int
16571657mmap_ass_subscript_lock_held (PyObject * op , PyObject * item , PyObject * value )
16581658{
16591659 mmap_object * self = mmap_object_CAST (op );
1660- CHECK_VALID (-1 );
16611660
16621661 if (!is_writable (self ))
16631662 return -1 ;
16641663
16651664 if (PyIndex_Check (item )) {
16661665 Py_ssize_t i = PyNumber_AsSsize_t (item , PyExc_IndexError );
1667- Py_ssize_t v ;
1668-
16691666 if (i == -1 && PyErr_Occurred ())
16701667 return -1 ;
1671- if (i < 0 )
1672- i += self -> size ;
1673- if (i < 0 || i >= self -> size ) {
1674- PyErr_SetString (PyExc_IndexError ,
1675- "mmap index out of range" );
1676- return -1 ;
1677- }
1668+
16781669 if (value == NULL ) {
16791670 PyErr_SetString (PyExc_TypeError ,
16801671 "mmap doesn't support item deletion" );
@@ -1685,7 +1676,7 @@ mmap_ass_subscript_lock_held(PyObject *op, PyObject *item, PyObject *value)
16851676 "mmap item value must be an int" );
16861677 return -1 ;
16871678 }
1688- v = PyNumber_AsSsize_t (value , PyExc_TypeError );
1679+ Py_ssize_t v = PyNumber_AsSsize_t (value , PyExc_TypeError );
16891680 if (v == -1 && PyErr_Occurred ())
16901681 return -1 ;
16911682 if (v < 0 || v > 255 ) {
@@ -1694,7 +1685,18 @@ mmap_ass_subscript_lock_held(PyObject *op, PyObject *item, PyObject *value)
16941685 "in range(0, 256)" );
16951686 return -1 ;
16961687 }
1688+
1689+ /* Converting item or value above may have run arbitrary code
1690+ * (e.g. __index__) that resized or closed the mmap, so bounds
1691+ * are only checked now, against the current size. */
16971692 CHECK_VALID (-1 );
1693+ if (i < 0 )
1694+ i += self -> size ;
1695+ if (i < 0 || i >= self -> size ) {
1696+ PyErr_SetString (PyExc_IndexError ,
1697+ "mmap index out of range" );
1698+ return -1 ;
1699+ }
16981700
16991701 char v_char = (char ) v ;
17001702 if (safe_byte_copy (self -> data + i , & v_char ) < 0 ) {
@@ -1709,22 +1711,26 @@ mmap_ass_subscript_lock_held(PyObject *op, PyObject *item, PyObject *value)
17091711 if (PySlice_Unpack (item , & start , & stop , & step ) < 0 ) {
17101712 return -1 ;
17111713 }
1712- slicelen = PySlice_AdjustIndices (self -> size , & start , & stop , step );
17131714 if (value == NULL ) {
17141715 PyErr_SetString (PyExc_TypeError ,
17151716 "mmap object doesn't support slice deletion" );
17161717 return -1 ;
17171718 }
17181719 if (PyObject_GetBuffer (value , & vbuf , PyBUF_SIMPLE ) < 0 )
17191720 return -1 ;
1721+
1722+ /* Acquiring the buffer above may have run arbitrary code (e.g. a
1723+ * __buffer__ method) that resized or closed this mmap, so the slice bounds
1724+ * are only computed now, against the current size. */
1725+ CHECK_VALID_OR_RELEASE (-1 , vbuf );
1726+ slicelen = PySlice_AdjustIndices (self -> size , & start , & stop , step );
17201727 if (vbuf .len != slicelen ) {
17211728 PyErr_SetString (PyExc_IndexError ,
17221729 "mmap slice assignment is wrong size" );
17231730 PyBuffer_Release (& vbuf );
17241731 return -1 ;
17251732 }
17261733
1727- CHECK_VALID_OR_RELEASE (-1 , vbuf );
17281734 int result = 0 ;
17291735 if (slicelen == 0 ) {
17301736 }
0 commit comments