Skip to content

Commit c05ef02

Browse files
committed
krate/publish: prevent publication of crates with [patch] sections
Fixes #11188.
1 parent e38e064 commit c05ef02

File tree

2 files changed

+39
-0
lines changed

2 files changed

+39
-0
lines changed

src/controllers/krate/publish.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,13 @@ pub async fn publish(app: AppState, req: Parts, body: Body) -> AppResult<Json<Go
342342
validate_dependency(dep)?;
343343
}
344344

345+
// We don't want to allow [patch] sections in manifests at all.
346+
if matches!(&tarball_info.manifest.patch, Some(patch) if !patch.is_empty()) {
347+
return Err(bad_request(
348+
"crates.io does not allow crates to be published with `[patch]` sections in their manifests.",
349+
));
350+
}
351+
345352
let api_token_id = auth.api_token_id();
346353
let user = auth.user();
347354

src/tests/krate/publish/dependencies.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,38 @@ async fn new_krate_with_wildcard_dependency() {
285285
assert_that!(app.stored_files().await, empty());
286286
}
287287

288+
#[tokio::test(flavor = "multi_thread")]
289+
async fn new_krate_with_patch() {
290+
let (app, _, user, token) = TestApp::full().with_token().await;
291+
let mut conn = app.db_conn().await;
292+
293+
// Insert a crate directly into the database so that new_wild can depend on it
294+
CrateBuilder::new("foo_patch", user.as_model().id)
295+
.expect_build(&mut conn)
296+
.await;
297+
298+
let manifest = r#"
299+
[package]
300+
name = "new_patch"
301+
version = "1.0.0"
302+
description = "foo?!"
303+
license = "MIT"
304+
305+
[dependencies]
306+
foo_patch = "1.0.0"
307+
308+
[patch.crates-io]
309+
foo_patch = { git = "https://github.com/foo/patch.git" }
310+
"#;
311+
312+
let crate_to_publish = PublishBuilder::new("new_patch", "1.0.0").custom_manifest(manifest);
313+
314+
let response = token.publish_crate(crate_to_publish).await;
315+
assert_eq!(response.status(), StatusCode::BAD_REQUEST);
316+
assert_snapshot!(response.text(), @r###"{"errors":[{"detail":"crates.io does not allow crates to be published with `[patch]` sections in their manifests."}]}"###);
317+
assert_that!(app.stored_files().await, empty());
318+
}
319+
288320
#[tokio::test(flavor = "multi_thread")]
289321
async fn new_krate_dependency_missing() {
290322
let (app, _, _, token) = TestApp::full().with_token().await;

0 commit comments

Comments
 (0)