-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Added warning when using restricted names in Windows. #8136
Conversation
r? @Eh2406 (rust_highfive has picked a reviewer for you, use r? to override) |
Thanks for the PR! What I would do is extract this code into a new function Also, I don't think there should be any message for non-windows platforms. These filenames aren't a problem for non-windows users. You'll need to place this in the |
@ehuss something like this? |
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.
Can you write a test for this? Use Package
to publish a package with an invalid filename, and then try to use it as a dependency, and then run cargo build
. Let me know if you have any questions about writing tests.
Also, it would be good to reuse is_windows_reserved_path
in cargo_package::check_filename
.
@@ -81,3 +82,20 @@ pub fn validate_package_name(name: &str, what: &str, help: &str) -> CargoResult< | |||
} | |||
Ok(()) | |||
} | |||
|
|||
// Check the entire path for names reserved in Windows. | |||
pub fn is_windows_reserved_path(path: &Path) -> bool { |
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 instead of fold
, it might be simpler to use any
. Also, it's probably more correct to check every path component. So this function could maybe be rewritten as:
path.iter()
.filter_map(|component| component.to_str())
.any(|component| {
let stem = component.split('.').next().unwrap();
is_windows_reserved(stem)
})
src/cargo/sources/registry/mod.rs
Outdated
entry | ||
.unpack_in(parent) | ||
.chain_err(|| format!("failed to unpack entry at `{}`", entry_path.display()))?; | ||
entry.unpack_in(parent).chain_err(|| { |
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.
Would it be possible to structure this such that the error looks something roughly like this?
error: failed to download ...
Caused by:
failed to unpack package ...
Caused by:
failed to unpack entry at '{PATH}'
Caused by:
'{PATH}' appears to contain a reserved windows path, it cannot be extracted on Windows
Caused by:
... More details from tar
So that the windows note is a separate item in the cause chain. You'll need to use let mut result = …
to be able to conditionally chain the error, then result = result.chain_err(|| …);
inside the condition.
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.
Do you have an example of this kind of error chaining in the codebase?
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.
No, but I think it would look something like this:
let mut result = entry.unpack_in(parent).map_err(anyhow::Error::from);
if cfg!(windows) && restricted_names::is_windows_reserved_path(&entry_path) {
result = result.chain_err(|| {
format!(
"`{}` appears to contain a reserved windows path, \
it cannot be extracted on Windows",
entry_path.display()
)
});
}
result.chain_err(|| format!("failed to unpack entry at `{}`", entry_path.display()))?;
src/cargo/sources/registry/mod.rs
Outdated
.chain_err(|| format!("failed to unpack entry at `{}`", entry_path.display()))?; | ||
entry.unpack_in(parent).chain_err(|| { | ||
if cfg!(windows) { | ||
if restricted_names::is_windows_reserved_path(entry_path.as_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 usually use deref to convert to a Path, so entry_path.as_path()
can be &entry_path
.
src/cargo/sources/registry/mod.rs
Outdated
entry.unpack_in(parent).chain_err(|| { | ||
if cfg!(windows) { | ||
if restricted_names::is_windows_reserved_path(entry_path.as_path()) { | ||
format!( |
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.
This doesn't have any effect, since format!
just evaluates to a string, it doesn't return from the closure.
Thanks for all the comments c: I will take a look at it later today. |
So how do I write the test for this? I have this #[cargo_test]
fn reserved_windows_name() {
Package::new("aux", "1.0.0").publish();
let p = project()
.file(
"Cargo.toml",
r#"
[project]
name = "foo"
version = "0.0.1"
authors = []
license = "MIT"
description = "foo"
[dependencies]
aux = "1.0.0"
"#,
)
.file("src/main.rs", "extern crate aux;\nfn main() { }")
.build();
p.cargo("package").run();
} But this panics with in Windows.
|
You'll want to create a package with a normal name (like Package::new("bar", "1.0.0")
.file("src/lib.rs", "pub mod aux;")
.file("src/aux.rs", "")
.publish(); |
☔ The latest upstream changes (presumably #8095) made this pull request unmergeable. Please resolve the merge conflicts. |
bfaaa0b
to
2c67111
Compare
Looks great, thanks! |
📌 Commit 2c67111 has been approved by |
⌛ Testing commit 2c67111 with merge 4845c033736c43fbc4919cee24ac3884c9b7726c... |
💔 Test failed - checks-azure |
☀️ Test successful - checks-azure |
Update cargo 11 commits in 8751eb3010d4cdb5329b5a6bd2b6d765c95b0dca..90931d9b31e8b854522fed00916504a3ac6d8619 2020-04-21 18:04:35 +0000 to 2020-04-28 01:56:59 +0000 - Use associated constants directly on primitive types instead of modules (rust-lang/cargo#8077) - Clear `RUSTDOCFLAGS` before running tests (rust-lang/cargo#8168) - Fix warning for `resolve` mismatch in workspace. (rust-lang/cargo#8169) - Fix flaky linking_interrupted test. (rust-lang/cargo#8162) - Fixed some unnecessary borrows and clones. (rust-lang/cargo#8146) - Added warning when using restricted names in Windows. (rust-lang/cargo#8136) - Add changelog about dylib uplift. (rust-lang/cargo#8161) - Mention that cargo_metadata can parse json messages (rust-lang/cargo#8158) - Re-enable rustc-info-cache test again (rust-lang/cargo#8155) - Updates to path source walking. (rust-lang/cargo#8095) - Bump to 0.46.0, update changelog (rust-lang/cargo#8153)
The implementation could have been better. I think there ought to be a way to only use the views into the
OsString
instead of creating a new one. I am new to Rust so any pointer will help ^^