diff --git a/src/cargo/util/config.rs b/src/cargo/util/config.rs index b3075a99a41..4494b9ca307 100644 --- a/src/cargo/util/config.rs +++ b/src/cargo/util/config.rs @@ -29,7 +29,7 @@ use crate::util::errors::{self, internal, CargoResult, CargoResultExt}; use crate::util::toml as cargo_toml; use crate::util::Filesystem; use crate::util::Rustc; -use crate::util::ToUrlWithBase; +use crate::util::{ToUrl, ToUrlWithBase}; use crate::util::{paths, validate_package_name}; /// Configuration information for cargo. This is not specific to a build, it is information @@ -684,7 +684,9 @@ impl Config { } fn resolve_registry_index(&self, index: Value) -> CargoResult { - let base = index.definition.root(&self).join("truncated-by-url-with-base"); + let base = index.definition.root(&self).join("truncated-by-url_with_base"); + // Parse val to check it is a URL, not a relative path without a protocol. + let _parsed = index.val.to_url()?; let url = index.val.to_url_with_base(Some(&*base))?; if url.password().is_some() { failure::bail!("Registry URLs may not contain passwords"); diff --git a/tests/testsuite/alt_registry.rs b/tests/testsuite/alt_registry.rs index d4b1d3bc1a9..0f5491836ef 100644 --- a/tests/testsuite/alt_registry.rs +++ b/tests/testsuite/alt_registry.rs @@ -1167,13 +1167,13 @@ fn unknown_registry() { } #[test] -fn registries_index_relative_path() { +fn registries_index_relative_url() { let config = paths::root().join(".cargo/config"); fs::create_dir_all(config.parent().unwrap()).unwrap(); File::create(&config).unwrap() .write_all(br#" [registries.relative] - index = "alternative-registry" + index = "file:alternative-registry" "#).unwrap(); registry::init(); @@ -1215,13 +1215,13 @@ fn registries_index_relative_path() { } #[test] -fn registry_index_relative_path() { +fn registry_index_relative_url() { let config = paths::root().join(".cargo/config"); fs::create_dir_all(config.parent().unwrap()).unwrap(); File::create(&config).unwrap() .write_all(br#" [registry] - index = "alternative-registry" + index = "file:alternative-registry" "#).unwrap(); registry::init(); @@ -1263,3 +1263,49 @@ warning: custom registry support via the `registry.index` configuration is being )) .run(); } + +#[test] +fn registries_index_relative_path_not_allowed() { + let config = paths::root().join(".cargo/config"); + fs::create_dir_all(config.parent().unwrap()).unwrap(); + File::create(&config).unwrap() + .write_all(br#" + [registries.relative] + index = "alternative-registry" + "#).unwrap(); + + registry::init(); + + let p = project() + .file( + "Cargo.toml", + r#" + [project] + name = "foo" + version = "0.0.1" + authors = [] + + [dependencies.bar] + version = "0.0.1" + registry = "relative" + "#, + ) + .file("src/main.rs", "fn main() {}") + .build(); + + Package::new("bar", "0.0.1") + .alternative(true) + .publish(); + + p.cargo("build") + .with_stderr(&format!( + "\ +error: failed to parse manifest at `{root}/foo/Cargo.toml` + +Caused by: + invalid url `alternative-registry`: relative URL without a base +" + , root = paths::root().to_str().unwrap())) + .with_status(101) + .run(); +}