Skip to content

Commit f47425f

Browse files
committed
Do not allow create name starts with _
Signed-off-by: hi-rustin <rustin.liu@gmail.com>
1 parent b23fe07 commit f47425f

File tree

3 files changed

+54
-14
lines changed

3 files changed

+54
-14
lines changed

src/models/krate.rs

+52-12
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,47 @@ impl Crate {
199199
name, MAX_NAME_LENGTH
200200
)));
201201
}
202-
Crate::valid_ident(name, "crate name")
202+
Crate::valid_create_ident(name)
203+
}
204+
205+
// Checks that the name is a valid crate name.
206+
// 1. The name must be non-empty.
207+
// 2. The first character must be an ASCII character.
208+
// 3. The remaining characters must be ASCII alphanumerics or `-` or `_`.
209+
// Note: This differs from `valid_dependency_name`, which allows `_` as the first character.
210+
fn valid_create_ident(name: &str) -> AppResult<()> {
211+
if name.is_empty() {
212+
return Err(cargo_err("the crate name cannot be an empty"));
213+
}
214+
let mut chars = name.chars();
215+
if let Some(ch) = chars.next() {
216+
if ch.is_ascii_digit() {
217+
return Err(cargo_err(&format!(
218+
"the name `{}` cannot be used as a crate name, \
219+
the name cannot start with a digit",
220+
name,
221+
)));
222+
}
223+
if !ch.is_ascii_alphabetic() {
224+
return Err(cargo_err(&format!(
225+
"invalid character `{}` in crate name: `{}`, \
226+
the first character must be an ASCII character",
227+
ch, name
228+
)));
229+
}
230+
}
231+
232+
for ch in chars {
233+
if !(ch.is_ascii_alphanumeric() || ch == '-' || ch == '_') {
234+
return Err(cargo_err(&format!(
235+
"invalid character `{}` in crate name: `{}`, \
236+
characters must be an ASCII alphanumeric characters, `-`, or `_`",
237+
ch, name
238+
)));
239+
}
240+
}
241+
242+
Ok(())
203243
}
204244

205245
pub fn valid_dependency_name(name: &str) -> AppResult<()> {
@@ -209,41 +249,41 @@ impl Crate {
209249
name, MAX_NAME_LENGTH
210250
)));
211251
}
212-
Crate::valid_ident(name, "dependency name")
252+
Crate::valid_dependency_ident(name)
213253
}
214254

215-
// Checks that the name is a valid identifier.
255+
// Checks that the name is a valid dependency name.
216256
// 1. The name must be non-empty.
217257
// 2. The first character must be an ASCII character or `_`.
218258
// 3. The remaining characters must be ASCII alphanumerics or `-` or `_`.
219-
fn valid_ident(name: &str, what: &str) -> AppResult<()> {
259+
fn valid_dependency_ident(name: &str) -> AppResult<()> {
220260
if name.is_empty() {
221-
return Err(cargo_err(&format!("the {} cannot be an empty", what)));
261+
return Err(cargo_err("the dependency name cannot be an empty"));
222262
}
223263
let mut chars = name.chars();
224264
if let Some(ch) = chars.next() {
225265
if ch.is_ascii_digit() {
226266
return Err(cargo_err(&format!(
227-
"the name `{}` cannot be used as a {}, \
267+
"the name `{}` cannot be used as a dependency name, \
228268
the name cannot start with a digit",
229-
name, what,
269+
name,
230270
)));
231271
}
232272
if !(ch.is_ascii_alphabetic() || ch == '_') {
233273
return Err(cargo_err(&format!(
234-
"invalid character `{}` in {}: `{}`, \
274+
"invalid character `{}` in dependency name: `{}`, \
235275
the first character must be an ASCII character, or `_`",
236-
ch, what, name
276+
ch, name
237277
)));
238278
}
239279
}
240280

241281
for ch in chars {
242282
if !(ch.is_ascii_alphanumeric() || ch == '-' || ch == '_') {
243283
return Err(cargo_err(&format!(
244-
"invalid character `{}` in {}: `{}`, \
284+
"invalid character `{}` in dependency name: `{}`, \
245285
characters must be an ASCII alphanumeric characters, `-`, or `_`",
246-
ch, what, name
286+
ch, name
247287
)));
248288
}
249289
}
@@ -549,7 +589,7 @@ mod tests {
549589
assert!(Crate::valid_name("foo_underscore").is_ok());
550590
assert!(Crate::valid_name("foo-dash").is_ok());
551591
assert!(Crate::valid_name("foo+plus").is_err());
552-
assert!(Crate::valid_name("_foo").is_ok());
592+
assert!(Crate::valid_name("_foo").is_err());
553593
assert!(Crate::valid_name("-foo").is_err());
554594
}
555595

src/tests/krate/publish/snapshots/all__krate__publish__dependencies__invalid_dependency_name.snap

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ expression: response.into_json()
55
{
66
"errors": [
77
{
8-
"detail": "invalid character `🦀` in crate name: `🦀`, the first character must be an ASCII character, or `_`"
8+
"detail": "invalid character `🦀` in crate name: `🦀`, the first character must be an ASCII character"
99
}
1010
]
1111
}

src/tests/krate/publish/snapshots/all__krate__publish__validation__invalid_names-5.snap

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ expression: response.into_json()
55
{
66
"errors": [
77
{
8-
"detail": "invalid character `á` in crate name: `áccênts`, the first character must be an ASCII character, or `_`"
8+
"detail": "invalid character `á` in crate name: `áccênts`, the first character must be an ASCII character"
99
}
1010
]
1111
}

0 commit comments

Comments
 (0)