Skip to content

Commit

Permalink
Auto merge of #11447 - arlosi:exact, r=weihanglo
Browse files Browse the repository at this point in the history
Crate checksum lookup query should match on semver build metadata

Since crates.io allows crate versions to differ only by build metadata, a query using `OptVersionReq::exact` + `next()` can return nondeterministic results.

This change fixes the issue by adding an additional `filter` that ensures the version is equal (including build metadata).

It still feels somewhat wrong that a query using `exact` can match multiple crates, so an alternative fix would be to add a new variant of `OptVersionReq` that also matched on build metadata.

Fixes #11412
  • Loading branch information
bors committed Aug 15, 2023
2 parents 7c3904d + fb98f3f commit a11f624
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 5 deletions.
12 changes: 7 additions & 5 deletions src/cargo/sources/registry/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,9 @@ impl<'cfg> RegistryIndex<'cfg> {
pub fn hash(&mut self, pkg: PackageId, load: &mut dyn RegistryData) -> Poll<CargoResult<&str>> {
let req = OptVersionReq::exact(pkg.version());
let summary = self.summaries(&pkg.name(), &req, load)?;
let summary = ready!(summary).next();
let summary = ready!(summary)
.filter(|s| s.summary.version() == pkg.version())
.next();
Poll::Ready(Ok(summary
.ok_or_else(|| internal(format!("no hash listed for {}", pkg)))?
.summary
Expand Down Expand Up @@ -623,10 +625,10 @@ impl<'cfg> RegistryIndex<'cfg> {
load: &mut dyn RegistryData,
) -> Poll<CargoResult<bool>> {
let req = OptVersionReq::exact(pkg.version());
let found = self
.summaries(&pkg.name(), &req, load)
.map_ok(|mut p| p.any(|summary| summary.yanked));
found
let found = ready!(self.summaries(&pkg.name(), &req, load))?
.filter(|s| s.summary.version() == pkg.version())
.any(|summary| summary.yanked);
Poll::Ready(Ok(found))
}
}

Expand Down
1 change: 1 addition & 0 deletions src/cargo/sources/registry/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,7 @@ impl<'cfg> RegistrySource<'cfg> {
.summaries(&package.name(), &req, &mut *self.ops)?
.expect("a downloaded dep now pending!?")
.map(|s| s.summary.clone())
.filter(|s| s.version() == package.version())
.next()
.expect("summary not found");
if let Some(cksum) = summary_with_cksum.checksum() {
Expand Down
35 changes: 35 additions & 0 deletions tests/testsuite/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3529,3 +3529,38 @@ fn unpack_again_when_cargo_ok_is_unrecognized() {
let ok = fs::read_to_string(&cargo_ok).unwrap();
assert_eq!(&ok, r#"{"v":1}"#);
}

#[cargo_test]
fn differ_only_by_metadata() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.1"
authors = []
[dependencies]
baz = "=0.0.1"
"#,
)
.file("src/main.rs", "fn main() {}")
.build();

Package::new("baz", "0.0.1+b").publish();
Package::new("baz", "0.0.1+c").yanked(true).publish();

p.cargo("check")
.with_stderr(
"\
[UPDATING] `dummy-registry` index
[DOWNLOADING] crates ...
[DOWNLOADED] [..] v0.0.1+b (registry `dummy-registry`)
[CHECKING] baz v0.0.1+b
[CHECKING] foo v0.0.1 ([CWD])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s
",
)
.run();
}

0 comments on commit a11f624

Please sign in to comment.