Skip to content

Commit bed7f4d

Browse files
committed
feat: contains, split, rsplit using ob_exports
1 parent 8d04ec3 commit bed7f4d

File tree

2 files changed

+50
-42
lines changed

2 files changed

+50
-42
lines changed

Lib/test/test_bytes.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2065,6 +2065,11 @@ def test_search_methods_reentrancy_raises_buffererror(self):
20652065
class Evil:
20662066
def __init__(self, ba):
20672067
self.ba = ba
2068+
def __buffer__(self, flags):
2069+
self.ba.clear()
2070+
return memoryview(self.ba)
2071+
def __release_buffer__(self, view: memoryview) -> None:
2072+
view.release()
20682073
def __index__(self):
20692074
self.ba.clear()
20702075
return ord("A")
@@ -2079,6 +2084,14 @@ def make_case():
20792084
with self.assertRaises(BufferError):
20802085
getattr(ba, name)(evil)
20812086

2087+
ba, evil = make_case()
2088+
with self.assertRaises(BufferError):
2089+
evil in ba
2090+
with self.assertRaises(BufferError):
2091+
ba.split(evil)
2092+
with self.assertRaises(BufferError):
2093+
ba.rsplit(evil)
2094+
20822095

20832096
class AssortedBytesTest(unittest.TestCase):
20842097
#

Objects/bytearrayobject.c

Lines changed: 37 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1375,12 +1375,13 @@ static int
13751375
bytearray_contains(PyObject *self, PyObject *arg)
13761376
{
13771377
int ret = -1;
1378-
Py_buffer selfbuf;
13791378
Py_BEGIN_CRITICAL_SECTION(self);
1380-
if (PyObject_GetBuffer((PyObject *)self, &selfbuf, PyBUF_SIMPLE) == 0) {
1381-
ret = _Py_bytes_contains((const char *)selfbuf.buf, selfbuf.len, arg);
1382-
PyBuffer_Release(&selfbuf);
1383-
}
1379+
PyByteArrayObject *ba = _PyByteArray_CAST(self);
1380+
ba->ob_exports++;
1381+
ret = _Py_bytes_contains(PyByteArray_AS_STRING(ba),
1382+
PyByteArray_GET_SIZE(self),
1383+
arg);
1384+
ba->ob_exports--;
13841385
Py_END_CRITICAL_SECTION();
13851386
return ret;
13861387
}
@@ -1793,38 +1794,34 @@ Return a list of the sections in the bytearray, using sep as the delimiter.
17931794
[clinic start generated code]*/
17941795

17951796
static PyObject *
1796-
bytearray_split_impl(PyByteArrayObject *self, PyObject *sep,
1797-
Py_ssize_t maxsplit)
1798-
/*[clinic end generated code: output=833e2cf385d9a04d input=dd9f6e2910cc3a34]*/
1797+
bytearray_split_impl(PyByteArrayObject *self, PyObject *sep, Py_ssize_t maxsplit)
17991798
{
1800-
PyObject *list;
1801-
Py_buffer selfbuf, vsub;
1802-
if (PyObject_GetBuffer((PyObject *)self, &selfbuf, PyBUF_SIMPLE) != 0) {
1803-
return NULL;
1804-
}
1799+
PyObject *list = NULL;
1800+
_Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED((PyObject *)self);
1801+
1802+
self->ob_exports++;
1803+
const char *sbuf = PyByteArray_AS_STRING(self);
1804+
Py_ssize_t slen = PyByteArray_GET_SIZE((PyObject *)self);
18051805

18061806
if (maxsplit < 0)
18071807
maxsplit = PY_SSIZE_T_MAX;
18081808

18091809
if (sep == Py_None) {
1810-
list = stringlib_split_whitespace((PyObject*) self,
1811-
(const char *)selfbuf.buf, selfbuf.len,
1812-
maxsplit);
1813-
PyBuffer_Release(&selfbuf);
1814-
return list;
1810+
list = stringlib_split_whitespace((PyObject*)self, sbuf, slen, maxsplit);
1811+
goto done;
18151812
}
18161813

1814+
Py_buffer vsub;
18171815
if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0) {
1818-
PyBuffer_Release(&selfbuf);
1819-
return NULL;
1816+
goto done;
18201817
}
18211818

1822-
list = stringlib_split(
1823-
(PyObject*) self, (const char *)selfbuf.buf, selfbuf.len,
1824-
(const char *)vsub.buf, vsub.len, maxsplit
1825-
);
1819+
list = stringlib_split((PyObject*)self, sbuf, slen,
1820+
(const char *)vsub.buf, vsub.len, maxsplit);
18261821
PyBuffer_Release(&vsub);
1827-
PyBuffer_Release(&selfbuf);
1822+
1823+
done:
1824+
self->ob_exports--;
18281825
return list;
18291826
}
18301827

@@ -1923,34 +1920,32 @@ bytearray_rsplit_impl(PyByteArrayObject *self, PyObject *sep,
19231920
Py_ssize_t maxsplit)
19241921
/*[clinic end generated code: output=a55e0b5a03cb6190 input=60e9abf305128ff4]*/
19251922
{
1926-
PyObject *list;
1927-
Py_buffer selfbuf, vsub;
1928-
if (PyObject_GetBuffer((PyObject *)self, &selfbuf, PyBUF_SIMPLE) != 0) {
1929-
return NULL;
1930-
}
1923+
PyObject *list = NULL;
1924+
_Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED((PyObject *)self);
1925+
1926+
self->ob_exports++;
1927+
const char *sbuf = PyByteArray_AS_STRING(self);
1928+
Py_ssize_t slen = PyByteArray_GET_SIZE((PyObject *)self);
19311929

19321930
if (maxsplit < 0)
19331931
maxsplit = PY_SSIZE_T_MAX;
19341932

19351933
if (sep == Py_None) {
1936-
list = stringlib_rsplit_whitespace((PyObject*) self,
1937-
(const char *)selfbuf.buf, selfbuf.len,
1938-
maxsplit);
1939-
PyBuffer_Release(&selfbuf);
1940-
return list;
1934+
list = stringlib_rsplit_whitespace((PyObject*)self, sbuf, slen, maxsplit);
1935+
goto done;
19411936
}
19421937

1938+
Py_buffer vsub;
19431939
if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0) {
1944-
PyBuffer_Release(&selfbuf);
1945-
return NULL;
1940+
goto done;
19461941
}
19471942

1948-
list = stringlib_rsplit(
1949-
(PyObject*) self, (const char *)selfbuf.buf, selfbuf.len,
1950-
(const char *)vsub.buf, vsub.len, maxsplit
1951-
);
1943+
list = stringlib_rsplit((PyObject*)self, sbuf, slen,
1944+
(const char *)vsub.buf, vsub.len, maxsplit);
19521945
PyBuffer_Release(&vsub);
1953-
PyBuffer_Release(&selfbuf);
1946+
1947+
done:
1948+
self->ob_exports--;
19541949
return list;
19551950
}
19561951

0 commit comments

Comments
 (0)