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

std::path::Path prefix parsing in Windows is inconsistent with other OS's #100833

Closed
ncihnegn opened this issue Aug 21, 2022 · 8 comments
Closed
Labels
A-io Area: `std::io`, `std::fs`, `std::net` and `std::path` C-bug Category: This is a bug. O-windows Operating system: Windows

Comments

@ncihnegn
Copy link

I tried this code:

Path("//tmp/abs_evil2.txt").components()

I expected to see this happen:

RootDir, RootDir, Normal("tmp"), Normal("abs_evil2.txt")

Instead, this happened:

Prefix(PrefixComponent { raw: "//tmp/abs_evil2.txt", parsed: UNC("tmp", "abs_evil2.txt") })
@ChrisDenton
Copy link
Member

This is intentional. Path is an abstraction over the paths of the platform it's used on. On Unix this is a POSIX path and on Windows it's a Win32 path. So they are not expected to work the same across platform.

In this case the path //tmp/abs_evil2.txt is parsed as a Win32 UNC path on Windows. Note also that Windows normalizes / to \ so //tmp/abs_evil2.txt is equivalent to \\tmp\abs_evil2.txt.

@ChrisDenton
Copy link
Member

@rustbot label +O-windows +A-io

@rustbot rustbot added A-io Area: `std::io`, `std::fs`, `std::net` and `std::path` O-windows Operating system: Windows labels Aug 21, 2022
@ncihnegn
Copy link
Author

I think it is incorrect to parse a POSIX path into a Win32 path.

A path should be parsed as UNC only if it starts with \\, not when it starts with //.

@Kobata
Copy link

Kobata commented Aug 22, 2022

There is no difference, as pointed out above Windows will accept either / or \ mostly-equivalently[1].

It's fairly easy to see, for instance in cmd running something like dir "//./C:/" (you do need the quotes for it to think it's a path) is equivalent to dir \\.\C:\ (which is also equivalent to dir "C:/" and dir C:\)

[1] The exception is paths that begin with exactly \\?\, using backslashes, //?/ is also a valid path-prefix but doesn't have the special handling that the backspace-version does.

@ncihnegn
Copy link
Author

Is there any way to force POSIX path parsing or disable UNC parsing?

@ChrisDenton
Copy link
Member

ChrisDenton commented Aug 22, 2022

Disabling UNC parsing wouldn't make sense, even if it were possible it's still a Windows path so / wouldn't be a RootDir. What you're looking for is UnixPath which doesn't yet exist in std. Currently you'd have to use a third party crate (or make your own).

@chipsenkbeil
Copy link

@ncihnegn @ChrisDenton I just published typed-path as a means to partially solve this problem by providing UnixPath and WindowsPath, in case you were interested in something like this.

@ChrisDenton
Copy link
Member

Great! I'm closing this issue in favour of #66621 or using a crate.

alexcrichton pushed a commit to alexcrichton/tar-rs that referenced this issue Jul 5, 2023
Prepend `c:` so that it won't be treated as UNC path.

See rust-lang/rust#100833 for more.
ararslan pushed a commit to ararslan/binstall-tar that referenced this issue Jun 6, 2024
Prepend `c:` so that it won't be treated as UNC path.

See rust-lang/rust#100833 for more.

(cherry picked from commit 7025986)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-io Area: `std::io`, `std::fs`, `std::net` and `std::path` C-bug Category: This is a bug. O-windows Operating system: Windows
Projects
None yet
Development

No branches or pull requests

5 participants