Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit360540f

Browse files
picnixzbast0006
andauthored
[3.13]gh-91153: prevent a crash inbytearray.__setitem__(ind, ...) whenind.__index__ has side-effects (GH-132379) (#136582)
(cherry picked from commit5e1e21d)Co-authored-by: Bast <52266665+bast0006@users.noreply.github.com>
1 parent6176101 commit360540f

File tree

3 files changed

+43
-3
lines changed

3 files changed

+43
-3
lines changed

‎Lib/test/test_bytes.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1827,6 +1827,8 @@ def test_repeat_after_setslice(self):
18271827
self.assertEqual(b3,b'xcxcxc')
18281828

18291829
deftest_mutating_index(self):
1830+
# bytearray slice assignment can call into python code
1831+
# that reallocates the internal buffer
18301832
# See gh-91153
18311833

18321834
classBoom:
@@ -1844,6 +1846,39 @@ def __index__(self):
18441846
withself.assertRaises(IndexError):
18451847
self._testlimitedcapi.sequence_setitem(b,0,Boom())
18461848

1849+
deftest_mutating_index_inbounds(self):
1850+
# gh-91153 continued
1851+
# Ensure buffer is not broken even if length is correct
1852+
1853+
classMutatesOnIndex:
1854+
def__init__(self):
1855+
self.ba=bytearray(0x180)
1856+
1857+
def__index__(self):
1858+
self.ba.clear()
1859+
self.new_ba=bytearray(0x180)# to catch out-of-bounds writes
1860+
self.ba.extend([0]*0x180)# to check bounds checks
1861+
return0
1862+
1863+
withself.subTest("skip_bounds_safety"):
1864+
instance=MutatesOnIndex()
1865+
instance.ba[instance]=ord("?")
1866+
self.assertEqual(instance.ba[0],ord("?"),"Assigned bytearray not altered")
1867+
self.assertEqual(instance.new_ba,bytearray(0x180),"Wrong object altered")
1868+
1869+
withself.subTest("skip_bounds_safety_capi"):
1870+
instance=MutatesOnIndex()
1871+
instance.ba[instance]=ord("?")
1872+
self._testlimitedcapi.sequence_setitem(instance.ba,instance,ord("?"))
1873+
self.assertEqual(instance.ba[0],ord("?"),"Assigned bytearray not altered")
1874+
self.assertEqual(instance.new_ba,bytearray(0x180),"Wrong object altered")
1875+
1876+
withself.subTest("skip_bounds_safety_slice"):
1877+
instance=MutatesOnIndex()
1878+
instance.ba[instance:1]= [ord("?")]
1879+
self.assertEqual(instance.ba[0],ord("?"),"Assigned bytearray not altered")
1880+
self.assertEqual(instance.new_ba,bytearray(0x180),"Wrong object altered")
1881+
18471882

18481883
classAssortedBytesTest(unittest.TestCase):
18491884
#
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix a crash when a:class:`bytearray` is concurrently mutated during item assignment.

‎Objects/bytearrayobject.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -591,8 +591,10 @@ static int
591591
bytearray_ass_subscript(PyByteArrayObject*self,PyObject*index,PyObject*values)
592592
{
593593
Py_ssize_tstart,stop,step,slicelen,needed;
594-
char*buf,*bytes;
595-
buf=PyByteArray_AS_STRING(self);
594+
char*bytes;
595+
// Do not store a reference to the internal buffer since
596+
// index.__index__() or _getbytevalue() may alter 'self'.
597+
// See https://github.com/python/cpython/issues/91153.
596598

597599
if (_PyIndex_Check(index)) {
598600
Py_ssize_ti=PyNumber_AsSsize_t(index,PyExc_IndexError);
@@ -627,7 +629,7 @@ bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *valu
627629
}
628630
else {
629631
assert(0 <=ival&&ival<256);
630-
buf[i]= (char)ival;
632+
PyByteArray_AS_STRING(self)[i]= (char)ival;
631633
return0;
632634
}
633635
}
@@ -682,6 +684,7 @@ bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *valu
682684
/* Delete slice */
683685
size_tcur;
684686
Py_ssize_ti;
687+
char*buf=PyByteArray_AS_STRING(self);
685688

686689
if (!_canresize(self))
687690
return-1;
@@ -722,6 +725,7 @@ bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *valu
722725
/* Assign slice */
723726
Py_ssize_ti;
724727
size_tcur;
728+
char*buf=PyByteArray_AS_STRING(self);
725729

726730
if (needed!=slicelen) {
727731
PyErr_Format(PyExc_ValueError,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp