mirror of
https://github.com/matrix-org/matrix-rust-sdk.git
synced 2026-05-06 23:15:08 -04:00
refactor(ffi): Improve is_room_alias_format_valid so it's more strict.
Previously this only used the Ruma checks, which only handled the initial `#` char and the domain part. With these changes, the name part is also validated, checking it's lowercase, with no whitespaces and containing only allowed chars, similar to what `DisplayName::to_room_alias_name` does. Moved the code to the SDK crate so it can be properly tested.
This commit is contained in:
committed by
Jorge Martin Espinosa
parent
965a59d5b8
commit
7c600fddf0
@@ -1,10 +1,13 @@
|
||||
use matrix_sdk::RoomDisplayName;
|
||||
use ruma::RoomAliasId;
|
||||
|
||||
/// Verifies the passed `String` matches the expected room alias format.
|
||||
/// Verifies the passed `String` matches the expected room alias format:
|
||||
///
|
||||
/// This means it's lowercase, with no whitespace chars, has a single leading
|
||||
/// `#` char and a single `:` separator between the local and domain parts, and
|
||||
/// the local part only contains characters that can't be percent encoded.
|
||||
#[matrix_sdk_ffi_macros::export]
|
||||
fn is_room_alias_format_valid(alias: String) -> bool {
|
||||
RoomAliasId::parse(alias).is_ok()
|
||||
matrix_sdk::utils::is_room_alias_format_valid(alias)
|
||||
}
|
||||
|
||||
/// Transforms a Room's display name into a valid room alias name.
|
||||
|
||||
@@ -24,6 +24,7 @@ use futures_util::StreamExt;
|
||||
use ruma::{
|
||||
events::{AnyMessageLikeEventContent, AnyStateEventContent},
|
||||
serde::Raw,
|
||||
RoomAliasId,
|
||||
};
|
||||
use serde_json::value::{RawValue as RawJsonValue, Value as JsonValue};
|
||||
#[cfg(feature = "e2e-encryption")]
|
||||
@@ -190,8 +191,37 @@ impl IntoRawStateEventContent for &Box<RawJsonValue> {
|
||||
}
|
||||
}
|
||||
|
||||
const INVALID_ROOM_ALIAS_NAME_CHARS: &str = "#,:";
|
||||
|
||||
/// Verifies the passed `String` matches the expected room alias format:
|
||||
///
|
||||
/// This means it's lowercase, with no whitespace chars, has a single leading
|
||||
/// `#` char and a single `:` separator between the local and domain parts, and
|
||||
/// the local part only contains characters that can't be percent encoded.
|
||||
pub fn is_room_alias_format_valid(alias: String) -> bool {
|
||||
let alias_parts: Vec<&str> = alias.split(':').collect();
|
||||
if alias_parts.len() != 2 {
|
||||
return false;
|
||||
}
|
||||
|
||||
let local_part = alias_parts[0];
|
||||
let has_valid_format = local_part.chars().skip(1).all(|c| {
|
||||
c.is_ascii()
|
||||
&& !c.is_whitespace()
|
||||
&& !c.is_control()
|
||||
&& !INVALID_ROOM_ALIAS_NAME_CHARS.contains(c)
|
||||
});
|
||||
|
||||
let is_lowercase = alias.to_lowercase() == alias;
|
||||
|
||||
// Checks both the local part and the domain part
|
||||
has_valid_format && is_lowercase && RoomAliasId::parse(alias).is_ok()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::utils::is_room_alias_format_valid;
|
||||
|
||||
#[cfg(feature = "e2e-encryption")]
|
||||
#[test]
|
||||
fn test_channel_observable_get_set() {
|
||||
@@ -202,4 +232,54 @@ mod test {
|
||||
assert_eq!(observable.set(10), 1);
|
||||
assert_eq!(observable.get(), 10);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_room_alias_format_valid_when_it_has_no_leading_hash_char_is_not_valid() {
|
||||
assert!(!is_room_alias_format_valid("alias:domain.org".to_owned()))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_room_alias_format_valid_when_it_has_several_colon_chars_is_not_valid() {
|
||||
assert!(!is_room_alias_format_valid("#alias:something:domain.org".to_owned()))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_room_alias_format_valid_when_it_has_no_colon_chars_is_not_valid() {
|
||||
assert!(!is_room_alias_format_valid("#alias.domain.org".to_owned()))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_room_alias_format_valid_when_server_part_is_not_valid() {
|
||||
assert!(!is_room_alias_format_valid("#alias:".to_owned()))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_room_alias_format_valid_when_name_part_has_whitespace_is_not_valid() {
|
||||
assert!(!is_room_alias_format_valid("#alias with whitespace:domain.org".to_owned()))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_room_alias_format_valid_when_name_part_has_control_char_is_not_valid() {
|
||||
assert!(!is_room_alias_format_valid("#alias\u{0009}:domain.org".to_owned()))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_room_alias_format_valid_when_name_part_has_invalid_char_is_not_valid() {
|
||||
assert!(!is_room_alias_format_valid("#alias,test:domain.org".to_owned()))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_room_alias_format_valid_when_name_part_is_not_lowercase_is_not_valid() {
|
||||
assert!(!is_room_alias_format_valid("#Alias:domain.org".to_owned()))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_room_alias_format_valid_when_server_part_is_not_lowercase_is_not_valid() {
|
||||
assert!(!is_room_alias_format_valid("#alias:Domain.org".to_owned()))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_room_alias_format_valid_when_has_valid_format() {
|
||||
assert!(is_room_alias_format_valid("#alias.test:domain.org".to_owned()))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user