严格校验自动项目名称
自动命名仅接受二至十六个汉字。 补充格式、路径、凭据和长度边界回归测试。
This commit is contained in:
@@ -26,40 +26,25 @@ pub(crate) struct AutomaticProjectNameAttachment {
|
||||
pub(crate) media_type: Option<String>,
|
||||
}
|
||||
|
||||
fn is_chinese_project_name_character(value: char) -> bool {
|
||||
matches!(
|
||||
value,
|
||||
'\u{3400}'..='\u{4DBF}'
|
||||
| '\u{4E00}'..='\u{9FFF}'
|
||||
| '\u{F900}'..='\u{FAFF}'
|
||||
| '\u{20000}'..='\u{2FA1F}'
|
||||
| '\u{30000}'..='\u{323AF}'
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn normalize_suggested_project_name(value: &str) -> Option<String> {
|
||||
let value = value.trim();
|
||||
let mut lines = value.lines();
|
||||
let first_line = lines.next()?.trim();
|
||||
if first_line.is_empty() || lines.next().is_some() {
|
||||
let character_count = value.chars().count();
|
||||
if !(2..=16).contains(&character_count) || !value.chars().all(is_chinese_project_name_character)
|
||||
{
|
||||
return None;
|
||||
}
|
||||
let first_line = first_line
|
||||
.strip_prefix("项目名称:")
|
||||
.or_else(|| first_line.strip_prefix("项目名称:"))
|
||||
.or_else(|| first_line.strip_prefix("项目名:"))
|
||||
.or_else(|| first_line.strip_prefix("项目名:"))
|
||||
.unwrap_or(first_line)
|
||||
.trim();
|
||||
let bytes = first_line.as_bytes();
|
||||
let stripped = if bytes.len() >= 2 {
|
||||
let first = first_line.chars().next()?;
|
||||
let last = first_line.chars().last()?;
|
||||
if (first == '"' && last == '"')
|
||||
|| (first == '“' && last == '”')
|
||||
|| (first == '\'' && last == '\'')
|
||||
|| (first == '`' && last == '`')
|
||||
{
|
||||
first_line[first.len_utf8()..first_line.len() - last.len_utf8()].trim()
|
||||
} else {
|
||||
first_line
|
||||
}
|
||||
} else {
|
||||
first_line
|
||||
};
|
||||
if stripped.chars().count() < 2 {
|
||||
return None;
|
||||
}
|
||||
normalize_game_creation_project_name(stripped).ok()
|
||||
normalize_game_creation_project_name(value).ok()
|
||||
}
|
||||
|
||||
pub(crate) fn build_automatic_project_name_prompt(
|
||||
|
||||
@@ -1607,8 +1607,16 @@ fn rename_local_game_project_rejects_unsafe_names_and_uninitialized_projects() {
|
||||
#[test]
|
||||
fn automatic_project_name_suggestions_are_normalized_fail_closed() {
|
||||
assert_eq!(
|
||||
normalize_suggested_project_name(" 项目名称:《星轨夜航》 "),
|
||||
Some("《星轨夜航》".to_string())
|
||||
normalize_suggested_project_name(" 星轨夜航 "),
|
||||
Some("星轨夜航".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
normalize_suggested_project_name("星河"),
|
||||
Some("星河".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
normalize_suggested_project_name("一二三四五六七八九十甲乙丙丁戊己"),
|
||||
Some("一二三四五六七八九十甲乙丙丁戊己".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
normalize_suggested_project_name("星轨夜航\n解释"),
|
||||
@@ -1621,6 +1629,16 @@ fn automatic_project_name_suggestions_are_normalized_fail_closed() {
|
||||
"名",
|
||||
"项目名:名",
|
||||
"名称\n控制字符",
|
||||
"**星轨夜航**",
|
||||
"https://example.com",
|
||||
"C:\\projects\\game",
|
||||
"Bearer sk-secret",
|
||||
"“星轨夜航”",
|
||||
"《星轨夜航》",
|
||||
"项目名称:星轨夜航",
|
||||
"星轨夜航2",
|
||||
"星轨Game",
|
||||
&"长".repeat(17),
|
||||
&"长".repeat(81),
|
||||
] {
|
||||
assert!(
|
||||
|
||||
Reference in New Issue
Block a user