@@ -82,6 +82,25 @@ bytearray_releasebuffer(PyObject *self, Py_buffer *view)
8282 Py_END_CRITICAL_SECTION ();
8383}
8484
85+ typedef PyObject * (* _ba_bytes_op )(const char * buf , Py_ssize_t len ,
86+ PyObject * sub , Py_ssize_t start ,
87+ Py_ssize_t end );
88+
89+ static PyObject *
90+ _bytearray_with_buffer (PyByteArrayObject * self , _ba_bytes_op op , PyObject * sub ,
91+ Py_ssize_t start , Py_ssize_t end )
92+ {
93+ PyObject * res ;
94+
95+ _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED (self );
96+
97+ /* Increase exports to prevent bytearray storage from changing during op. */
98+ self -> ob_exports ++ ;
99+ res = op (PyByteArray_AS_STRING (self ), Py_SIZE (self ), sub , start , end );
100+ self -> ob_exports -- ;
101+ return res ;
102+ }
103+
85104static int
86105_canresize (PyByteArrayObject * self )
87106{
@@ -1300,8 +1319,7 @@ bytearray_find_impl(PyByteArrayObject *self, PyObject *sub, Py_ssize_t start,
13001319 Py_ssize_t end )
13011320/*[clinic end generated code: output=413e1cab2ae87da0 input=1de9f4558df68336]*/
13021321{
1303- return _Py_bytes_find (PyByteArray_AS_STRING (self ), PyByteArray_GET_SIZE (self ),
1304- sub , start , end );
1322+ return _bytearray_with_buffer (self , _Py_bytes_find , sub , start , end );
13051323}
13061324
13071325/*[clinic input]
@@ -1316,8 +1334,7 @@ bytearray_count_impl(PyByteArrayObject *self, PyObject *sub,
13161334 Py_ssize_t start , Py_ssize_t end )
13171335/*[clinic end generated code: output=a21ee2692e4f1233 input=2608c30644614724]*/
13181336{
1319- return _Py_bytes_count (PyByteArray_AS_STRING (self ), PyByteArray_GET_SIZE (self ),
1320- sub , start , end );
1337+ return _bytearray_with_buffer (self , _Py_bytes_count , sub , start , end );
13211338}
13221339
13231340/*[clinic input]
@@ -1364,8 +1381,7 @@ bytearray_index_impl(PyByteArrayObject *self, PyObject *sub,
13641381 Py_ssize_t start , Py_ssize_t end )
13651382/*[clinic end generated code: output=067a1e78efc672a7 input=0086ba0ab9bf44a5]*/
13661383{
1367- return _Py_bytes_index (PyByteArray_AS_STRING (self ), PyByteArray_GET_SIZE (self ),
1368- sub , start , end );
1384+ return _bytearray_with_buffer (self , _Py_bytes_index , sub , start , end );
13691385}
13701386
13711387/*[clinic input]
@@ -1382,8 +1398,7 @@ bytearray_rfind_impl(PyByteArrayObject *self, PyObject *sub,
13821398 Py_ssize_t start , Py_ssize_t end )
13831399/*[clinic end generated code: output=51bf886f932b283c input=ac73593305d5c1d1]*/
13841400{
1385- return _Py_bytes_rfind (PyByteArray_AS_STRING (self ), PyByteArray_GET_SIZE (self ),
1386- sub , start , end );
1401+ return _bytearray_with_buffer (self , _Py_bytes_rfind , sub , start , end );
13871402}
13881403
13891404/*[clinic input]
@@ -1400,18 +1415,22 @@ bytearray_rindex_impl(PyByteArrayObject *self, PyObject *sub,
14001415 Py_ssize_t start , Py_ssize_t end )
14011416/*[clinic end generated code: output=38e1cf66bafb08b9 input=0cf331bf5ebe0e91]*/
14021417{
1403- return _Py_bytes_rindex (PyByteArray_AS_STRING (self ), PyByteArray_GET_SIZE (self ),
1404- sub , start , end );
1418+ return _bytearray_with_buffer (self , _Py_bytes_rindex , sub , start , end );
14051419}
14061420
14071421static int
14081422bytearray_contains (PyObject * self , PyObject * arg )
14091423{
1410- int ret ;
1424+ int ret = -1 ;
14111425 Py_BEGIN_CRITICAL_SECTION (self );
1412- ret = _Py_bytes_contains (PyByteArray_AS_STRING (self ),
1426+ PyByteArrayObject * ba = _PyByteArray_CAST (self );
1427+
1428+ /* Increase exports to prevent bytearray storage from changing during _Py_bytes_contains(). */
1429+ ba -> ob_exports ++ ;
1430+ ret = _Py_bytes_contains (PyByteArray_AS_STRING (ba ),
14131431 PyByteArray_GET_SIZE (self ),
14141432 arg );
1433+ ba -> ob_exports -- ;
14151434 Py_END_CRITICAL_SECTION ();
14161435 return ret ;
14171436}
@@ -1437,8 +1456,7 @@ bytearray_startswith_impl(PyByteArrayObject *self, PyObject *subobj,
14371456 Py_ssize_t start , Py_ssize_t end )
14381457/*[clinic end generated code: output=a3d9b6d44d3662a6 input=ea8d036d09df34b2]*/
14391458{
1440- return _Py_bytes_startswith (PyByteArray_AS_STRING (self ), PyByteArray_GET_SIZE (self ),
1441- subobj , start , end );
1459+ return _bytearray_with_buffer (self , _Py_bytes_startswith , subobj , start , end );
14421460}
14431461
14441462/*[clinic input]
@@ -1462,8 +1480,7 @@ bytearray_endswith_impl(PyByteArrayObject *self, PyObject *subobj,
14621480 Py_ssize_t start , Py_ssize_t end )
14631481/*[clinic end generated code: output=e75ea8c227954caa input=c61b90bb23a689ce]*/
14641482{
1465- return _Py_bytes_endswith (PyByteArray_AS_STRING (self ), PyByteArray_GET_SIZE (self ),
1466- subobj , start , end );
1483+ return _bytearray_with_buffer (self , _Py_bytes_endswith , subobj , start , end );
14671484}
14681485
14691486/*[clinic input]
@@ -1736,26 +1753,32 @@ bytearray_split_impl(PyByteArrayObject *self, PyObject *sep,
17361753 Py_ssize_t maxsplit )
17371754/*[clinic end generated code: output=833e2cf385d9a04d input=1c367486b9938909]*/
17381755{
1739- Py_ssize_t len = PyByteArray_GET_SIZE (self ), n ;
1740- const char * s = PyByteArray_AS_STRING (self ), * sub ;
1741- PyObject * list ;
1742- Py_buffer vsub ;
1756+ PyObject * list = NULL ;
1757+
1758+ /* Increase exports to prevent bytearray storage from changing during _Py_bytes_contains(). */
1759+ self -> ob_exports ++ ;
1760+ const char * sbuf = PyByteArray_AS_STRING (self );
1761+ Py_ssize_t slen = PyByteArray_GET_SIZE ((PyObject * )self );
17431762
17441763 if (maxsplit < 0 )
17451764 maxsplit = PY_SSIZE_T_MAX ;
17461765
1747- if (sep == Py_None )
1748- return stringlib_split_whitespace ((PyObject * ) self , s , len , maxsplit );
1766+ if (sep == Py_None ) {
1767+ list = stringlib_split_whitespace ((PyObject * )self , sbuf , slen , maxsplit );
1768+ goto done ;
1769+ }
17491770
1750- if ( PyObject_GetBuffer ( sep , & vsub , PyBUF_SIMPLE ) != 0 )
1751- return NULL ;
1752- sub = vsub . buf ;
1753- n = vsub . len ;
1771+ Py_buffer vsub ;
1772+ if ( PyObject_GetBuffer ( sep , & vsub , PyBUF_SIMPLE ) != 0 ) {
1773+ goto done ;
1774+ }
17541775
1755- list = stringlib_split (
1756- (PyObject * ) self , s , len , sub , n , maxsplit
1757- );
1776+ list = stringlib_split ((PyObject * )self , sbuf , slen ,
1777+ (const char * )vsub .buf , vsub .len , maxsplit );
17581778 PyBuffer_Release (& vsub );
1779+
1780+ done :
1781+ self -> ob_exports -- ;
17591782 return list ;
17601783}
17611784
@@ -1850,26 +1873,32 @@ bytearray_rsplit_impl(PyByteArrayObject *self, PyObject *sep,
18501873 Py_ssize_t maxsplit )
18511874/*[clinic end generated code: output=a55e0b5a03cb6190 input=3cd513c2b94a53c1]*/
18521875{
1853- Py_ssize_t len = PyByteArray_GET_SIZE (self ), n ;
1854- const char * s = PyByteArray_AS_STRING (self ), * sub ;
1855- PyObject * list ;
1856- Py_buffer vsub ;
1876+ PyObject * list = NULL ;
1877+
1878+ /* Increase exports to prevent bytearray storage from changing during _Py_bytes_contains(). */
1879+ self -> ob_exports ++ ;
1880+ const char * sbuf = PyByteArray_AS_STRING (self );
1881+ Py_ssize_t slen = PyByteArray_GET_SIZE ((PyObject * )self );
18571882
18581883 if (maxsplit < 0 )
18591884 maxsplit = PY_SSIZE_T_MAX ;
18601885
1861- if (sep == Py_None )
1862- return stringlib_rsplit_whitespace ((PyObject * ) self , s , len , maxsplit );
1886+ if (sep == Py_None ) {
1887+ list = stringlib_rsplit_whitespace ((PyObject * )self , sbuf , slen , maxsplit );
1888+ goto done ;
1889+ }
18631890
1864- if ( PyObject_GetBuffer ( sep , & vsub , PyBUF_SIMPLE ) != 0 )
1865- return NULL ;
1866- sub = vsub . buf ;
1867- n = vsub . len ;
1891+ Py_buffer vsub ;
1892+ if ( PyObject_GetBuffer ( sep , & vsub , PyBUF_SIMPLE ) != 0 ) {
1893+ goto done ;
1894+ }
18681895
1869- list = stringlib_rsplit (
1870- (PyObject * ) self , s , len , sub , n , maxsplit
1871- );
1896+ list = stringlib_rsplit ((PyObject * )self , sbuf , slen ,
1897+ (const char * )vsub .buf , vsub .len , maxsplit );
18721898 PyBuffer_Release (& vsub );
1899+
1900+ done :
1901+ self -> ob_exports -- ;
18731902 return list ;
18741903}
18751904
0 commit comments