Repository: rust-lang/cargo (rust)

Issue:
Next `tar-rs` update creates sparse entries by default
Recently, the `tar` crate got support for creating archives with sparse entries (https://github.com/alexcrichton/tar-rs/pull/375). It is going to be enabled by default in the next release.

For Cargo (which depends on this crate), keeping the default would mean that some very old versions of Cargo would not be able to read some archives created by the latest Cargo. Specifically, the ability to read sparse entries was added in `tar` `0.4.6` (released 2016-06-09). The corresponding `tar-rs` bump for Cargo was #2973, which is included in Cargo `0.13` which is included in rust `1.12`.

The sparseness check does not affect Rust source files (as text files generally do not contain large chunks of null bytes), but it may affect crates containing binary files. For example, [`protobuf-build`](https://docs.rs/crate/protobuf-build/0.14.0/source/bin/protoc-linux-ppcle_64) and [`metal`](https://docs.rs/crate/metal/0.29.0/source/examples/mps/shaders.metallib) crates contain binaries that could possibly be sparse. The command `rg -ca '\x00{4096}' ~/.cargo/registry/` might reveal other similar binaries.

I'm creating this issue at the [request](https://github.com/alexcrichton/tar-rs/pull/375#issuecomment-2364276823) of @alexcrichton to let the Cargo team decide whether to
- keep the new default as-is, or
- add a few `ar.sparse(false)` calls explicitly everywhere `tar::Builder` is used.

Pull request description:
chore(deps): update tar to 0.4.42
The new version of tar enables the creation of sparse tar archives by default.  The ability to read such sparse entries was added in tar 0.4.6, which has been in use starting from Cargo 0.13 and Rust 1.12. Additionally, `docker cp` doesn't support sparse tar entries in the GNU format.  For compatibility with older versions of Rust and Cargo, as well as with `docker cp`, this commit disables sparse archive creation everywhere the `tar::Builder` is used.

Closes #14594. CC: @weihanglo, @alexcrichton.

<!-- homu-ignore:start -->
<!--
Thanks for submitting a pull request 🎉! Here are some tips for you:

* If this is your first contribution, read "Cargo Contribution Guide" first:
  https://doc.crates.io/contrib/
* Run `cargo fmt --all` to format your code changes.
* Small commits and pull requests are always preferable and easy to review.
* If your idea is large and needs feedback from the community, read how:
  https://doc.crates.io/contrib/process/#working-on-large-features
* Cargo takes care of compatibility. Read our design principles:
  https://doc.crates.io/contrib/design.html
* When changing help text of cargo commands, follow the steps to generate docs:
  https://github.com/rust-lang/cargo/tree/master/src/doc#building-the-man-pages
* If your PR is not finished, set it as "draft" PR or add "WIP" in its title.
* It's ok to use the CI resources to test your PR, but please don't abuse them.

### What does this PR try to resolve?

Explain the motivation behind this change.
A clear overview along with an in-depth explanation are helpful.

You can use `Fixes #<issue number>` to associate this PR to an existing issue.

### How should we test and review this PR?

Demonstrate how you test this change and guide reviewers through your PR.
With a smooth review process, a pull request usually gets reviewed quicker.

If you don't know how to write and run your tests, please read the guide:
https://doc.crates.io/contrib/tests

### Additional information

Other information you want to mention in this PR, such as prior arts,
future extensions, an unresolved problem, or a TODO list.
-->
<!-- homu-ignore:end -->


Patch:
diff --git a/Cargo.lock b/Cargo.lock
index 06c2c5a04..aa88e03af 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3371,9 +3371,9 @@ dependencies = [
 
 [[package]]
 name = "tar"
-version = "0.4.41"
+version = "0.4.42"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cb797dad5fb5b76fcf519e702f4a589483b5ef06567f160c392832c1f5e44909"
+checksum = "4ff6c40d3aedb5e06b57c6f669ad17ab063dd1e63d977c6a88e7f4dfa4f04020"
 dependencies = [
  "filetime",
  "libc",
diff --git a/Cargo.toml b/Cargo.toml
index 9682e216d..c62dc28df 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -94,7 +94,7 @@ shell-escape = "0.1.5"
 similar = "2.6.0"
 supports-hyperlinks = "3.0.0"
 snapbox = { version = "0.6.17", features = ["diff", "dir", "term-svg", "regex", "json"] }
-tar = { version = "0.4.41", default-features = false }
+tar = { version = "0.4.42", default-features = false }
 tempfile = "3.10.1"
 thiserror = "1.0.63"
 time = { version = "0.3.36", features = ["parsing", "formatting", "serde"] }
diff --git a/src/cargo/ops/cargo_package.rs b/src/cargo/ops/cargo_package.rs
index 047085840..239e5af2a 100644
--- a/src/cargo/ops/cargo_package.rs
+++ b/src/cargo/ops/cargo_package.rs
@@ -903,6 +903,7 @@ fn tar(
 
     // Put all package files into a compressed archive.
     let mut ar = Builder::new(encoder);
+    ar.sparse(false);
     let gctx = ws.gctx();
 
     let base_name = format!("{}-{}", pkg.name(), pkg.version());
diff --git a/src/doc/contrib/src/team.md b/src/doc/contrib/src/team.md
index 74576f3ee..e8044e6d9 100644
--- a/src/doc/contrib/src/team.md
+++ b/src/doc/contrib/src/team.md
@@ -135,7 +135,6 @@ The degree of process is correlated with the degree of change being proposed:
     These decisions are usually processed via private channels by the entirety of the team.
   - A change that is a "one-way door".
     That is, something that is difficult to reverse without breaking backwards compatibility.
-  - New or transferred "Intentional Artifact" crates to the team, see also [Rust crate ownership policy](https://forge.rust-lang.org/policies/crate-ownership.html)
 
 - Larger features should usually go through the [RFC process].
   This usually involves first soliciting feedback from the Cargo team and the rest of the community, often via the [Rust Internals] discussion board, [Cargo's issue tracker], and the [Zulip] channel.


Test patch:
diff --git a/crates/cargo-test-support/src/containers.rs b/crates/cargo-test-support/src/containers.rs
index 22fd5fd85..4ce6e1d50 100644
--- a/crates/cargo-test-support/src/containers.rs
+++ b/crates/cargo-test-support/src/containers.rs
@@ -122,6 +122,7 @@ impl Container {
             return;
         }
         let mut ar = tar::Builder::new(Vec::new());
+        ar.sparse(false);
         let files = std::mem::replace(&mut self.files, Vec::new());
         for mut file in files {
             ar.append_data(&mut file.header, &file.path, file.contents.as_slice())
diff --git a/crates/cargo-test-support/src/registry.rs b/crates/cargo-test-support/src/registry.rs
index 5af522a38..9e0bc9e3e 100644
--- a/crates/cargo-test-support/src/registry.rs
+++ b/crates/cargo-test-support/src/registry.rs
@@ -1513,6 +1513,7 @@ impl Package {
         t!(fs::create_dir_all(dst.parent().unwrap()));
         let f = t!(File::create(&dst));
         let mut a = Builder::new(GzEncoder::new(f, Compression::none()));
+        a.sparse(false);
 
         if !self
             .files