Skip to content

Commit 548eea7

Browse files
committed
Auto merge of #8453 - sourcefrog:name-length-limit-8452, r=alexcrichton
Write GNU tar files, supporting long names. Fixes #8452 If I understand the previous bugs correctly, long trees packaged using Cargo with this patch will be misinterpreted by Cargo from before Jan 2016. (Without this patch, they can't be written at all.) To me that seems like long enough ago that it's safe to land this now. - [x] Add a test.
2 parents c95c0b1 + 0dfd4a8 commit 548eea7

File tree

2 files changed

+50
-26
lines changed

2 files changed

+50
-26
lines changed

src/cargo/ops/cargo_package.rs

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -501,28 +501,7 @@ fn tar(
501501
config
502502
.shell()
503503
.verbose(|shell| shell.status("Archiving", &rel_str))?;
504-
// The `tar::Builder` type by default will build GNU archives, but
505-
// unfortunately we force it here to use UStar archives instead. The
506-
// UStar format has more limitations on the length of path name that it
507-
// can encode, so it's not quite as nice to use.
508-
//
509-
// Older cargos, however, had a bug where GNU archives were interpreted
510-
// as UStar archives. This bug means that if we publish a GNU archive
511-
// which has fully filled out metadata it'll be corrupt when unpacked by
512-
// older cargos.
513-
//
514-
// Hopefully in the future after enough cargos have been running around
515-
// with the bugfixed tar-rs library we'll be able to switch this over to
516-
// GNU archives, but for now we'll just say that you can't encode paths
517-
// in archives that are *too* long.
518-
//
519-
// For an instance of this in the wild, use the tar-rs 0.3.3 library to
520-
// unpack the selectors 0.4.0 crate on crates.io. Either that or take a
521-
// look at rust-lang/cargo#2326.
522-
let mut header = Header::new_ustar();
523-
header
524-
.set_path(&ar_path)
525-
.chain_err(|| format!("failed to add to archive: `{}`", rel_str))?;
504+
let mut header = Header::new_gnu();
526505
match contents {
527506
FileContents::OnDisk(disk_path) => {
528507
let mut file = File::open(&disk_path).chain_err(|| {
@@ -533,9 +512,10 @@ fn tar(
533512
})?;
534513
header.set_metadata(&metadata);
535514
header.set_cksum();
536-
ar.append(&header, &mut file).chain_err(|| {
537-
format!("could not archive source file `{}`", disk_path.display())
538-
})?;
515+
ar.append_data(&mut header, &ar_path, &mut file)
516+
.chain_err(|| {
517+
format!("could not archive source file `{}`", disk_path.display())
518+
})?;
539519
}
540520
FileContents::Generated(generated_kind) => {
541521
let contents = match generated_kind {
@@ -553,7 +533,7 @@ fn tar(
553533
);
554534
header.set_size(contents.len() as u64);
555535
header.set_cksum();
556-
ar.append(&header, contents.as_bytes())
536+
ar.append_data(&mut header, &ar_path, contents.as_bytes())
557537
.chain_err(|| format!("could not archive source file `{}`", rel_str))?;
558538
}
559539
}

tests/testsuite/package.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1845,3 +1845,47 @@ dependency `bar` does not specify a version.
18451845
)
18461846
.run();
18471847
}
1848+
1849+
#[cargo_test]
1850+
fn long_file_names() {
1851+
// Filenames over 100 characters require a GNU extension tarfile.
1852+
// See #8453.
1853+
1854+
registry::init();
1855+
let long_name = concat!(
1856+
"012345678901234567890123456789012345678901234567890123456789",
1857+
"012345678901234567890123456789012345678901234567890123456789",
1858+
"012345678901234567890123456789012345678901234567890123456789"
1859+
);
1860+
let p = project()
1861+
.file(
1862+
"Cargo.toml",
1863+
r#"
1864+
[package]
1865+
name = "foo"
1866+
version = "0.1.0"
1867+
license = "MIT"
1868+
description = "foo"
1869+
homepage = "foo"
1870+
1871+
[dependencies]
1872+
"#,
1873+
)
1874+
.file(long_name, "something")
1875+
.file("src/main.rs", "fn main() {}")
1876+
.build();
1877+
1878+
p.cargo("package").run();
1879+
p.cargo("package --list")
1880+
.with_stdout(&format!(
1881+
"\
1882+
{}
1883+
Cargo.lock
1884+
Cargo.toml
1885+
Cargo.toml.orig
1886+
src/main.rs
1887+
",
1888+
long_name
1889+
))
1890+
.run();
1891+
}

0 commit comments

Comments
 (0)