From 04a4d1e02facaad1675b2811e33541627f1cd7e1 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Sun, 28 Dec 2025 14:48:27 +0900 Subject: [PATCH] Prevent array.tofile re-entrant deadlock and add regression snippet (#6559) Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: youknowone <69878+youknowone@users.noreply.github.com> --- crates/stdlib/src/array.rs | 6 ++++-- extra_tests/snippets/stdlib_array.py | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/crates/stdlib/src/array.rs b/crates/stdlib/src/array.rs index 49ca4a890..b51bc02d3 100644 --- a/crates/stdlib/src/array.rs +++ b/crates/stdlib/src/array.rs @@ -938,8 +938,10 @@ mod array { /* XXX Make the block size settable */ const BLOCKSIZE: usize = 64 * 1024; - let bytes = self.read(); - let bytes = bytes.get_bytes(); + let bytes = { + let bytes = self.read(); + bytes.get_bytes().to_vec() + }; for b in bytes.chunks(BLOCKSIZE) { let b = PyBytes::from(b.to_vec()).into_ref(&vm.ctx); diff --git a/extra_tests/snippets/stdlib_array.py b/extra_tests/snippets/stdlib_array.py index 34eac9491..ed2a8f223 100644 --- a/extra_tests/snippets/stdlib_array.py +++ b/extra_tests/snippets/stdlib_array.py @@ -126,3 +126,20 @@ assert str(i.__class__.__name__) == "arrayiterator" a = array("B", [0]) assert a.__contains__(0) assert not a.__contains__(1) + + +class _ReenteringWriter: + def __init__(self, arr): + self.arr = arr + self.reentered = False + + def write(self, chunk): + if not self.reentered: + self.reentered = True + self.arr.append(0) + return len(chunk) + + +arr = array("b", range(128)) +arr.tofile(_ReenteringWriter(arr)) +assert len(arr) == 129