From 24b607cf751930c51f2b6449cdfbf2e81dce1c31 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Tue, 18 Apr 2023 11:12:30 -0700 Subject: [PATCH] wasi-common: change behavior of path_readlink to truncate on too-small buffers (#6225) this is the same behavior as exists in posix readlink(2) --- crates/test-programs/wasi-tests/src/bin/readlink.rs | 8 ++++---- crates/wasi-common/src/snapshots/preview_1.rs | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/crates/test-programs/wasi-tests/src/bin/readlink.rs b/crates/test-programs/wasi-tests/src/bin/readlink.rs index b06c01c593..615647247a 100644 --- a/crates/test-programs/wasi-tests/src/bin/readlink.rs +++ b/crates/test-programs/wasi-tests/src/bin/readlink.rs @@ -22,10 +22,10 @@ unsafe fn test_readlink(dir_fd: wasi::Fd) { // Read link into smaller buffer than the actual link's length let buf = &mut [0u8; 4]; - let err = wasi::path_readlink(dir_fd, "symlink", buf.as_mut_ptr(), buf.len()) - .err() - .expect("readlink with too-small buffer should fail"); - assert_errno!(err, wasi::ERRNO_RANGE); + let bufused = wasi::path_readlink(dir_fd, "symlink", buf.as_mut_ptr(), buf.len()) + .expect("readlink with too-small buffer should silently truncate"); + assert_eq!(bufused, 4); + assert_eq!(buf, b"targ"); // Clean up. wasi::path_unlink_file(dir_fd, "target").expect("removing a file"); diff --git a/crates/wasi-common/src/snapshots/preview_1.rs b/crates/wasi-common/src/snapshots/preview_1.rs index 1d8089b7c1..4f5efa6d09 100644 --- a/crates/wasi-common/src/snapshots/preview_1.rs +++ b/crates/wasi-common/src/snapshots/preview_1.rs @@ -801,11 +801,11 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx { .into_string() .map_err(|_| Error::illegal_byte_sequence().context("link contents"))?; let link_bytes = link.as_bytes(); - let link_len = link_bytes.len(); - if link_len > buf_len as usize { - return Err(Error::range()); - } - buf.as_array(link_len as u32).copy_from_slice(link_bytes)?; + // Like posix readlink(2), silently truncate links when they are larger than the + // destination buffer: + let link_len = std::cmp::min(link_bytes.len(), buf_len as usize); + buf.as_array(link_len as u32) + .copy_from_slice(&link_bytes[..link_len])?; Ok(link_len as types::Size) }