@@ -90,6 +90,25 @@ bytearray_releasebuffer(PyObject *self, Py_buffer *view)
9090 Py_END_CRITICAL_SECTION ();
9191}
9292
93+ typedef PyObject * (* _ba_bytes_op )(const char * buf , Py_ssize_t len ,
94+ PyObject * sub , Py_ssize_t start ,
95+ Py_ssize_t end );
96+
97+ static PyObject *
98+ _bytearray_with_buffer (PyByteArrayObject * self , _ba_bytes_op op , PyObject * sub ,
99+ Py_ssize_t start , Py_ssize_t end )
100+ {
101+ PyObject * res ;
102+
103+ _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED (self );
104+
105+ /* Increase exports to prevent bytearray storage from changing during op. */
106+ self -> ob_exports ++ ;
107+ res = op (PyByteArray_AS_STRING (self ), Py_SIZE (self ), sub , start , end );
108+ self -> ob_exports -- ;
109+ return res ;
110+ }
111+
93112static int
94113_canresize (PyByteArrayObject * self )
95114{
@@ -1248,8 +1267,7 @@ bytearray_find_impl(PyByteArrayObject *self, PyObject *sub, Py_ssize_t start,
12481267 Py_ssize_t end )
12491268/*[clinic end generated code: output=413e1cab2ae87da0 input=df3aa94840d893a7]*/
12501269{
1251- return _Py_bytes_find (PyByteArray_AS_STRING (self ), PyByteArray_GET_SIZE (self ),
1252- sub , start , end );
1270+ return _bytearray_with_buffer (self , _Py_bytes_find , sub , start , end );
12531271}
12541272
12551273/*[clinic input]
@@ -1265,8 +1283,7 @@ bytearray_count_impl(PyByteArrayObject *self, PyObject *sub,
12651283 Py_ssize_t start , Py_ssize_t end )
12661284/*[clinic end generated code: output=a21ee2692e4f1233 input=e8fcdca8272857e0]*/
12671285{
1268- return _Py_bytes_count (PyByteArray_AS_STRING (self ), PyByteArray_GET_SIZE (self ),
1269- sub , start , end );
1286+ return _bytearray_with_buffer (self , _Py_bytes_count , sub , start , end );
12701287}
12711288
12721289/*[clinic input]
@@ -1314,8 +1331,7 @@ bytearray_index_impl(PyByteArrayObject *self, PyObject *sub,
13141331 Py_ssize_t start , Py_ssize_t end )
13151332/*[clinic end generated code: output=067a1e78efc672a7 input=c37f177cfee19fe4]*/
13161333{
1317- return _Py_bytes_index (PyByteArray_AS_STRING (self ), PyByteArray_GET_SIZE (self ),
1318- sub , start , end );
1334+ return _bytearray_with_buffer (self , _Py_bytes_index , sub , start , end );
13191335}
13201336
13211337/*[clinic input]
@@ -1333,8 +1349,7 @@ bytearray_rfind_impl(PyByteArrayObject *self, PyObject *sub,
13331349 Py_ssize_t start , Py_ssize_t end )
13341350/*[clinic end generated code: output=51bf886f932b283c input=1265b11c437d2750]*/
13351351{
1336- return _Py_bytes_rfind (PyByteArray_AS_STRING (self ), PyByteArray_GET_SIZE (self ),
1337- sub , start , end );
1352+ return _bytearray_with_buffer (self , _Py_bytes_rfind , sub , start , end );
13381353}
13391354
13401355/*[clinic input]
@@ -1352,18 +1367,22 @@ bytearray_rindex_impl(PyByteArrayObject *self, PyObject *sub,
13521367 Py_ssize_t start , Py_ssize_t end )
13531368/*[clinic end generated code: output=38e1cf66bafb08b9 input=7d198b3d6b0a62ce]*/
13541369{
1355- return _Py_bytes_rindex (PyByteArray_AS_STRING (self ), PyByteArray_GET_SIZE (self ),
1356- sub , start , end );
1370+ return _bytearray_with_buffer (self , _Py_bytes_rindex , sub , start , end );
13571371}
13581372
13591373static int
13601374bytearray_contains (PyObject * self , PyObject * arg )
13611375{
1362- int ret ;
1376+ int ret = -1 ;
13631377 Py_BEGIN_CRITICAL_SECTION (self );
1364- ret = _Py_bytes_contains (PyByteArray_AS_STRING (self ),
1378+ PyByteArrayObject * ba = _PyByteArray_CAST (self );
1379+
1380+ /* Increase exports to prevent bytearray storage from changing during _Py_bytes_contains(). */
1381+ ba -> ob_exports ++ ;
1382+ ret = _Py_bytes_contains (PyByteArray_AS_STRING (ba ),
13651383 PyByteArray_GET_SIZE (self ),
13661384 arg );
1385+ ba -> ob_exports -- ;
13671386 Py_END_CRITICAL_SECTION ();
13681387 return ret ;
13691388}
@@ -1390,8 +1409,7 @@ bytearray_startswith_impl(PyByteArrayObject *self, PyObject *subobj,
13901409 Py_ssize_t start , Py_ssize_t end )
13911410/*[clinic end generated code: output=a3d9b6d44d3662a6 input=93f9ffee684f109a]*/
13921411{
1393- return _Py_bytes_startswith (PyByteArray_AS_STRING (self ), PyByteArray_GET_SIZE (self ),
1394- subobj , start , end );
1412+ return _bytearray_with_buffer (self , _Py_bytes_startswith , subobj , start , end );
13951413}
13961414
13971415/*[clinic input]
@@ -1416,8 +1434,7 @@ bytearray_endswith_impl(PyByteArrayObject *self, PyObject *subobj,
14161434 Py_ssize_t start , Py_ssize_t end )
14171435/*[clinic end generated code: output=e75ea8c227954caa input=d158b030a11d0b06]*/
14181436{
1419- return _Py_bytes_endswith (PyByteArray_AS_STRING (self ), PyByteArray_GET_SIZE (self ),
1420- subobj , start , end );
1437+ return _bytearray_with_buffer (self , _Py_bytes_endswith , subobj , start , end );
14211438}
14221439
14231440/*[clinic input]
@@ -1782,26 +1799,32 @@ bytearray_split_impl(PyByteArrayObject *self, PyObject *sep,
17821799 Py_ssize_t maxsplit )
17831800/*[clinic end generated code: output=833e2cf385d9a04d input=dd9f6e2910cc3a34]*/
17841801{
1785- Py_ssize_t len = PyByteArray_GET_SIZE (self ), n ;
1786- const char * s = PyByteArray_AS_STRING (self ), * sub ;
1787- PyObject * list ;
1788- Py_buffer vsub ;
1802+ PyObject * list = NULL ;
1803+
1804+ /* Increase exports to prevent bytearray storage from changing during _Py_bytes_contains(). */
1805+ self -> ob_exports ++ ;
1806+ const char * sbuf = PyByteArray_AS_STRING (self );
1807+ Py_ssize_t slen = PyByteArray_GET_SIZE ((PyObject * )self );
17891808
17901809 if (maxsplit < 0 )
17911810 maxsplit = PY_SSIZE_T_MAX ;
17921811
1793- if (sep == Py_None )
1794- return stringlib_split_whitespace ((PyObject * ) self , s , len , maxsplit );
1812+ if (sep == Py_None ) {
1813+ list = stringlib_split_whitespace ((PyObject * )self , sbuf , slen , maxsplit );
1814+ goto done ;
1815+ }
17951816
1796- if ( PyObject_GetBuffer ( sep , & vsub , PyBUF_SIMPLE ) != 0 )
1797- return NULL ;
1798- sub = vsub . buf ;
1799- n = vsub . len ;
1817+ Py_buffer vsub ;
1818+ if ( PyObject_GetBuffer ( sep , & vsub , PyBUF_SIMPLE ) != 0 ) {
1819+ goto done ;
1820+ }
18001821
1801- list = stringlib_split (
1802- (PyObject * ) self , s , len , sub , n , maxsplit
1803- );
1822+ list = stringlib_split ((PyObject * )self , sbuf , slen ,
1823+ (const char * )vsub .buf , vsub .len , maxsplit );
18041824 PyBuffer_Release (& vsub );
1825+
1826+ done :
1827+ self -> ob_exports -- ;
18051828 return list ;
18061829}
18071830
@@ -1900,26 +1923,32 @@ bytearray_rsplit_impl(PyByteArrayObject *self, PyObject *sep,
19001923 Py_ssize_t maxsplit )
19011924/*[clinic end generated code: output=a55e0b5a03cb6190 input=60e9abf305128ff4]*/
19021925{
1903- Py_ssize_t len = PyByteArray_GET_SIZE (self ), n ;
1904- const char * s = PyByteArray_AS_STRING (self ), * sub ;
1905- PyObject * list ;
1906- Py_buffer vsub ;
1926+ PyObject * list = NULL ;
1927+
1928+ /* Increase exports to prevent bytearray storage from changing during _Py_bytes_contains(). */
1929+ self -> ob_exports ++ ;
1930+ const char * sbuf = PyByteArray_AS_STRING (self );
1931+ Py_ssize_t slen = PyByteArray_GET_SIZE ((PyObject * )self );
19071932
19081933 if (maxsplit < 0 )
19091934 maxsplit = PY_SSIZE_T_MAX ;
19101935
1911- if (sep == Py_None )
1912- return stringlib_rsplit_whitespace ((PyObject * ) self , s , len , maxsplit );
1936+ if (sep == Py_None ) {
1937+ list = stringlib_rsplit_whitespace ((PyObject * )self , sbuf , slen , maxsplit );
1938+ goto done ;
1939+ }
19131940
1914- if ( PyObject_GetBuffer ( sep , & vsub , PyBUF_SIMPLE ) != 0 )
1915- return NULL ;
1916- sub = vsub . buf ;
1917- n = vsub . len ;
1941+ Py_buffer vsub ;
1942+ if ( PyObject_GetBuffer ( sep , & vsub , PyBUF_SIMPLE ) != 0 ) {
1943+ goto done ;
1944+ }
19181945
1919- list = stringlib_rsplit (
1920- (PyObject * ) self , s , len , sub , n , maxsplit
1921- );
1946+ list = stringlib_rsplit ((PyObject * )self , sbuf , slen ,
1947+ (const char * )vsub .buf , vsub .len , maxsplit );
19221948 PyBuffer_Release (& vsub );
1949+
1950+ done :
1951+ self -> ob_exports -- ;
19231952 return list ;
19241953}
19251954
0 commit comments