Skip to content

wasi:io: enforce the check-write permit in the remaining output streams - #14520

Open
xia-chao wants to merge 1 commit into
bytecodealliance:mainfrom
xia-chao:wasi-write-permit-complete
Open

xia-chao wants to merge 1 commit into
bytecodealliance:mainfrom
xia-chao:wasi-write-permit-complete

Conversation

@xia-chao

@xia-chao xia-chao commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

A stream has to trap when you write more than check-write allowed. Three don't:

SinkOutputStream — a guest's stdout with -Sinherit-stdout=n:

impl OutputStream for SinkOutputStream {
fn write(&mut self, _buf: Bytes) -> Result<(), StreamError> {
Ok(())
}
fn flush(&mut self) -> Result<(), StreamError> {
// This stream is always flushed
Ok(())
}
fn check_write(&mut self) -> Result<usize, StreamError> {
// This stream is always ready for writing.
Ok(crate::MAX_READ_SIZE_ALLOC)
}
}

OutputFile:

impl OutputStream for OutputFile {
fn write(&mut self, bytes: Bytes) -> StreamResult<()> {
(&*self.file)
.write_all(&bytes)
.map_err(|e| StreamError::LastOperationFailed(wasmtime::format_err!(e)))
}
fn flush(&mut self) -> StreamResult<()> {
use std::io::Write;
self.file
.flush()
.map_err(|e| StreamError::LastOperationFailed(wasmtime::format_err!(e)))
}
fn check_write(&mut self) -> StreamResult<usize> {
Ok(crate::MAX_READ_SIZE_ALLOC)
}

CustomOutputStream:

impl wasmtime_wasi::p2::OutputStream for CustomOutputStream {
fn write(&mut self, bytes: Bytes) -> Result<(), StreamError> {
let wrote = self
.inner
.raw_write(&bytes)
.map_err(|e| StreamError::LastOperationFailed(e.into()))?;
if wrote != bytes.len() {
return Err(StreamError::LastOperationFailed(wasmtime::format_err!(
"Partial writes in wasip2 implementation are not allowed"
)));
}
Ok(())
}
fn flush(&mut self) -> Result<(), StreamError> {
Ok(())
}
fn check_write(&mut self) -> Result<usize, StreamError> {
Ok(64 * 1024)
}
}

They hand back a number and then take anything. All three always give the same number, so one check is enough.

Spec:

/// Check readiness for writing. This function never blocks.
///
/// Returns the number of bytes permitted for the next call to `write`,
/// or an error. Calling `write` with more bytes than this function has
/// permitted will trap.
///
/// When this function returns 0 bytes, the `subscribe` pollable will
/// become ready when this function will report at least 1 byte, or an
/// error.
@since(version = 0.2.0)
check-write: func() -> result<u64, stream-error>;
/// Perform a write. This function never blocks.
///
/// When the destination of a `write` is binary data, the bytes from
/// `contents` are written verbatim. When the destination of a `write` is
/// known to the implementation to be text, the bytes of `contents` are
/// transcoded from UTF-8 into the encoding of the destination and then
/// written.
///
/// Precondition: check-write gave permit of Ok(n) and contents has a
/// length of less than or equal to n. Otherwise, this function will trap.

@xia-chao
xia-chao requested review from a team as code owners October 4, 2026 08:52
@xia-chao
xia-chao requested review from pchickey and removed request for a team October 4, 2026 08:52
`wasi:io/streams` says a `write` longer than the permit `check-write`
reported has to trap. Three output streams report a permit and then accept
any number of bytes: `SinkOutputStream`, `OutputFile` and the C API's
`CustomOutputStream`.

All three report a constant, so a constant comparison is enough to enforce
the permit, matching what `StdioOutputStream` and `FileOutputStream` already
do.

A guest reaches the first one as its stdout under `-Sinherit-stdout=n`.
@xia-chao
xia-chao force-pushed the wasi-write-permit-complete branch from 8b3a2e7 to de3b6af Compare October 4, 2026 09:42
@github-actions github-actions Bot added wasi Issues pertaining to WASI wasmtime:c-api Issues pertaining to the C API. labels Oct 4, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

wasi Issues pertaining to WASI wasmtime:c-api Issues pertaining to the C API.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant