Skip to content

Commit 9ec474c

Browse files
authored
Merge pull request #718 from integer32llc/limit-names
Limit crate names to 64 characters
2 parents 73b3491 + de37d5b commit 9ec474c

File tree

3 files changed

+18
-6
lines changed

3 files changed

+18
-6
lines changed

src/krate.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ pub const ALL_COLUMNS: AllColumns = (crates::id, crates::name,
6767
crates::readme, crates::license, crates::repository,
6868
crates::max_upload_size);
6969

70+
pub const MAX_NAME_LENGTH: usize = 64;
71+
7072
type CrateQuery<'a> = crates::BoxedQuery<'a, Pg, <AllColumns as Expression>::SqlType>;
7173

7274
#[derive(RustcEncodable, RustcDecodable)]
@@ -370,6 +372,13 @@ impl Crate {
370372
}
371373

372374
pub fn valid_name(name: &str) -> bool {
375+
let under_max_length = name.chars()
376+
.take(MAX_NAME_LENGTH + 1)
377+
.count() <= MAX_NAME_LENGTH;
378+
Crate::valid_ident(name) && under_max_length
379+
}
380+
381+
fn valid_ident(name: &str) -> bool {
373382
if name.is_empty() { return false }
374383
name.chars().next().unwrap().is_alphabetic() &&
375384
name.chars().all(|c| c.is_alphanumeric() || c == '_' || c == '-') &&
@@ -379,12 +388,12 @@ impl Crate {
379388
pub fn valid_feature_name(name: &str) -> bool {
380389
let mut parts = name.split('/');
381390
match parts.next() {
382-
Some(part) if !Crate::valid_name(part) => return false,
391+
Some(part) if !Crate::valid_ident(part) => return false,
383392
None => return false,
384393
_ => {}
385394
}
386395
match parts.next() {
387-
Some(part) if !Crate::valid_name(part) => return false,
396+
Some(part) if !Crate::valid_ident(part) => return false,
388397
_ => {}
389398
}
390399
parts.next().is_none()

src/tests/krate.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use cargo_registry::dependency::EncodableDependency;
1414
use cargo_registry::download::EncodableVersionDownload;
1515
use cargo_registry::git;
1616
use cargo_registry::keyword::{Keyword, EncodableKeyword};
17-
use cargo_registry::krate::{Crate, EncodableCrate};
17+
use cargo_registry::krate::{Crate, EncodableCrate, MAX_NAME_LENGTH};
1818
use cargo_registry::upload as u;
1919
use cargo_registry::user::EncodableUser;
2020
use cargo_registry::version::EncodableVersion;
@@ -397,14 +397,14 @@ fn new_bad_names() {
397397
let (_b, app, middle) = ::app();
398398
let mut req = ::new_req(app, name, "1.0.0");
399399
::mock_user(&mut req, ::user("foo"));
400-
::logout(&mut req);
401400
let json = bad_resp!(middle.call(&mut req));
402401
assert!(json.errors[0].detail.contains("invalid crate name"),
403402
"{:?}", json.errors);
404403
}
405404

406405
bad_name("");
407406
bad_name("foo bar");
407+
bad_name(&"a".repeat(MAX_NAME_LENGTH + 1));
408408
}
409409

410410
#[test]

src/upload.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use semver;
66
use dependency::Kind as DependencyKind;
77

88
use keyword::Keyword as CrateKeyword;
9-
use krate::Crate;
9+
use krate::{Crate, MAX_NAME_LENGTH};
1010

1111
#[derive(RustcDecodable, RustcEncodable)]
1212
pub struct NewCrate {
@@ -52,7 +52,10 @@ impl Decodable for CrateName {
5252
fn decode<D: Decoder>(d: &mut D) -> Result<CrateName, D::Error> {
5353
let s = d.read_str()?;
5454
if !Crate::valid_name(&s) {
55-
return Err(d.error(&format!("invalid crate name specified: {}", s)))
55+
return Err(d.error(&format!("invalid crate name specified: {}. \
56+
Valid crate names must start with a letter; contain only \
57+
letters, numbers, hyphens, or underscores; and have {} or \
58+
fewer characters.", s, MAX_NAME_LENGTH)))
5659
}
5760
Ok(CrateName(s))
5861
}

0 commit comments

Comments
 (0)