Restrict registry names to same style as package names.

This commit is contained in:
Eric Huss 2018-12-19 20:33:57 -08:00
parent 0d1f1bbeab
commit 080f0b34c4
8 changed files with 84 additions and 45 deletions

View File

@ -7,7 +7,7 @@ use url::Url;
use crate::core::PackageId; use crate::core::PackageId;
use crate::util::errors::{CargoResult, CargoResultExt}; use crate::util::errors::{CargoResult, CargoResultExt};
use crate::util::{ToSemver, ToUrl}; use crate::util::{validate_package_name, ToSemver, ToUrl};
/// Some or all of the data required to identify a package: /// Some or all of the data required to identify a package:
/// ///
@ -64,11 +64,7 @@ impl PackageIdSpec {
Some(version) => Some(Version::parse(version)?), Some(version) => Some(Version::parse(version)?),
None => None, None => None,
}; };
for ch in name.chars() { validate_package_name(name, "pkgid", "")?;
if !ch.is_alphanumeric() && ch != '_' && ch != '-' {
failure::bail!("invalid character in pkgid `{}`: `{}`", spec, ch)
}
}
Ok(PackageIdSpec { Ok(PackageIdSpec {
name: name.to_string(), name: name.to_string(),
version, version,

View File

@ -10,7 +10,7 @@ use git2::Repository as GitRepository;
use crate::core::{compiler, Workspace}; use crate::core::{compiler, Workspace};
use crate::util::errors::{CargoResult, CargoResultExt}; use crate::util::errors::{CargoResult, CargoResultExt};
use crate::util::{existing_vcs_repo, internal, FossilRepo, GitRepo, HgRepo, PijulRepo}; use crate::util::{existing_vcs_repo, internal, FossilRepo, GitRepo, HgRepo, PijulRepo};
use crate::util::{paths, Config}; use crate::util::{paths, validate_package_name, Config};
use toml; use toml;
@ -161,20 +161,7 @@ fn check_name(name: &str, opts: &NewOptions) -> CargoResult<()> {
} }
} }
for c in name.chars() { validate_package_name(name, "crate name", name_help)?;
if c.is_alphanumeric() {
continue;
}
if c == '_' || c == '-' {
continue;
}
failure::bail!(
"Invalid character `{}` in crate name: `{}`{}",
c,
name,
name_help
)
}
Ok(()) Ok(())
} }

View File

