diff options
| author | Zeyla Hellyer <[email protected]> | 2017-04-15 22:37:49 -0700 |
|---|---|---|
| committer | Zeyla Hellyer <[email protected]> | 2017-04-19 14:53:32 -0700 |
| commit | e1079e9a03473f9ec67414628d5b84e7ea1b5b38 (patch) | |
| tree | c872eced06b3a1dfce04e876f1d7c381ee926f29 /src/model | |
| parent | Add a test suite for event deserialization (diff) | |
| download | serenity-e1079e9a03473f9ec67414628d5b84e7ea1b5b38.tar.xz serenity-e1079e9a03473f9ec67414628d5b84e7ea1b5b38.zip | |
Check for embed lengths on message sends
Due to the maximum length of the textual content of an embed being 4000,
this should be checked prior to message sending.
Embeds have a fairly new limit of only being 4000 character long, at
maximum. The length of these fields - where present - should be summed,
so that bad requests are not made with embeds that are too large in
text.
The fields that count as "textual" includes:
- author name
- description
- `name` and `value` of each field
- footer text
- title
If this exceeds the limit - currently at 4000 unicode codepoints - then
a `ClientError::EmbedTooLarge` will be returned, including the number
of codepoints overflowing.
Diffstat (limited to 'src/model')
| -rw-r--r-- | src/model/channel/channel_id.rs | 9 | ||||
| -rw-r--r-- | src/model/channel/message.rs | 65 |
2 files changed, 67 insertions, 7 deletions
diff --git a/src/model/channel/channel_id.rs b/src/model/channel/channel_id.rs index 5b238b0..79a6fa4 100644 --- a/src/model/channel/channel_id.rs +++ b/src/model/channel/channel_id.rs @@ -418,13 +418,8 @@ impl ChannelId { where F: FnOnce(CreateMessage) -> CreateMessage { let map = f(CreateMessage::default()).0; - if let Some(content) = map.get(&"content".to_owned()) { - if let Value::String(ref content) = *content { - if let Some(length_over) = Message::overflow_length(content) { - return Err(Error::Client(ClientError::MessageTooLong(length_over))); - } - } - } + Message::check_content_length(&map)?; + Message::check_embed_length(&map)?; rest::send_message(self.0, &Value::Object(map)) } diff --git a/src/model/channel/message.rs b/src/model/channel/message.rs index 6bbb1a2..11855b8 100644 --- a/src/model/channel/message.rs +++ b/src/model/channel/message.rs @@ -431,6 +431,71 @@ impl Message { -> Result<Vec<User>> where R: Into<ReactionType>, U: Into<UserId> { self.reaction_users(reaction_type, limit, after) } + + #[doc(hidden)] + pub fn check_content_length(map: &JsonMap) -> Result<()> { + if let Some(content) = map.get("content") { + if let Value::String(ref content) = *content { + if let Some(length_over) = Message::overflow_length(content) { + return Err(Error::Client(ClientError::MessageTooLong(length_over))); + } + } + } + + Ok(()) + } + + #[doc(hidden)] + pub fn check_embed_length(map: &JsonMap) -> Result<()> { + let embed = match map.get("embed") { + Some(&Value::Object(ref value)) => value, + _ => return Ok(()), + }; + + let mut total: usize = 0; + + if let Some(&Value::Object(ref author)) = embed.get("author") { + if let Some(&Value::Object(ref name)) = author.get("name") { + total += name.len(); + } + } + + if let Some(&Value::String(ref description)) = embed.get("description") { + total += description.len(); + } + + if let Some(&Value::Array(ref fields)) = embed.get("fields") { + for field_as_value in fields { + if let Value::Object(ref field) = *field_as_value { + if let Some(&Value::String(ref field_name)) = field.get("name") { + total += field_name.len(); + } + + if let Some(&Value::String(ref field_value)) = field.get("value") { + total += field_value.len(); + } + } + } + } + + if let Some(&Value::Object(ref footer)) = embed.get("footer") { + if let Some(&Value::String(ref text)) = footer.get("text") { + total += text.len(); + } + } + + if let Some(&Value::String(ref title)) = embed.get("title") { + total += title.len(); + } + + if total > constants::EMBED_MAX_LENGTH as usize { + Ok(()) + } else { + let overflow = constants::EMBED_MAX_LENGTH as u64 - total as u64; + + Err(Error::Client(ClientError::EmbedTooLarge(overflow))) + } + } } impl From<Message> for MessageId { |