-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Handle win32 separator for cygwin paths #141864
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
base: master
Are you sure you want to change the base?
Conversation
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here I just use
cygwin_conv_path
because it handles both cygwin and win32 paths correctly and convert them into absolute POSIX paths.
I was going to raise the issue of encoding, but looking at the code it doesn't seem to deal with WIN_A as a different encoding than POSIX paths, so I guess that's not an issue. I guess I need to have a conversation on the Cygwin list to better understand this.
Finally I reuse the prefix parser from Windows. Now the cygwin use std::path::{absolute, Path};
fn main() {
test_path("C:\\msys64");
test_path("/dev/sda1");
test_path("./sda1");
test_path("/c/Users");
test_path("\\\\?\\UNC/localhost/share");
}
fn test_path(p: impl AsRef<Path>) {
let p = p.as_ref();
let abs = absolute(p).unwrap();
if p.is_absolute() {
println!("{} == {}", p.display(), abs.display());
} else {
println!("{} -> {}", p.display(), abs.display());
}
println!("{:?}", p.components().collect::<Vec<_>>());
} On Windows, it should output (the current drive is
While on Cygwin, it should output
|
Actually rust doesn't handle very well for non-UTF-8 encoding on Unix. |
OK, seems that the command line is converted from UTF-16: https://github.com/cygwin/cygwin/blob/972872c0d396dbf0ce296b8280cee08ce7727b51/winsup/cygwin/dcrt0.cc#L902 And stdin handles the encoding conversion: https://github.com/cygwin/cygwin/blob/972872c0d396dbf0ce296b8280cee08ce7727b51/winsup/cygwin/fhandler/pty.cc#L3935 So I think all inputs are UTF-8 for a Cygwin program, and the developers could not construct a non-UTF-8 Win32 path if they aren't aware of encodings. If they are, they should know that Rust codes are UTF-8:) |
Now I'm a little worried about |
This was originally reported by @Ry0taK through Rust's security disclosure process, and since this affects a still-in-development tier 3 target (with very few users right now) we agreed to let the development of the fix happen in the open. |
This change is T-libs area, so it will require their review. r? rust-lang/libs I'm not familiar with Cygwin API at all, but I see what you want to achieve here, and I think it's sensible.
They wouldn't want to break that API as a normal release, right? I'd expected a documented API to remain backwards compatible. @pietroalbini I'm out of the loop, could you shed some light on your comment? |
Also, there is a typo in both the title and the first commit 😉 |
Cygwin's encoding may not always be UTF-8 - one can set the locale environment variables like they can on Unix to set the encoding, and then the conversions of paths and terminal input will use that encoding instead of UTF-8. |
In such locale, Rust doesn't even work on Linux. That's fair:) |
@mati865 this was originally reported to [email protected] as it could defeat path traversal mitigations like this: if p.components().into_iter().any(|x| x == Component::ParentDir) {
panic!("path traversal");
} By only parsing unix-like paths, it would be possible to sneak in a path traversal using win32 paths. Given the current status of the target we agreed it would be ok to develop the fix in the open. |
@tgross35 ping? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks pretty reasonable to me, a few small comments/questions
@Berrysoft could you add a regression test to this effect that fails without this change? Probably in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One test request then lgtm with a squash
a15c379
to
b6ad7ff
Compare
Should there be some testing of |
I'll add some immediately. |
@jeremyd2019 mind confirming/approving when this looks good to you? Considering you're one of the resident cygwin experts. |
Added tests for |
It looks like Cygwin will take |
Are these tests actually run in CI? I was concerned that the prefix parsing had some hard-coded backslashes that may result in the forward-slash |
No. I ran the tests on my devices... The prefix parser converts all |
Well... You're right then. So when does Cygwin doesn't take P.S. |
I don't know, probably have to ask Corinna when she's online |
I think the tests cover the cases I thought of, with the exception of |
Seems that Cygwin treats |
I think I need more time to think how to handle the |
Now they are handled. Based on my experiments, only |
This comment has been minimized.
This comment has been minimized.
My only concern is will this work out well if the current handling of I posted this question to https://inbox.sourceware.org/cygwin/[email protected]/T/#u |
I don't think it's a bug now. It's only a little wierd. Due to the design of rust std, I choose to identify the whole |
Tested on Cygwin and I found that Cygwin even treats |
This PR handles a issue that cygwin actually supports Win32 path, so we need to handle the Win32 prefix and separaters.
r? @mati865
cc @jeremyd2019
Not sure if I should handle the prefix like the windows target... Cygwin does support win32 paths directly going through the APIs, but I think it's not the recommended way.Here I just use
cygwin_conv_path
because it handles both cygwin and win32 paths correctly and convert them into absolute POSIX paths.UPDATE: Windows path prefix is handled.