Simplify regex for user/community name validation (#5164)

* Add lowercase only check for community names

* Lint

* Remove redundant check

* Lint

* Add newline escape tests

* Eliminate confounding factor in community name test

* Use same check for user names and community names

* Use min/max length check

---------

Co-authored-by: Dessalines <dessalines@users.noreply.github.com>
Co-authored-by: Felix Ableitner <me@nutomic.com>
This commit is contained in:
SleeplessOne1917 2024-11-12 10:54:23 +00:00 committed by GitHub
parent 7d5cb9de49
commit a8fb55d6c8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -85,26 +85,19 @@ fn has_newline(name: &str) -> bool {
}
pub fn is_valid_actor_name(name: &str, actor_name_max_length: usize) -> LemmyResult<()> {
static VALID_ACTOR_NAME_REGEX_EN: LazyLock<Regex> =
LazyLock::new(|| Regex::new(r"^[a-zA-Z0-9_]{3,}$").expect("compile regex"));
static VALID_ACTOR_NAME_REGEX_AR: LazyLock<Regex> =
LazyLock::new(|| Regex::new(r"^[\p{Arabic}0-9_]{3,}$").expect("compile regex"));
static VALID_ACTOR_NAME_REGEX_RU: LazyLock<Regex> =
LazyLock::new(|| Regex::new(r"^[\p{Cyrillic}0-9_]{3,}$").expect("compile regex"));
let check = name.chars().count() <= actor_name_max_length && !has_newline(name);
// Only allow characters from a single alphabet per username. This avoids problems with lookalike
// characters like `o` which looks identical in Latin and Cyrillic, and can be used to imitate
// other users. Checks for additional alphabets can be added in the same way.
let lang_check = VALID_ACTOR_NAME_REGEX_EN.is_match(name)
|| VALID_ACTOR_NAME_REGEX_AR.is_match(name)
|| VALID_ACTOR_NAME_REGEX_RU.is_match(name);
static VALID_ACTOR_NAME_REGEX: LazyLock<Regex> = LazyLock::new(|| {
Regex::new(r"^(?:[a-zA-Z0-9_]+|[0-9_\p{Arabic}]+|[0-9_\p{Cyrillic}]+)$").expect("compile regex")
});
if !check || !lang_check {
Err(LemmyErrorType::InvalidName.into())
} else {
min_length_check(name, 3, LemmyErrorType::InvalidName)?;
max_length_check(name, actor_name_max_length, LemmyErrorType::InvalidName)?;
if VALID_ACTOR_NAME_REGEX.is_match(name) {
Ok(())
} else {
Err(LemmyErrorType::InvalidName.into())
}
}
@ -441,6 +434,15 @@ mod tests {
assert!(is_valid_actor_name("a", actor_name_max_length).is_err());
// empty
assert!(is_valid_actor_name("", actor_name_max_length).is_err());
// newline
assert!(is_valid_actor_name(
r"Line1
Line3",
actor_name_max_length
)
.is_err());
assert!(is_valid_actor_name("Line1\nLine3", actor_name_max_length).is_err());
}
#[test]