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" + ); } }