diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Handlers/ChatHandler.cpp | 65 | ||||
-rw-r--r-- | src/server/worldserver/worldserver.conf.dist | 7 |
2 files changed, 36 insertions, 36 deletions
diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp index bab3afae48f..08aac7d5462 100644 --- a/src/server/game/Handlers/ChatHandler.cpp +++ b/src/server/game/Handlers/ChatHandler.cpp @@ -41,36 +41,17 @@ #include "Util.h" #include "World.h" #include "WorldPacket.h" +#include <algorithm> -static void StripInvisibleChars(std::string& str) +inline bool isNasty(char c) { - static std::string const invChars = " \t\7\n"; - - size_t wpos = 0; - - bool space = false; - for (size_t pos = 0; pos < str.size(); ++pos) - { - if (invChars.find(str[pos]) != std::string::npos) - { - if (!space) - { - str[wpos++] = ' '; - space = true; - } - } - else - { - if (wpos != pos) - str[wpos++] = str[pos]; - else - ++wpos; - space = false; - } - } - - if (wpos < str.size()) - str.erase(wpos, str.size()); + if (c < 32) // all of these are control characters + return true; + if (c == 127) // ascii delete + return true; + if (c == 255) // non-breaking whitespace + return true; + return false; } void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) @@ -242,9 +223,6 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) if (msg.size() > 255) return; - // Strip invisible characters for non-addon messages - if (sWorld->getBoolConfig(CONFIG_CHAT_FAKE_MESSAGE_PREVENTING) && lang != LANG_ADDON) - StripInvisibleChars(msg); // no chat commands in AFK/DND autoreply, and it can be empty if (!(type == CHAT_MSG_AFK || type == CHAT_MSG_DND)) @@ -263,8 +241,29 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) } } - if ((lang != LANG_ADDON) && !ValidateHyperlinksAndMaybeKick(msg)) - return; + // do message validity checks + if (lang != LANG_ADDON) + { + // abort on any sort of nasty character + for (char c : msg) + if (isNasty(c)) + { + TC_LOG_ERROR("network", "Player %s (GUID: %u) sent a message containing control character %u - blocked", GetPlayer()->GetName().c_str(), + GetPlayer()->GetGUID().GetCounter(), uint32(c)); + return; + } + + // collapse multiple spaces into one + if (sWorld->getBoolConfig(CONFIG_CHAT_FAKE_MESSAGE_PREVENTING)) + { + auto end = std::unique(msg.begin(), msg.end(), [](char c1, char c2) { return (c1 == ' ') && (c2 == ' '); }); + msg.erase(end, msg.end()); + } + + // validate hyperlinks + if (!ValidateHyperlinksAndMaybeKick(msg)) + return; + } switch (type) { diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index 5463affdb5b..49ee6ab3cfd 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -1876,9 +1876,10 @@ Respawn.DynamicMinimumGameObject = 10 # CHAT SETTINGS # # ChatFakeMessagePreventing -# Description: Chat protection from creating fake messages using a lot spaces or other -# invisible symbols. Not applied to the addon language, but may break old -# addons that use normal languages for sending data to other clients. +# Description: Additional protection from creating fake chat messages using spaces. +# Collapses multiple subsequent whitespaces into a single whitespace. +# Not applied to the addon language, but may break old addons that use +# "normal" chat messages for sending data to other clients. # Default: 1 - (Enabled, Blizzlike) # 0 - (Disabled) |