-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
path.push() should work as expected on windows verbatim paths #89270
Conversation
This comment has been minimized.
This comment has been minimized.
This mixes two orthogonal functions
The microsoft docs say that those actually are allowed in paths with the verbatim prefix and will access files named |
I think it would be great to have something that addresses this but there I there should perhaps be a holistic look at Windows path handling in Rust before adding adhoc methods as there are currently numerous open issues with paths. Discussions like this are probably best had on the internals forum or Zulip. Personally speaking, my thinking at the moment is that I guess |
d5c0893
to
a3c0ae2
Compare
This comment has been minimized.
This comment has been minimized.
6bacc73
to
8575dbb
Compare
This comment has been minimized.
This comment has been minimized.
8575dbb
to
0361a3d
Compare
That is probably a good idea. In order to facilitate that discussion, I'm updating this PR.
This is a good point and I totally agree this. I've updated this PR to do exactly that.
|
I don't think this is true. I've tried creating |
Can you explain how it wouldn't solve it?
That might depend on the filesystem. I think it's similar on linux. On most filesystems |
Consider
Your original point was about Windows, so I tried this on Windows:
(I tried On Linux (BTW I'm a kernel maintainer) |
Then why not
Maybe it's limited to dir entry enumeration, but I do recall getting surprising results when using FUSE
But did you try with different filesystems? E.g. FAT? I don't have a windows machine here, otherwise I'd poke around myself. I assume there is a reason why the documentation says:
|
Because I assumed that
path walks are done for file creation too. It would be interesting to hear more about "surprising results".
Now this is interesting - and I didn't expect this. With FAT and exFAT you can create files called If you then mount the file system on Linux, it cannot deal with the So now the question is, if verbatim paths permit
I can see the appeal of the |
Btw, I wrote a thing about NT and Win32 paths, in case it helps. The short version is NT paths can include anything except So these NT paths are essentially impossible to handle sensibly with Rust's I think |
Very interesting.
I concur completely. I would much rather see path join handling of If anyone wants to create a path like |
0361a3d
to
0bdbaf3
Compare
This comment has been minimized.
This comment has been minimized.
0bdbaf3
to
c1866d4
Compare
r? rust-lang/libs |
1c61cde
to
ddddc1a
Compare
path.push() should work as expected on windows verbatim paths On Windows, std::fs::canonicalize() returns an so-called UNC path. UNC paths differ with regular paths because: - This type of path can much longer than a non-UNC path (32k vs 260 characters). - The prefix for a UNC path is ``Component::Prefix(Prefix::DiskVerbatim(..)))`` - No `/` is allowed - No `.` is allowed - No `..` is allowed Rust has poor handling of such paths. If you join a UNC path with a path with any of the above, then this will not work. I've implemented a new method `fn join_fold()` which joins paths and also removes any `.` and `..` from it, and replaces `/` with `\` on Windows. Using this function it is possible to use UNC paths without issue. In addition, this function is useful on Linux too; paths can be appended without having to call `canonicalize()` to remove the `.` and `..`. This PR needs test cases, which can I add. I hope this will a start of a discussion.
path.push() should work as expected on windows verbatim paths On Windows, std::fs::canonicalize() returns an so-called UNC path. UNC paths differ with regular paths because: - This type of path can much longer than a non-UNC path (32k vs 260 characters). - The prefix for a UNC path is ``Component::Prefix(Prefix::DiskVerbatim(..)))`` - No `/` is allowed - No `.` is allowed - No `..` is allowed Rust has poor handling of such paths. If you join a UNC path with a path with any of the above, then this will not work. I've implemented a new method `fn join_fold()` which joins paths and also removes any `.` and `..` from it, and replaces `/` with `\` on Windows. Using this function it is possible to use UNC paths without issue. In addition, this function is useful on Linux too; paths can be appended without having to call `canonicalize()` to remove the `.` and `..`. This PR needs test cases, which can I add. I hope this will a start of a discussion.
path.push() should work as expected on windows verbatim paths On Windows, std::fs::canonicalize() returns an so-called UNC path. UNC paths differ with regular paths because: - This type of path can much longer than a non-UNC path (32k vs 260 characters). - The prefix for a UNC path is ``Component::Prefix(Prefix::DiskVerbatim(..)))`` - No `/` is allowed - No `.` is allowed - No `..` is allowed Rust has poor handling of such paths. If you join a UNC path with a path with any of the above, then this will not work. I've implemented a new method `fn join_fold()` which joins paths and also removes any `.` and `..` from it, and replaces `/` with `\` on Windows. Using this function it is possible to use UNC paths without issue. In addition, this function is useful on Linux too; paths can be appended without having to call `canonicalize()` to remove the `.` and `..`. This PR needs test cases, which can I add. I hope this will a start of a discussion.
…ingjubilee Rollup of 15 pull requests Successful merges: - rust-lang#87993 (Stabilize try_reserve) - rust-lang#88090 (Perform type inference in range pattern) - rust-lang#88780 (Added abs_diff for integer types.) - rust-lang#89270 (path.push() should work as expected on windows verbatim paths) - rust-lang#89413 (Correctly handle supertraits for min_specialization) - rust-lang#89456 (Update to the final LLVM 13.0.0 release) - rust-lang#89466 (Fix bug with query modifier parsing) - rust-lang#89473 (Fix extra `non_snake_case` warning for shorthand field bindings) - rust-lang#89474 (rustdoc: Improve doctest pass's name and module's name) - rust-lang#89478 (Fixed numerus of error message) - rust-lang#89480 (Add test for issue 89118.) - rust-lang#89487 (Try to recover from a `=>` -> `=` or `->` typo in a match arm) - rust-lang#89494 (Deny `where` clauses on `auto` traits) - rust-lang#89511 (:arrow_up: rust-analyzer) - rust-lang#89536 (update Miri) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
Since rust-lang/rust#89270 rust's pathbuf push() normalizes the path if it is a verbatim path, so that the result is still a valid verbatim path. This involves parsing reconstructing the path. Appending a path separator using push("") will no longer work, and if it did, it would be very inefficient. rust-lang/rust#89658 Signed-off-by: Sean Young <sean@mess.org>
I am aware of these issues but not knowledgeable. Thank you for the good discussion, both here and on zulip! I think I am convinced that this is a positive change. But, I am very surprised about the process here! Given this is a subtle change to windows behavior I would have expected knowledgeable parties to be cc'ed, like @ehuss or @retep998 maybe @kennykerr or @rylev. Given that this is a (invisible to crater) breaking change to a stable API I would expect some team to need to do a FCP, maybe @rust-lang/libs-api. And for there to be a discussion of how we are going to let people know about the breaking change. |
I agree this is the right change to make, but yes there should have been an FCP given this was a behavioral change to a rather fundamental stable API. |
On Windows, Path::join may makes invalid UNC path. It was fixed on nightly (rust-lang/rust#89270), but not yet on stable.
Since rust 1.57.0, path.push() works correctly on verbatim paths on Windows. See rust-lang/rust#89270 Signed-off-by: Sean Young <sean@mess.org>
Since rust 1.57.0, path.push() works correctly on verbatim paths on Windows. See rust-lang/rust#89270 Signed-off-by: Sean Young <sean@mess.org>
Since rust 1.57.0, path.push() works correctly on verbatim paths on Windows. See rust-lang/rust#89270 Signed-off-by: Sean Young <sean@mess.org>
Since rust 1.57.0, path.push() works correctly on verbatim paths on Windows. See rust-lang/rust#89270 Signed-off-by: Sean Young <sean@mess.org>
On Windows, std::fs::canonicalize() returns an so-called UNC path. UNC paths differ with regular paths because:
Component::Prefix(Prefix::DiskVerbatim(..)))
/
is allowed.
is allowed..
is allowedRust has poor handling of such paths. If you join a UNC path with a path with any of the above, then this will not work.
I've implemented a new method
fn join_fold()
which joins paths and also removes any.
and..
from it, and replaces/
with\
on Windows. Using this function it is possible to use UNC paths without issue. In addition, this function is useful on Linux too; paths can be appended without having to callcanonicalize()
to remove the.
and..
.This PR needs test cases, which can I add. I hope this will a start of a discussion.