mirror of
https://github.com/python/cpython
synced 2026-11-06 09:02:40 +03:00
[3.15] gh-158803: Fix crash in bytes.join() on a concurrently mutated list (GH-158910)
In the free-threaded build, bytes.join() and bytearray.join() read
items from the list with borrowed references and without holding its
lock, so another thread could replace and free an item before it was
increfed.
Run the join under Py_BEGIN_CRITICAL_SECTION_SEQUENCE_FAST, as
PyUnicode_Join() already does.
(cherry picked from commit 05d80ccfe7)
33 lines
932 B
Python
33 lines
932 B
Python
import unittest
|
|
from threading import Event
|
|
from test.support import threading_helper
|
|
|
|
threading_helper.requires_working_threading(module=True)
|
|
|
|
|
|
class BytesThreading(unittest.TestCase):
|
|
def test_racing_join_replace(self):
|
|
# gh-158803: join() must not use a list item that another thread
|
|
# replaces (and frees) concurrently.
|
|
lst = [bytes(10) for _ in range(100)]
|
|
done = Event()
|
|
|
|
def writer():
|
|
try:
|
|
for _ in range(100):
|
|
for i in range(len(lst)):
|
|
lst[i] = bytearray(10) if i % 2 else bytes(10)
|
|
finally:
|
|
done.set()
|
|
|
|
def reader():
|
|
while not done.is_set():
|
|
b''.join(lst)
|
|
b'-'.join(lst)
|
|
bytearray().join(lst)
|
|
|
|
threading_helper.run_concurrently([writer] + [reader] * 4)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|