From c1b730a329cca64329dc78845ecf96dfb50e20c8 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 14 Apr 2026 07:17:59 -0700 Subject: [PATCH] Limit async stream read/write lengths The canonical ABI requires that the maximum size of any one stream operation is `(1 << 28) - 1`, so this commit places that limit on the runtime implementation. This generally isn't applicable but it does get used for `stream` without a payload where otherwise the capacity of vectors is `usize::MAX`, hence large reads/writes. --- .../guest-rust/src/rt/async_support/stream_support.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/crates/guest-rust/src/rt/async_support/stream_support.rs b/crates/guest-rust/src/rt/async_support/stream_support.rs index 6e4771827..f2e1e1be2 100644 --- a/crates/guest-rust/src/rt/async_support/stream_support.rs +++ b/crates/guest-rust/src/rt/async_support/stream_support.rs @@ -17,6 +17,9 @@ use { }, }; +/// Maximum size of a read/write operation as specified by the canonical ABI. +const MAX_LENGTH: usize = (1 << 28) - 1; + /// Operations that a stream requires throughout the implementation. /// /// This is generated by `wit_bindgen::generate!` primarily. @@ -376,7 +379,11 @@ where let (ptr, len) = buf.abi_ptr_and_len(); // SAFETY: sure hope this is safe, everything in this module and // `AbiBuffer` is trying to make this safe. - let code = unsafe { self.writer.ops.start_write(self.writer.handle, ptr, len) }; + let code = unsafe { + self.writer + .ops + .start_write(self.writer.handle, ptr, len.min(MAX_LENGTH)) + }; rtdebug!( "stream.write({}, {ptr:?}, {len}) = {code:#x}", self.writer.handle @@ -618,7 +625,7 @@ unsafe impl<'a, O: StreamOps> WaitableOp for StreamReadOp<'a, O> { let code = unsafe { self.reader .ops - .start_read(self.reader.handle(), ptr, cap.len()) + .start_read(self.reader.handle(), ptr, cap.len().min(MAX_LENGTH)) }; rtdebug!( "stream.read({}, {ptr:?}, {}) = {code:#x}",