Skip to content

Commit

Permalink
Auto merge of #10551 - jeremyBanks:Cargo.toml.orig, r=weihanglo
Browse files Browse the repository at this point in the history
Reserve filename `Cargo.toml.orig` in `cargo package`

### What does this PR try to resolve?

_([previously discussed on Zulip](https://rust-lang.zulipchat.com/#narrow/stream/246057-t-cargo/topic/Reserving.20.2FCargo.2Etoml.2Eorig))_

Currently, `cargo package` will detect if there is an existing file named `.cargo_vcs_info.json` in the project folder and raise an error. This is to avoid collisions with the file it generates of the same name.

However, there is no such logic for the other file it generates, `Cargo.toml.orig`. If such a file exists in the project folder, instead of an error, or one file taking precedence, cargo will generate a tarball containing two files with the same name. For example, from a package I uploaded as a test:

```sh
curl https://crates.io/api/v1/crates/a-/0.0.0--a-/download -L | gunzip | tar -tv
```
```text
-rw-r--r--  0 0      0           8 29 Nov  1973 a--0.0.0--a-/.gitignore
-rw-r--r--  0 0      0         150 31 Dec  1969 a--0.0.0--a-/Cargo.lock
-rw-r--r--  0 0      0         641 31 Dec  1969 a--0.0.0--a-/Cargo.toml
-rw-r--r--  0 0      0         160 29 Nov  1973 a--0.0.0--a-/Cargo.toml.orig <-- generated
-rw-r--r--  0 0      0          14 29 Nov  1973 a--0.0.0--a-/Cargo.toml.orig <-- existing
-rw-r--r--  0 0      0          45 29 Nov  1973 a--0.0.0--a-/src/main.rs
```

This PR is a two-line change to add this filename to the existing check for `.cargo_vcs_info.json`.

### How should we test and review this PR?

I have added a unit test to verify that the expected error is produced, copying the existing unit test for `.cargo_vcs_info.json`. I have manually tested the change locally and confirmed that it raises an error if the file exists, and has no effect if it does not. Given the small size of this change, I think this is sufficient, but please let me know if anything else is expected.

### Additional information

This raises a separate question of whether Cargo or crates.io should prohibit tarballs with duplicate filenames. It seems like most (all?) `tar` implementations will give precedence to the last file (which will be the existing copy here, not the generated one), but I don't believe this is specified behaviour, and it's possible that scripts scanning through tarballs directly (without first extracting to the filesystem) may not handle this case correctly. For example, I was working on a rough script to compare packaged libraries to their corresponding Git commits where possible, and this wasn't a case I had anticipated.

In any case, it seems like preventing such tarballs from being created by accident (this PR) is a good place to start.
  • Loading branch information
bors committed Apr 11, 2022
2 parents 1073915 + e71fb81 commit 50d52eb
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 6 deletions.
12 changes: 6 additions & 6 deletions src/cargo/ops/cargo_package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ pub struct PackageOpts<'cfg> {
pub cli_features: CliFeatures,
}

const ORIGINAL_MANIFEST_FILE: &str = "Cargo.toml.orig";
const VCS_INFO_FILE: &str = ".cargo_vcs_info.json";

struct ArchiveFile {
Expand Down Expand Up @@ -219,8 +220,8 @@ fn build_ar_list(
match rel_str.as_ref() {
"Cargo.toml" => {
result.push(ArchiveFile {
rel_path: PathBuf::from("Cargo.toml.orig"),
rel_str: "Cargo.toml.orig".to_string(),
rel_path: PathBuf::from(ORIGINAL_MANIFEST_FILE),
rel_str: ORIGINAL_MANIFEST_FILE.to_string(),
contents: FileContents::OnDisk(src_file),
});
result.push(ArchiveFile {
Expand All @@ -230,10 +231,9 @@ fn build_ar_list(
});
}
"Cargo.lock" => continue,
VCS_INFO_FILE => anyhow::bail!(
"invalid inclusion of reserved file name \
{} in package source",
VCS_INFO_FILE
VCS_INFO_FILE | ORIGINAL_MANIFEST_FILE => anyhow::bail!(
"invalid inclusion of reserved file name {} in package source",
rel_str
),
_ => {
result.push(ArchiveFile {
Expand Down
39 changes: 39 additions & 0 deletions tests/testsuite/package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,45 @@ in package source
.run();
}

#[cargo_test]
fn orig_file_collision() {
let p = project().build();
let _ = git::repo(&paths::root().join("foo"))
.file(
"Cargo.toml",
r#"
[project]
name = "foo"
description = "foo"
version = "0.0.1"
authors = []
license = "MIT"
documentation = "foo"
homepage = "foo"
repository = "foo"
exclude = ["*.no-existe"]
"#,
)
.file(
"src/main.rs",
r#"
fn main() {}
"#,
)
.file("Cargo.toml.orig", "oops")
.build();
p.cargo("package")
.arg("--no-verify")
.with_status(101)
.with_stderr(
"\
[ERROR] invalid inclusion of reserved file name Cargo.toml.orig \
in package source
",
)
.run();
}

#[cargo_test]
fn path_dependency_no_version() {
let p = project()
Expand Down

0 comments on commit 50d52eb

Please sign in to comment.