Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Leading slash in std::env::current_dir output on Windows #10415

Open
maxdeviant opened this issue Mar 17, 2025 · 2 comments
Open

Leading slash in std::env::current_dir output on Windows #10415

maxdeviant opened this issue Mar 17, 2025 · 2 comments
Labels
bug Incorrect behavior in the current implementation that needs fixing

Comments

@maxdeviant
Copy link

maxdeviant commented Mar 17, 2025

We use Wasm and Wasmtime to power the extension system in Zed and are seeing some undesired behavior with std::env::current_dir when executing Wasm on Windows.

I have created a minimized test case that I believe showcases the issue. The repo can be found at maxdeviant/wasmtime-current-dir-repro. It contains CI set up to run the reproduction case on Windows, as well as on macOS and Linux to contrast the behaviors.

If the Wasmtime repo isn't the right place for this issue, let me know where I can redirect it.

Test Case

In the reproduction repo above, I have the following Rust program:

fn main() {
    let pwd = std::env::var("PWD").expect("failed to get PWD");
    println!("PWD: {pwd:?}");

    println!(
        "Before: {:?}",
        std::env::current_dir().expect("failed to get current_dir")
    );

    std::env::set_current_dir(pwd).expect("failed to set current_dir");

    println!(
        "After: {:?}",
        std::env::current_dir().expect("failed to get current_dir")
    );
}

When run on Windows with the PWD environment variable set to D:/a/wasmtime-current-dir-repro/wasmtime-current-dir-repro this is the output of the program:

PWD: "D:/a/wasmtime-current-dir-repro/wasmtime-current-dir-repro"
Before: "/"
After: "/D:/a/wasmtime-current-dir-repro/wasmtime-current-dir-repro"

Steps to Reproduce

  1. Compile the above program with cargo build --target wasm32-wasip1
  2. Run the Wasm program on Windows with wasmtime run --dir=$PWD --env PWD ./target/wasm32-wasip1/debug/wasm-current-dir-repro.wasm
  3. Observe that the std::env::current_dir path in the After: line contains a leading slash

Expected Results

std::env::current_dir returns D:/a/wasmtime-current-dir-repro/wasmtime-current-dir-repro as the path.

Actual Results

std::env::current_dir returns /D:/a/wasmtime-current-dir-repro/wasmtime-current-dir-repro as the path (note the leading slash).

Versions and Environment

Wasmtime version or commit: wasmtime 30.0.2 (398694a59 2025-02-25)

Operating system: Windows 10

Architecture: x64

Extra Info

I also tried testing this with --target wasm32-wasip2 to see if it would make a difference, and it did not: the output remained the same on Windows (containing a leading slash).

@maxdeviant maxdeviant added the bug Incorrect behavior in the current implementation that needs fixing label Mar 17, 2025
@alexcrichton
Copy link
Member

Thanks for the report, and thank you for minimizing this as well, it's much appreciated! I fear though that I may not have great news for you as this is not going to be an easy bug to fix.

Unfortunately this has nothing to do with Wasmtime, it's got everything to do with the guest program itself. However it's also not entirely fair (IMO) to "point the finger of blame" at the guest program. In the end this is basically a situation that's not super well supported today.

To elaborate on that, what's happening here is, as you've seen, a clash of Windows an Unix paths. Windows understands that the leading D:/ is a drive prefix but to a unix path system (which WASI targets use currently) there's no knowledge of the D:/ prefix so it looks like a folder name, meaning "/".join("D:/") produces "/D:/". The default current directory is set in wasi-libc itself which is / by default (as you've seen), so changing the current directory to D:/... is interpreted in a similar manner to set_current_dir("foo") which would change to /foo. Effectively WASI and wasi-libc are using a unix-like filesystem format and there's nothing on Windows to do any sort of translation between the two.

The question is then somewhat: "who should do this translation?" A reasonable answer is "wasmtime!" but unfortunately the tools aren't in place for that right now. For example to Wasmtime this is "just another env var" being passed to the program and it has no idea that PWD is in fact a path. Wasmtime would then additionally need to have some sort of translation understanding that when mounting the root path there's some sort of understanding/translation to access the various drives. This is all theoretically possible but not set up today.

So in essence the problem you're running into is that when giving access to the whole filesystem to windows guest someone or something will have to do translation of windows paths. As-is today something would have to translate D:/... to something unix-like (like /d/...) and would need to translate both ways (e.g. passing paths to the guest and processing paths received from the guest as well). My gut is that something in wasmtime-wasi probably wants to do this as opposed to guest programs and/or changes to wasi-libc, but I'm not actually sure what that would look like. Overall I don't think we've sufficiently filled out functionality in "give the guest access to the entire host drive" in Wasmtime, which is where this is all stemming from.

cc @sunfishcode this seems like the kind of bug/issue you might be interested in being aware of

@maxdeviant
Copy link
Author

Thank you for the reply, @alexcrichton!

Unfortunately this has nothing to do with Wasmtime, it's got everything to do with the guest program itself. However it's also not entirely fair (IMO) to "point the finger of blame" at the guest program. In the end this is basically a situation that's not super well supported today.

This is pretty much what I expected, but wanted to make get confirmation by opening this issue rather than simply assuming 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Incorrect behavior in the current implementation that needs fixing
Projects
None yet
Development

No branches or pull requests

2 participants