Skip to content

Commit 11f329d

Browse files
committed
Auto merge of #8136 - hbina:error_on_illegal_in_windows, r=ehuss
Added warning when using restricted names in Windows. 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 ^^
2 parents fc0f447 + 2c67111 commit 11f329d

File tree

4 files changed

+81
-24
lines changed

4 files changed

+81
-24
lines changed

src/cargo/ops/cargo_package.rs

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -823,25 +823,12 @@ fn check_filename(file: &Path, shell: &mut Shell) -> CargoResult<()> {
823823
file.display()
824824
)
825825
}
826-
let mut check_windows = |name| -> CargoResult<()> {
827-
if restricted_names::is_windows_reserved(name) {
828-
shell.warn(format!(
829-
"file {} is a reserved Windows filename, \
826+
if restricted_names::is_windows_reserved_path(file) {
827+
shell.warn(format!(
828+
"file {} is a reserved Windows filename, \
830829
it will not work on Windows platforms",
831-
file.display()
832-
))?;
833-
}
834-
Ok(())
835-
};
836-
for component in file.iter() {
837-
if let Some(component) = component.to_str() {
838-
check_windows(component)?;
839-
}
840-
}
841-
if file.extension().is_some() {
842-
if let Some(stem) = file.file_stem().and_then(|s| s.to_str()) {
843-
check_windows(stem)?;
844-
}
830+
file.display()
831+
))?;
845832
}
846833
Ok(())
847834
}

src/cargo/sources/registry/mod.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ use crate::sources::PathSource;
178178
use crate::util::errors::CargoResultExt;
179179
use crate::util::hex;
180180
use crate::util::into_url::IntoUrl;
181-
use crate::util::{CargoResult, Config, Filesystem};
181+
use crate::util::{restricted_names, CargoResult, Config, Filesystem};
182182

183183
const PACKAGE_SOURCE_LOCK: &str = ".cargo-ok";
184184
pub const CRATES_IO_INDEX: &str = "https://github.com/rust-lang/crates.io-index";
@@ -495,11 +495,18 @@ impl<'cfg> RegistrySource<'cfg> {
495495
prefix
496496
)
497497
}
498-
499-
// Once that's verified, unpack the entry as usual.
500-
entry
501-
.unpack_in(parent)
502-
.chain_err(|| format!("failed to unpack entry at `{}`", entry_path.display()))?;
498+
// Unpacking failed
499+
let mut result = entry.unpack_in(parent).map_err(anyhow::Error::from);
500+
if cfg!(windows) && restricted_names::is_windows_reserved_path(&entry_path) {
501+
result = result.chain_err(|| {
502+
format!(
503+
"`{}` appears to contain a reserved Windows path, \
504+
it cannot be extracted on Windows",
505+
entry_path.display()
506+
)
507+
});
508+
}
509+
result.chain_err(|| format!("failed to unpack entry at `{}`", entry_path.display()))?;
503510
}
504511

505512
// Write to the lock file to indicate that unpacking was successful.

src/cargo/util/restricted_names.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
33
use crate::util::CargoResult;
44
use anyhow::bail;
5+
use std::path::Path;
56

67
/// Returns `true` if the name contains non-ASCII characters.
78
pub fn is_non_ascii_name(name: &str) -> bool {
@@ -81,3 +82,13 @@ pub fn validate_package_name(name: &str, what: &str, help: &str) -> CargoResult<
8182
}
8283
Ok(())
8384
}
85+
86+
// Check the entire path for names reserved in Windows.
87+
pub fn is_windows_reserved_path(path: &Path) -> bool {
88+
path.iter()
89+
.filter_map(|component| component.to_str())
90+
.any(|component| {
91+
let stem = component.split('.').next().unwrap();
92+
is_windows_reserved(stem)
93+
})
94+
}

tests/testsuite/package.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1744,3 +1744,55 @@ src/lib.rs
17441744
)
17451745
.run();
17461746
}
1747+
1748+
#[cargo_test]
1749+
#[cfg(windows)]
1750+
fn reserved_windows_name() {
1751+
Package::new("bar", "1.0.0")
1752+
.file("src/lib.rs", "pub mod aux;")
1753+
.file("src/aux.rs", "")
1754+
.publish();
1755+
1756+
let p = project()
1757+
.file(
1758+
"Cargo.toml",
1759+
r#"
1760+
[project]
1761+
name = "foo"
1762+
version = "0.0.1"
1763+
authors = []
1764+
license = "MIT"
1765+
description = "foo"
1766+
1767+
[dependencies]
1768+
bar = "1.0.0"
1769+
"#,
1770+
)
1771+
.file("src/main.rs", "extern crate bar;\nfn main() { }")
1772+
.build();
1773+
p.cargo("package")
1774+
.with_status(101)
1775+
.with_stderr_contains(
1776+
"\
1777+
error: failed to verify package tarball
1778+
1779+
Caused by:
1780+
failed to download replaced source registry `[..]`
1781+
1782+
Caused by:
1783+
failed to unpack package `[..] `[..]`)`
1784+
1785+
Caused by:
1786+
failed to unpack entry at `[..]aux.rs`
1787+
1788+
Caused by:
1789+
`[..]aux.rs` appears to contain a reserved Windows path, it cannot be extracted on Windows
1790+
1791+
Caused by:
1792+
failed to unpack `[..]aux.rs`
1793+
1794+
Caused by:
1795+
failed to unpack `[..]aux.rs` into `[..]aux.rs`",
1796+
)
1797+
.run();
1798+
}

0 commit comments

Comments
 (0)