Skip to content

Commit a11f624

Browse files
committed
Auto merge of #11447 - arlosi:exact, r=weihanglo
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
2 parents 7c3904d + fb98f3f commit a11f624

File tree

3 files changed

+43
-5
lines changed

3 files changed

+43
-5
lines changed

src/cargo/sources/registry/index.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,9 @@ impl<'cfg> RegistryIndex<'cfg> {
379379
pub fn hash(&mut self, pkg: PackageId, load: &mut dyn RegistryData) -> Poll<CargoResult<&str>> {
380380
let req = OptVersionReq::exact(pkg.version());
381381
let summary = self.summaries(&pkg.name(), &req, load)?;
382-
let summary = ready!(summary).next();
382+
let summary = ready!(summary)
383+
.filter(|s| s.summary.version() == pkg.version())
384+
.next();
383385
Poll::Ready(Ok(summary
384386
.ok_or_else(|| internal(format!("no hash listed for {}", pkg)))?
385387
.summary
@@ -623,10 +625,10 @@ impl<'cfg> RegistryIndex<'cfg> {
623625
load: &mut dyn RegistryData,
624626
) -> Poll<CargoResult<bool>> {
625627
let req = OptVersionReq::exact(pkg.version());
626-
let found = self
627-
.summaries(&pkg.name(), &req, load)
628-
.map_ok(|mut p| p.any(|summary| summary.yanked));
629-
found
628+
let found = ready!(self.summaries(&pkg.name(), &req, load))?
629+
.filter(|s| s.summary.version() == pkg.version())
630+
.any(|summary| summary.yanked);
631+
Poll::Ready(Ok(found))
630632
}
631633
}
632634

src/cargo/sources/registry/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,7 @@ impl<'cfg> RegistrySource<'cfg> {
694694
.summaries(&package.name(), &req, &mut *self.ops)?
695695
.expect("a downloaded dep now pending!?")
696696
.map(|s| s.summary.clone())
697+
.filter(|s| s.version() == package.version())
697698
.next()
698699
.expect("summary not found");
699700
if let Some(cksum) = summary_with_cksum.checksum() {

tests/testsuite/registry.rs

+35
Original file line numberDiff line numberDiff line change
@@ -3529,3 +3529,38 @@ fn unpack_again_when_cargo_ok_is_unrecognized() {
35293529
let ok = fs::read_to_string(&cargo_ok).unwrap();
35303530
assert_eq!(&ok, r#"{"v":1}"#);
35313531
}
3532+
3533+
#[cargo_test]
3534+
fn differ_only_by_metadata() {
3535+
let p = project()
3536+
.file(
3537+
"Cargo.toml",
3538+
r#"
3539+
[package]
3540+
name = "foo"
3541+
version = "0.0.1"
3542+
authors = []
3543+
3544+
[dependencies]
3545+
baz = "=0.0.1"
3546+
"#,
3547+
)
3548+
.file("src/main.rs", "fn main() {}")
3549+
.build();
3550+
3551+
Package::new("baz", "0.0.1+b").publish();
3552+
Package::new("baz", "0.0.1+c").yanked(true).publish();
3553+
3554+
p.cargo("check")
3555+
.with_stderr(
3556+
"\
3557+
[UPDATING] `dummy-registry` index
3558+
[DOWNLOADING] crates ...
3559+
[DOWNLOADED] [..] v0.0.1+b (registry `dummy-registry`)
3560+
[CHECKING] baz v0.0.1+b
3561+
[CHECKING] foo v0.0.1 ([CWD])
3562+
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s
3563+
",
3564+
)
3565+
.run();
3566+
}

0 commit comments

Comments
 (0)