aboutsummaryrefslogtreecommitdiff
path: root/src/model
diff options
context:
space:
mode:
authorZeyla Hellyer <[email protected]>2017-04-15 22:37:49 -0700
committerZeyla Hellyer <[email protected]>2017-04-19 14:53:32 -0700
commite1079e9a03473f9ec67414628d5b84e7ea1b5b38 (patch)
treec872eced06b3a1dfce04e876f1d7c381ee926f29 /src/model
parentAdd a test suite for event deserialization (diff)
downloadserenity-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.rs9
-rw-r--r--src/model/channel/message.rs65
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 {