From 1dcabe118e5aa74c977f158223cdf5af8ee2adc6 Mon Sep 17 00:00:00 2001 From: Yage Hu Date: Tue, 11 Jun 2024 14:29:39 -0700 Subject: [PATCH] Fix `path_open` trailing slash edge case `path_open` discards trailing slashes when path_open is creating a new file. This is a bug because trailing slash is semantically meaningful. Other runtimes like WasmEdge, Wazero, WAMR, Wasmtime, and Node correctly preserves the trailing slash. fixes #4833 --- lib/wasix/src/syscalls/wasi/path_open.rs | 6 ++++++ tests/wasi-fyi/fs_open_trailing_slash.rs | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/lib/wasix/src/syscalls/wasi/path_open.rs b/lib/wasix/src/syscalls/wasi/path_open.rs index e3aceea8561..5f8033cb63d 100644 --- a/lib/wasix/src/syscalls/wasi/path_open.rs +++ b/lib/wasix/src/syscalls/wasi/path_open.rs @@ -304,6 +304,12 @@ pub(crate) fn path_open_internal( if o_flags.contains(Oflags::DIRECTORY) { return Ok(Err(Errno::Notdir)); } + + // Trailing slash matters. But the underlying opener normalizes it away later. + if path.ends_with('/') { + return Ok(Err(Errno::Isdir)); + } + // strip end file name let (parent_inode, new_entity_name) = diff --git a/tests/wasi-fyi/fs_open_trailing_slash.rs b/tests/wasi-fyi/fs_open_trailing_slash.rs index 1493e145fc3..e534d0442a1 100644 --- a/tests/wasi-fyi/fs_open_trailing_slash.rs +++ b/tests/wasi-fyi/fs_open_trailing_slash.rs @@ -14,14 +14,18 @@ extern "C" { } const ERRNO_SUCCESS: i32 = 0; +const ERRNO_ISDIR: i32 = 31; const ERRNO_NOTDIR: i32 = 54; +const OFLAGS_CREAT: i32 = 1; const RIGHTS_FD_READ: i64 = 2; +const RIGHTS_FD_WRITE: i64 = 64; fn main() { unsafe { let fd = 5; let path_ok = "fyi/fs_open_trailing_slash.dir/file"; let path_bad = "fyi/fs_open_trailing_slash.dir/file/"; + let path_bad_new_file = "fyi/fs_open_trailing_slash.dir/new-file/"; let errno = path_open( fd, 0, @@ -53,5 +57,21 @@ fn main() { errno, ERRNO_NOTDIR, "opening a regular file with a trailing slash should fail" ); + + let errno = path_open( + fd, + 0, + path_bad_new_file.as_ptr() as i32, + path_bad_new_file.len() as i32, + OFLAGS_CREAT, + RIGHTS_FD_READ | RIGHTS_FD_WRITE, + 0, + 0, + 1024, + ); + assert_eq!( + errno, ERRNO_ISDIR, + "creating a regular file with a trailing slash should fail" + ); } }