diff --git a/client/src/lib.rs b/client/src/lib.rs index a2dfee571a..b242c00c70 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -9,7 +9,10 @@ pub use specs::{join::Join, saveload::Marker, Entity as EcsEntity, ReadStorage}; use common::{ comp, - msg::{ClientMsg, ClientState, RequestStateError, ServerError, ServerInfo, ServerMsg}, + msg::{ + validate_chat_msg, ChatMsgValidationError, ClientMsg, ClientState, RequestStateError, + ServerError, ServerInfo, ServerMsg, MAX_BYTES_CHAT_MSG, + }, net::PostBox, state::{State, Uid}, terrain::{block::Block, TerrainChunk, TerrainChunkSize}, @@ -232,7 +235,13 @@ impl Client { /// Send a chat message to the server. #[allow(dead_code)] pub fn send_chat(&mut self, msg: String) { - self.postbox.send_message(ClientMsg::chat(msg)) + match validate_chat_msg(&msg) { + Ok(()) => self.postbox.send_message(ClientMsg::chat(msg)), + Err(ChatMsgValidationError::TooLong) => log::warn!( + "Attempted to send a message that's too long (Over {} bytes)", + MAX_BYTES_CHAT_MSG + ), + } } /// Remove all cached terrain diff --git a/common/src/msg/mod.rs b/common/src/msg/mod.rs index 25644b36de..f3230d50a9 100644 --- a/common/src/msg/mod.rs +++ b/common/src/msg/mod.rs @@ -16,3 +16,18 @@ pub enum ClientState { Dead, Character, } + +pub const MAX_BYTES_CHAT_MSG: usize = 80; + +pub enum ChatMsgValidationError { + TooLong, +} + +pub fn validate_chat_msg(msg: &str) -> Result<(), ChatMsgValidationError> { + // TODO: Consider using grapheme cluster count instead of size in bytes + if msg.len() <= MAX_BYTES_CHAT_MSG { + Ok(()) + } else { + Err(ChatMsgValidationError::TooLong) + } +} diff --git a/server/src/lib.rs b/server/src/lib.rs index ec5b9cf319..8fb719590a 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -999,8 +999,17 @@ impl Server { ClientState::Registered | ClientState::Spectator | ClientState::Dead - | ClientState::Character => new_chat_msgs - .push((Some(entity), ServerMsg::ChatMsg { chat_type, message })), + | ClientState::Character => match validate_chat_msg(&message) { + Ok(()) => new_chat_msgs.push(( + Some(entity), + ServerMsg::ChatMsg { chat_type, message }, + )), + Err(ChatMsgValidationError::TooLong) => log::warn!( + "Recieved a chat message that's too long (max:{} len:{})", + MAX_BYTES_CHAT_MSG, + message.len() + ), + }, ClientState::Pending => {} }, ClientMsg::PlayerPhysics { pos, vel, ori } => match client.client_state { diff --git a/voxygen/src/hud/chat.rs b/voxygen/src/hud/chat.rs index 82de74380f..b9e2119285 100644 --- a/voxygen/src/hud/chat.rs +++ b/voxygen/src/hud/chat.rs @@ -3,7 +3,7 @@ use super::{ KILL_COLOR, META_COLOR, PRIVATE_COLOR, SAY_COLOR, TELL_COLOR, TEXT_COLOR, }; use client::Event as ClientEvent; -use common::ChatType; +use common::{msg::validate_chat_msg, ChatType}; use conrod_core::{ input::Key, position::Dimension, @@ -59,7 +59,9 @@ impl<'a> Chat<'a> { } pub fn input(mut self, input: String) -> Self { - self.force_input = Some(input); + if let Ok(()) = validate_chat_msg(&input) { + self.force_input = Some(input); + } self } @@ -206,7 +208,9 @@ impl<'a> Widget for Chat<'a> { { let mut input = str.to_owned(); input.retain(|c| c != '\n'); - state.update(|s| s.input = input); + if let Ok(()) = validate_chat_msg(&input) { + state.update(|s| s.input = input); + } } }