diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ac5e14..44f9367 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [Unreleased] +### Changed + +- Added emoji count check to profile data validator. + ## [1.20.0] - 2023-03-07 ### Added diff --git a/src/activitypub/actors/helpers.rs b/src/activitypub/actors/helpers.rs index 5f9849f..69bc009 100644 --- a/src/activitypub/actors/helpers.rs +++ b/src/activitypub/actors/helpers.rs @@ -24,7 +24,7 @@ use crate::activitypub::{ }; use crate::media::MediaStorage; use crate::validators::{ - posts::EMOJIS_MAX_NUM, + posts::EMOJI_LIMIT, profiles::{clean_profile_create_data, clean_profile_update_data}, }; @@ -123,7 +123,7 @@ async fn parse_tags( for tag_value in actor.tag.clone() { let tag_type = tag_value["type"].as_str().unwrap_or(HASHTAG); if tag_type == EMOJI { - if emojis.len() >= EMOJIS_MAX_NUM { + if emojis.len() >= EMOJI_LIMIT { log::warn!("too many emojis"); continue; }; diff --git a/src/activitypub/handlers/create.rs b/src/activitypub/handlers/create.rs index 15b92e8..30134f5 100644 --- a/src/activitypub/handlers/create.rs +++ b/src/activitypub/handlers/create.rs @@ -50,11 +50,11 @@ use crate::validators::{ }, posts::{ content_allowed_classes, - ATTACHMENTS_MAX_NUM, + ATTACHMENT_LIMIT, CONTENT_MAX_SIZE, - EMOJIS_MAX_NUM, - LINKS_MAX_NUM, - MENTIONS_MAX_NUM, + EMOJI_LIMIT, + LINK_LIMIT, + MENTION_LIMIT, OBJECT_ID_SIZE_MAX, }, tags::validate_hashtag, @@ -183,7 +183,7 @@ pub async fn get_object_attachments( log::info!("downloaded attachment {}", attachment_url); downloaded.push((file_name, file_size, maybe_media_type)); // Stop downloading if limit is reached - if downloaded.len() >= ATTACHMENTS_MAX_NUM { + if downloaded.len() >= ATTACHMENT_LIMIT { log::warn!("too many attachments"); break; }; @@ -363,7 +363,7 @@ pub async fn get_object_tags( }; }; } else if tag_type == MENTION { - if mentions.len() >= MENTIONS_MAX_NUM { + if mentions.len() >= MENTION_LIMIT { log::warn!("too many mentions"); continue; }; @@ -444,7 +444,7 @@ pub async fn get_object_tags( log::warn!("failed to parse mention {}", tag_name); }; } else if tag_type == LINK { - if links.len() >= LINKS_MAX_NUM { + if links.len() >= LINK_LIMIT { log::warn!("too many links"); continue; }; @@ -471,7 +471,7 @@ pub async fn get_object_tags( links.push(linked.id); }; } else if tag_type == EMOJI { - if emojis.len() >= EMOJIS_MAX_NUM { + if emojis.len() >= EMOJI_LIMIT { log::warn!("too many emojis"); continue; }; diff --git a/src/mastodon_api/instance/types.rs b/src/mastodon_api/instance/types.rs index 071889a..7b4d76d 100644 --- a/src/mastodon_api/instance/types.rs +++ b/src/mastodon_api/instance/types.rs @@ -9,7 +9,7 @@ use mitra_utils::markdown::markdown_to_html; use crate::mastodon_api::MASTODON_API_VERSION; use crate::media::SUPPORTED_MEDIA_TYPES; -use crate::validators::posts::ATTACHMENTS_MAX_NUM; +use crate::validators::posts::ATTACHMENT_LIMIT; #[derive(Serialize)] struct InstanceStats { @@ -93,7 +93,7 @@ impl InstanceInfo { configuration: InstanceConfiguration { statuses: InstanceStatusLimits { max_characters: config.limits.posts.character_limit, - max_media_attachments: ATTACHMENTS_MAX_NUM, + max_media_attachments: ATTACHMENT_LIMIT, }, media_attachments: InstanceMediaLimits { supported_mime_types: SUPPORTED_MEDIA_TYPES.iter() diff --git a/src/mastodon_api/statuses/microsyntax/links.rs b/src/mastodon_api/statuses/microsyntax/links.rs index 1b7fe35..539e702 100644 --- a/src/mastodon_api/statuses/microsyntax/links.rs +++ b/src/mastodon_api/statuses/microsyntax/links.rs @@ -8,7 +8,7 @@ use mitra_models::{ }; use crate::activitypub::fetcher::helpers::get_post_by_object_id; -use crate::validators::posts::LINKS_MAX_NUM; +use crate::validators::posts::LINK_LIMIT; // MediaWiki-like syntax: [[url|text]] const OBJECT_LINK_SEARCH_RE: &str = r"(?m)\[\[(?P[^\s\|]+)(\|(?P.+?))?\]\]"; @@ -49,7 +49,7 @@ pub async fn find_linked_posts( let mut link_map: HashMap = HashMap::new(); let mut counter = 0; for url in links { - if counter > LINKS_MAX_NUM { + if counter > LINK_LIMIT { // Limit the number of queries break; // TODO: single database query diff --git a/src/mastodon_api/statuses/views.rs b/src/mastodon_api/statuses/views.rs index d4a92d2..5ac54e1 100644 --- a/src/mastodon_api/statuses/views.rs +++ b/src/mastodon_api/statuses/views.rs @@ -57,8 +57,8 @@ use crate::mastodon_api::{ use crate::media::remove_media; use crate::validators::posts::{ clean_content, - ATTACHMENTS_MAX_NUM, - EMOJIS_MAX_NUM, + ATTACHMENT_LIMIT, + EMOJI_LIMIT, }; use super::helpers::{ build_status, @@ -137,7 +137,7 @@ async fn create_status( // Emoji validation let emojis: Vec<_> = emojis.iter().map(|emoji| emoji.id).collect(); - if emojis.len() > EMOJIS_MAX_NUM { + if emojis.len() > EMOJI_LIMIT { return Err(ValidationError("too many emojis").into()); }; @@ -171,7 +171,7 @@ async fn create_status( }; // Validate attachments let attachments = status_data.media_ids.unwrap_or(vec![]); - if attachments.len() > ATTACHMENTS_MAX_NUM { + if attachments.len() > ATTACHMENT_LIMIT { return Err(ValidationError("too many attachments").into()); }; diff --git a/src/validators/posts.rs b/src/validators/posts.rs index 7ed3458..25575ef 100644 --- a/src/validators/posts.rs +++ b/src/validators/posts.rs @@ -2,10 +2,10 @@ use mitra_utils::html::clean_html_strict; use crate::errors::ValidationError; -pub const ATTACHMENTS_MAX_NUM: usize = 15; -pub const MENTIONS_MAX_NUM: usize = 50; -pub const LINKS_MAX_NUM: usize = 10; -pub const EMOJIS_MAX_NUM: usize = 50; +pub const ATTACHMENT_LIMIT: usize = 15; +pub const MENTION_LIMIT: usize = 50; +pub const LINK_LIMIT: usize = 10; +pub const EMOJI_LIMIT: usize = 50; pub const OBJECT_ID_SIZE_MAX: usize = 2000; pub const CONTENT_MAX_SIZE: usize = 100000; diff --git a/src/validators/profiles.rs b/src/validators/profiles.rs index 6c7fb7c..bdf3fe1 100644 --- a/src/validators/profiles.rs +++ b/src/validators/profiles.rs @@ -9,6 +9,8 @@ use mitra_utils::html::{clean_html, clean_html_strict}; use crate::errors::ValidationError; +use super::posts::EMOJI_LIMIT; + const USERNAME_RE: &str = r"^[a-zA-Z0-9_\.-]+$"; const DISPLAY_NAME_MAX_LENGTH: usize = 200; const BIO_MAX_LENGTH: usize = 10000; @@ -106,6 +108,9 @@ pub fn clean_profile_create_data( &profile_data.extra_fields, is_remote, )?; + if profile_data.emojis.len() > EMOJI_LIMIT { + return Err(ValidationError("too many emojis")); + }; Ok(()) } @@ -124,6 +129,9 @@ pub fn clean_profile_update_data( &profile_data.extra_fields, is_remote, )?; + if profile_data.emojis.len() > EMOJI_LIMIT { + return Err(ValidationError("too many emojis")); + }; Ok(()) }