diff --git a/CHANGELOG.md b/CHANGELOG.md index d4d8d83cdff..a4aa0bd0d64 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -78,6 +78,7 @@ Looking for changes that affect our C API? See the [C API Changelog](lib/c-api/C - [#2157](https://github.com/wasmerio/wasmer/pull/2157) Simplify the code behind `WasmPtr` ### Fixed +- [#2397](https://github.com/wasmerio/wasmer/pull/2397) Fix WASI rename temporary file issue. - [#2391](https://github.com/wasmerio/wasmer/pull/2391) Fix Singlepass emit bug, [#2347](https://github.com/wasmerio/wasmer/issues/2347) and [#2159](https://github.com/wasmerio/wasmer/issues/2159) - [#2327](https://github.com/wasmerio/wasmer/pull/2327) Fix memory leak preventing internal instance memory from being freed when a WasmerEnv contained an exported extern (e.g. Memory, etc.). - [#2247](https://github.com/wasmerio/wasmer/pull/2247) Internal WasiFS logic updated to be closer to what WASI libc does when finding a preopened fd for a path. diff --git a/lib/wasi/src/syscalls/mod.rs b/lib/wasi/src/syscalls/mod.rs index 58413a6933c..5071aa273da 100644 --- a/lib/wasi/src/syscalls/mod.rs +++ b/lib/wasi/src/syscalls/mod.rs @@ -2068,7 +2068,7 @@ pub fn path_rename( return __WASI_EEXIST; } let mut out_path = path.clone(); - out_path.push(target_path); + out_path.push(std::path::Path::new(&target_entry_name)); out_path } Kind::Root { .. } => return __WASI_ENOTCAPABLE, diff --git a/tests/wasi-wast/wasi/snapshot1/path_rename.wasm b/tests/wasi-wast/wasi/snapshot1/path_rename.wasm index 9d5c5377ecf..2b99f365993 100755 Binary files a/tests/wasi-wast/wasi/snapshot1/path_rename.wasm and b/tests/wasi-wast/wasi/snapshot1/path_rename.wasm differ diff --git a/tests/wasi-wast/wasi/snapshot1/path_rename.wast b/tests/wasi-wast/wasi/snapshot1/path_rename.wast index 37462eedb39..10e6178eef0 100644 --- a/tests/wasi-wast/wasi/snapshot1/path_rename.wast +++ b/tests/wasi-wast/wasi/snapshot1/path_rename.wast @@ -3,5 +3,5 @@ (wasi_test "path_rename.wasm" (temp_dirs "temp") (assert_return (i64.const 0)) - (assert_stdout "The original file does not still exist!\nFound item: path_renamed_file.txt\n柴犬\n") + (assert_stdout "The original file does not still exist!\nFound item: path_renamed_file.txt\n柴犬\nrun_with_sub_dir: The original file does not still exist!\nrun_with_different_sub_dirs: The original file does not still exist!\n") ) diff --git a/tests/wasi-wast/wasi/tests/path_rename.rs b/tests/wasi-wast/wasi/tests/path_rename.rs index 266990c655f..28ea0dea1be 100644 --- a/tests/wasi-wast/wasi/tests/path_rename.rs +++ b/tests/wasi-wast/wasi/tests/path_rename.rs @@ -5,7 +5,7 @@ use std::fs; use std::io::{Read, Write}; use std::path::PathBuf; -fn main() { +fn run_with_toplevel_dir() { #[cfg(not(target_os = "wasi"))] let mut base = PathBuf::from("test_fs"); #[cfg(target_os = "wasi")] @@ -73,3 +73,95 @@ fn main() { println!("{}", test_str); std::fs::remove_file(file_to_rename_to).unwrap(); } + +fn run_with_sub_dir() { + #[cfg(not(target_os = "wasi"))] + let base = PathBuf::from("test_fs"); + #[cfg(target_os = "wasi")] + let mut base = PathBuf::from("temp"); + + //make a sub-directory + fs::create_dir(base.join("sub")); + + let file_to_create = base.join("sub/path_rename_file.txt"); + let file_to_rename_to = base.join("sub/path_renamed_file.txt"); + + { + let mut f = std::fs::OpenOptions::new() + .create_new(true) + .write(true) + .open(&file_to_create) + .unwrap(); + + let string = "Hello world"; + let bytes: Vec = string.bytes().collect(); + f.write_all(&bytes[..]).unwrap(); + } + + std::fs::rename(&file_to_create, &file_to_rename_to).unwrap(); + let mut file = fs::File::open(&file_to_rename_to).expect("Could not open file"); + if file_to_create.exists() { + println!("run_with_sub_dir: The original file still exists!"); + return; + } else { + println!("run_with_sub_dir: The original file does not still exist!"); + } + + if !file_to_rename_to.exists() { + println!("run_with_sub_dir: The moved file does not exist!"); + return; + } + fs::remove_dir_all(base.join("sub")); +} + +fn run_with_different_sub_dirs() { + #[cfg(not(target_os = "wasi"))] + let base = PathBuf::from("test_fs"); + #[cfg(target_os = "wasi")] + let mut base = PathBuf::from("temp"); + + //make sub-directories + fs::create_dir(base.join("a")); + fs::create_dir(base.join("a/b")); + fs::create_dir(base.join("c")); + fs::create_dir(base.join("c/d")); + fs::create_dir(base.join("c/d/e")); + + let file_to_create = base.join("a/b/path_rename_file.txt"); + let file_to_rename_to = base.join("c/d/e/path_renamed_file.txt"); + + { + let mut f = std::fs::OpenOptions::new() + .create_new(true) + .write(true) + .open(&file_to_create) + .unwrap(); + + let string = "Hello world"; + let bytes: Vec = string.bytes().collect(); + f.write_all(&bytes[..]).unwrap(); + } + + std::fs::rename(&file_to_create, &file_to_rename_to).unwrap(); + let mut file = fs::File::open(&file_to_rename_to).expect("Could not open file"); + if file_to_create.exists() { + println!("run_with_different_sub_dirs: The original file still exists!"); + return; + } else { + println!("run_with_different_sub_dirs: The original file does not still exist!"); + } + + if !file_to_rename_to.exists() { + println!("run_with_different_sub_dirs: The moved file does not exist!"); + return; + } + + fs::remove_dir_all(base.join("a")); + fs::remove_dir_all(base.join("c")); +} + +fn main() { + run_with_toplevel_dir(); + run_with_sub_dir(); + run_with_different_sub_dirs(); +} diff --git a/tests/wasi-wast/wasi/unstable/path_rename.wasm b/tests/wasi-wast/wasi/unstable/path_rename.wasm index 4642d31858a..5945204f8e1 100755 Binary files a/tests/wasi-wast/wasi/unstable/path_rename.wasm and b/tests/wasi-wast/wasi/unstable/path_rename.wasm differ diff --git a/tests/wasi-wast/wasi/unstable/path_rename.wast b/tests/wasi-wast/wasi/unstable/path_rename.wast index 37462eedb39..10e6178eef0 100644 --- a/tests/wasi-wast/wasi/unstable/path_rename.wast +++ b/tests/wasi-wast/wasi/unstable/path_rename.wast @@ -3,5 +3,5 @@ (wasi_test "path_rename.wasm" (temp_dirs "temp") (assert_return (i64.const 0)) - (assert_stdout "The original file does not still exist!\nFound item: path_renamed_file.txt\n柴犬\n") + (assert_stdout "The original file does not still exist!\nFound item: path_renamed_file.txt\n柴犬\nrun_with_sub_dir: The original file does not still exist!\nrun_with_different_sub_dirs: The original file does not still exist!\n") )