@ -19,8 +19,8 @@ use crate::sources::{RegistrySource, SourceConfigMap};
use crate::util::config::{self, Config}; use crate::util::config::{self, Config};
use crate::util::errors::{CargoResult, CargoResultExt}; use crate::util::errors::{CargoResult, CargoResultExt};
use crate::util::important_paths::find_root_manifest_for_wd; use crate::util::important_paths::find_root_manifest_for_wd;
use crate::util::paths;
use crate::util::ToUrl; use crate::util::ToUrl;
use crate::util::{paths, validate_package_name};
use crate::version; use crate::version;
pub struct RegistryConfig { pub struct RegistryConfig {
@ -294,12 +294,15 @@ pub fn registry_configuration(
registry: Option<String>, registry: Option<String>,
) -> CargoResult<RegistryConfig> { ) -> CargoResult<RegistryConfig> {
let (index, token) = match registry { let (index, token) = match registry {
Some(registry) => ( Some(registry) => {
validate_package_name(&registry, "registry name", "")?;
(
Some(config.get_registry_index(&registry)?.to_string()), Some(config.get_registry_index(&registry)?.to_string()),
config config
.get_string(&format!("registries.{}.token", registry))? .get_string(&format!("registries.{}.token", registry))?
.map(|p| p.val), .map(|p| p.val),
), )
}
None => { None => {
// Checking out for default index and token // Checking out for default index and token
( (

View File

@ -6,7 +6,7 @@ use crate::core::Workspace;
use crate::ops::{CompileFilter, CompileOptions, NewOptions, Packages, VersionControl}; use crate::ops::{CompileFilter, CompileOptions, NewOptions, Packages, VersionControl};
use crate::sources::CRATES_IO_REGISTRY; use crate::sources::CRATES_IO_REGISTRY;
use crate::util::important_paths::find_root_manifest_for_wd; use crate::util::important_paths::find_root_manifest_for_wd;
use crate::util::paths; use crate::util::{paths, validate_package_name};
use crate::CargoResult; use crate::CargoResult;
use clap::{self, SubCommand}; use clap::{self, SubCommand};
@ -370,11 +370,12 @@ pub trait ArgMatchesExt {
requires -Zunstable-options to use." requires -Zunstable-options to use."
)); ));
} }
validate_package_name(registry, "registry name", "")?;
if registry == CRATES_IO_REGISTRY { if registry == CRATES_IO_REGISTRY {
// If "crates.io" is specified then we just need to return None // If "crates.io" is specified then we just need to return None
// as that will cause cargo to use crates.io. This is required // as that will cause cargo to use crates.io. This is required
// for the case where a default alterative registry is used // for the case where a default alternative registry is used
// but the user wants to switch back to crates.io for a single // but the user wants to switch back to crates.io for a single
// command. // command.
Ok(None) Ok(None)

View File

@ -24,11 +24,11 @@ use crate::core::shell::Verbosity;
use crate::core::{CliUnstable, Shell, SourceId, Workspace}; use crate::core::{CliUnstable, Shell, SourceId, Workspace};
use crate::ops; use crate::ops;
use crate::util::errors::{internal, CargoResult, CargoResultExt}; use crate::util::errors::{internal, CargoResult, CargoResultExt};
use crate::util::paths;
use crate::util::toml as cargo_toml; use crate::util::toml as cargo_toml;
use crate::util::Filesystem; use crate::util::Filesystem;
use crate::util::Rustc; use crate::util::Rustc;
use crate::util::ToUrl; use crate::util::ToUrl;
use crate::util::{paths, validate_package_name};
use url::Url; use url::Url;
use self::ConfigValue as CV; use self::ConfigValue as CV;
@ -656,6 +656,7 @@ impl Config {
/// Gets the index for a registry. /// Gets the index for a registry.
pub fn get_registry_index(&self, registry: &str) -> CargoResult<Url> { pub fn get_registry_index(&self, registry: &str) -> CargoResult<Url> {
validate_package_name(registry, "registry name", "")?;
Ok( Ok(
match self.get_string(&format!("registries.{}.index", registry))? { match self.get_string(&format!("registries.{}.index", registry))? {
Some(index) => { Some(index) => {

View File

@ -59,3 +59,19 @@ pub fn elapsed(duration: Duration) -> String {
format!("{}.{:02}s", secs, duration.subsec_nanos() / 10_000_000) format!("{}.{:02}s", secs, duration.subsec_nanos() / 10_000_000)
} }
} }
/// Check the base requirements for a package name.
///
/// This can be used for other things than package names, to enforce some
/// level of sanity. Note that package names have other restrictions
/// elsewhere. `cargo new` has a few restrictions, such as checking for
/// reserved names. crates.io has even more restrictions.
pub fn validate_package_name(name: &str, what: &str, help: &str) -> CargoResult<()> {
if let Some(ch) = name
.chars()
.find(|ch| !ch.is_alphanumeric() && *ch != '_' && *ch != '-')
{
failure::bail!("Invalid character `{}` in {}: `{}`{}", ch, what, name, help);
}
Ok(())
}

View File

@ -21,7 +21,7 @@ use crate::core::{GitReference, PackageIdSpec, SourceId, WorkspaceConfig, Worksp
use crate::sources::{CRATES_IO_INDEX, CRATES_IO_REGISTRY}; use crate::sources::{CRATES_IO_INDEX, CRATES_IO_REGISTRY};
use crate::util::errors::{CargoResult, CargoResultExt, ManifestError}; use crate::util::errors::{CargoResult, CargoResultExt, ManifestError};
use crate::util::paths; use crate::util::paths;
use crate::util::{self, Config, ToUrl}; use crate::util::{self, validate_package_name, Config, ToUrl};
mod targets; mod targets;
use self::targets::targets; use self::targets::targets;
@ -809,19 +809,7 @@ impl TomlManifest {
failure::bail!("package name cannot be an empty string") failure::bail!("package name cannot be an empty string")
} }
for c in package_name.chars() { validate_package_name(package_name, "package name", "")?;
if c.is_alphanumeric() {
continue;
}
if c == '_' || c == '-' {
continue;
}
failure::bail!(
"Invalid character `{}` in package name: `{}`",
c,
package_name
)
}
let pkgid = project.to_package_id(source_id)?; let pkgid = project.to_package_id(source_id)?;

View File

@ -558,3 +558,50 @@ fn patch_alt_reg() {
) )
.run(); .run();
} }
#[test]
fn bad_registry_name() {
let p = project()
.file(
"Cargo.toml",
r#"
cargo-features = ["alternative-registries"]
[project]
name = "foo"
version = "0.0.1"
authors = []
[dependencies.bar]
version = "0.0.1"
registry = "bad name"
"#,
)
.file("src/main.rs", "fn main() {}")
.build();
p.cargo("build")
.masquerade_as_nightly_cargo()
.with_status(101)
.with_stderr(
"\
[ERROR] failed to parse manifest at `[CWD]/Cargo.toml`
Caused by:
Invalid character ` ` in registry name: `bad name`",
)
.run();
for cmd in &[
"init", "install", "login", "owner", "publish", "search", "yank",
] {
p.cargo(cmd)
.arg("-Zunstable-options")
.arg("--registry")
.arg("bad name")
.masquerade_as_nightly_cargo()
.with_status(101)
.with_stderr("[ERROR] Invalid character ` ` in registry name: `bad name`")
.run();
}
}