-
Notifications
You must be signed in to change notification settings - Fork 898
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
[WIP] Use absolute_path instead of fs::canonicalize #3324
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,8 @@ | ||
use std::borrow::Cow; | ||
use std::io; | ||
use std::path; | ||
|
||
use bytecount; | ||
|
||
use rustc_target::spec::abi; | ||
use syntax::ast::{ | ||
self, Attribute, CrateSugar, MetaItem, MetaItemKind, NestedMetaItem, NestedMetaItemKind, | ||
|
@@ -615,6 +616,47 @@ pub(crate) fn unicode_str_width(s: &str) -> usize { | |
s.width() | ||
} | ||
|
||
#[cfg(windows)] | ||
pub fn absolute_path<P: AsRef<path::Path>>(p: P) -> io::Result<path::PathBuf> { | ||
use std::ffi::OsString; | ||
use std::iter::once; | ||
use std::os::windows::ffi::{OsStrExt, OsStringExt}; | ||
use std::ptr::null_mut; | ||
use winapi::um::errhandlingapi::GetLastError; | ||
use winapi::um::fileapi::GetFullPathNameW; | ||
|
||
// FIXME: This `MAX_PATH` may be valid only from Windows 10, version 1607. | ||
// https://docs.microsoft.com/ja-jp/windows/desktop/FileIO/naming-a-file#paths | ||
const MAX_PATH: usize = 32767; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this is correct. From my reading of the documentation noted above, it looks like a MAX_PATH of 32000+ can only be depended on for Windows 10, for certain later versions, and only if the system/user has opted-in, by changing a registry entry. This, to me, means that it can never be depended on and should likely not be used. MAX_PATH should be ~260 characters for normal paths (absolute or relative). For longer paths (up to 32000+ characters), the path would need to be in "extended" format which means absolute form prefixed with "\\?\". There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems like you cannot use
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tried to prefix the path with
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Must be in absolute path form. |
||
let wide: Vec<u16> = p | ||
.as_ref() | ||
.as_os_str() | ||
.encode_wide() | ||
.chain(once(0)) | ||
.collect(); | ||
let mut buffer: Vec<u16> = vec![0; MAX_PATH]; | ||
unsafe { | ||
let result = GetFullPathNameW( | ||
wide.as_ptr(), | ||
MAX_PATH as u32, | ||
buffer.as_mut_ptr(), | ||
null_mut(), | ||
); | ||
if result == 0 { | ||
Err(std::io::Error::from_raw_os_error(GetLastError() as i32)) | ||
} else { | ||
Ok(path::PathBuf::from(OsString::from_wide( | ||
&buffer[..result as usize], | ||
))) | ||
} | ||
} | ||
} | ||
|
||
#[cfg(not(windows))] | ||
pub fn absolute_path<P: AsRef<path::Path>>(p: P) -> io::Result<path::PathBuf> { | ||
std::fs::canonicalize(p) | ||
} | ||
|
||
pub(crate) fn get_skip_macro_names(attrs: &[ast::Attribute]) -> Vec<String> { | ||
let mut skip_macro_names = vec![]; | ||
for attr in attrs { | ||
|
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.
based on the findings in https://github.com/rust-lang/rustfmt/pull/3309/files#diff-0f04fceb10cfdeda3716c7824a8dc2deR246, maybe you need to get the absolute_path of
manifest_path
: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.
@topecongiro can we merge this PR with #3309 ? this would fix also @rivy 's comment #3324 (comment)
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.
I think this should be a bug against
PathBuf.canonicalize()
. Any conversion to UNC must use the absolute path. PathBuf is taking that responsibility and should do it itself.Here, as a workaround, I think you should use both; canonicalize the absolute path...
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.
I expect a wrapper function (maybe just a passthru for non-windows OS) which executes this work-around would be a good way to proceed. And, I'd replace all uses of canonicalize() in the code base. A quick repo search shows only about about eight uses.
Not meaning to add more work, but any path comparisons should probably be reviewed for possibly needing canonicalizing of both sides. And I'm not sure where those might be scattered throughout the code base.
$0.02
Thanks for taking the time to review and repair this issue.
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.
review this in #3309 once this PR is merged.