Skip to content

Commit 4eedb3a

Browse files
Merge #1550
1550: Ensure only exact name matches are added to the index r=sgrif a=jtgeibel On the client side cargo checks dependency names against the index and requires an exact match. For instance, a user cannot depend on `diesel-migrations` or `Diesel_migrations` as cargo generates an error directing them to use the correct name `diesel_migrations`. This check for an exact name match is now repeated on the server when a crate is published. This ensures that bugs in cargo or third-party tooling cannot result in a dependency name that cargo is unable to locate in the index. Co-authored-by: Justin Geibel <[email protected]>
2 parents 005b010 + 86dffda commit 4eedb3a

File tree

3 files changed

+24
-1
lines changed

3 files changed

+24
-1
lines changed

src/models/dependency.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@ pub fn add_dependencies(
8181
let git_and_new_dependencies = deps
8282
.iter()
8383
.map(|dep| {
84-
let krate = Crate::by_name(&dep.name)
84+
// Match only identical names to ensure the index always references the original crate name
85+
let krate = Crate::by_exact_name(&dep.name)
8586
.first::<Crate>(&*conn)
8687
.map_err(|_| human(&format_args!("no known crate named `{}`", &*dep.name)))?;
8788
if dep.version_req == semver::VersionReq::parse("*").unwrap() {

src/models/krate.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ type CanonCrateName<T> = self::canon_crate_name::HelperType<T>;
9191
type All = diesel::dsl::Select<crates::table, AllColumns>;
9292
type WithName<'a> = diesel::dsl::Eq<CanonCrateName<crates::name>, CanonCrateName<&'a str>>;
9393
type ByName<'a> = diesel::dsl::Filter<All, WithName<'a>>;
94+
type ByExactName<'a> = diesel::dsl::Filter<All, diesel::dsl::Eq<crates::name, &'a str>>;
9495

9596
#[derive(Insertable, AsChangeset, Default, Debug)]
9697
#[table_name = "crates"]
@@ -244,6 +245,10 @@ impl Crate {
244245
Crate::all().filter(Self::with_name(name))
245246
}
246247

248+
pub fn by_exact_name(name: &str) -> ByExactName<'_> {
249+
Crate::all().filter(crates::name.eq(name))
250+
}
251+
247252
pub fn all() -> All {
248253
crates::table.select(ALL_COLUMNS)
249254
}

src/tests/krate.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,23 @@ fn new_krate_with_dependency() {
650650
token.publish(crate_to_publish).good();
651651
}
652652

653+
#[test]
654+
fn reject_new_krate_with_non_exact_dependency() {
655+
let (app, _, user, token) = TestApp::init().with_token();
656+
657+
app.db(|conn| {
658+
CrateBuilder::new("foo-dep", user.as_model().id).expect_build(&conn);
659+
});
660+
661+
// Use non-exact name for the dependency
662+
let dependency = DependencyBuilder::new("foo_dep");
663+
664+
let crate_to_publish = PublishBuilder::new("new_dep")
665+
.version("1.0.0")
666+
.dependency(dependency);
667+
token.publish(crate_to_publish).bad_with_status(200);
668+
}
669+
653670
#[test]
654671
fn new_krate_with_wildcard_dependency() {
655672
let (app, _, user, token) = TestApp::init().with_token();

0 commit comments

Comments
 (0)