Skip to content

Commit 2a874aa

Browse files
committed
Warn when packaging files with Windows special names.
1 parent 15ac82b commit 2a874aa

File tree

2 files changed

+58
-4
lines changed

2 files changed

+58
-4
lines changed

src/cargo/ops/cargo_package.rs

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@ use log::debug;
1313
use tar::{Archive, Builder, EntryType, Header};
1414

1515
use crate::core::compiler::{BuildConfig, CompileMode, DefaultExecutor, Executor};
16-
use crate::core::{Feature, Verbosity, Workspace};
16+
use crate::core::{Feature, Shell, Verbosity, Workspace};
1717
use crate::core::{Package, PackageId, PackageSet, Resolve, Source, SourceId};
1818
use crate::ops;
1919
use crate::sources::PathSource;
2020
use crate::util::errors::{CargoResult, CargoResultExt};
2121
use crate::util::paths;
2222
use crate::util::toml::TomlManifest;
23-
use crate::util::{self, Config, FileLock};
23+
use crate::util::{self, restricted_names, Config, FileLock};
2424

2525
pub struct PackageOpts<'cfg> {
2626
pub config: &'cfg Config,
@@ -142,7 +142,7 @@ fn build_ar_list(
142142
let root = pkg.root();
143143
for src_file in src_files {
144144
let rel_path = src_file.strip_prefix(&root)?.to_path_buf();
145-
check_filename(&rel_path)?;
145+
check_filename(&rel_path, &mut ws.config().shell())?;
146146
let rel_str = rel_path
147147
.to_str()
148148
.ok_or_else(|| {
@@ -804,7 +804,7 @@ fn report_hash_difference(orig: &HashMap<PathBuf, u64>, after: &HashMap<PathBuf,
804804
//
805805
// To help out in situations like this, issue about weird filenames when
806806
// packaging as a "heads up" that something may not work on other platforms.
807-
fn check_filename(file: &Path) -> CargoResult<()> {
807+
fn check_filename(file: &Path, shell: &mut Shell) -> CargoResult<()> {
808808
let name = match file.file_name() {
809809
Some(name) => name,
810810
None => return Ok(()),
@@ -825,5 +825,25 @@ fn check_filename(file: &Path) -> CargoResult<()> {
825825
file.display()
826826
)
827827
}
828+
let mut check_windows = |name| -> CargoResult<()> {
829+
if restricted_names::is_windows_reserved(name) {
830+
shell.warn(format!(
831+
"file {} is a reserved Windows filename, \
832+
it will not work on Windows platforms",
833+
file.display()
834+
))?;
835+
}
836+
Ok(())
837+
};
838+
for component in file.iter() {
839+
if let Some(component) = component.to_str() {
840+
check_windows(component)?;
841+
}
842+
}
843+
if file.extension().is_some() {
844+
if let Some(stem) = file.file_stem().and_then(|s| s.to_str()) {
845+
check_windows(stem)?;
846+
}
847+
}
828848
Ok(())
829849
}

tests/testsuite/package.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1663,3 +1663,37 @@ src/lib.rs
16631663
let orig = read_to_string(p.root().join("target/package/foo-1.0.0/Cargo.toml.orig")).unwrap();
16641664
assert!(orig.contains("license-file = \"../LICENSE\""));
16651665
}
1666+
1667+
#[cargo_test]
1668+
#[cfg(not(windows))] // Don't want to create invalid files on Windows.
1669+
fn package_restricted_windows() {
1670+
let p = project()
1671+
.file(
1672+
"Cargo.toml",
1673+
r#"
1674+
[package]
1675+
name = "foo"
1676+
version = "0.1.0"
1677+
license = "MIT"
1678+
description = "foo"
1679+
homepage = "foo"
1680+
"#,
1681+
)
1682+
.file("src/lib.rs", "pub mod con;\npub mod aux;")
1683+
.file("src/con.rs", "pub fn f() {}")
1684+
.file("src/aux/mod.rs", "pub fn f() {}")
1685+
.build();
1686+
1687+
p.cargo("package")
1688+
.with_stderr(
1689+
"\
1690+
[WARNING] file src/aux/mod.rs is a reserved Windows filename, it will not work on Windows platforms
1691+
[WARNING] file src/con.rs is a reserved Windows filename, it will not work on Windows platforms
1692+
[PACKAGING] foo [..]
1693+
[VERIFYING] foo [..]
1694+
[COMPILING] foo [..]
1695+
[FINISHED] [..]
1696+
",
1697+
)
1698+
.run();
1699+
}

0 commit comments

Comments
 (0)