diff options
author | Treeston <treeston.mmoc@gmail.com> | 2018-09-18 02:08:33 +0200 |
---|---|---|
committer | Treeston <treeston.mmoc@gmail.com> | 2018-09-18 02:08:33 +0200 |
commit | e50344b6df7d917ebc82b6aff4d01b1b5136f7b7 (patch) | |
tree | 25bf9445568c7135797b29e236c2715677408e5c /src/server/game/Handlers/ChatHandler.cpp | |
parent | e858706270c3059acf6915e7cf655eed0f7e88bb (diff) |
Core/Chat: Some more chat filtering cleanup:
* Always filter control characters
* Clean up stripping of duplicate whitespace
* Adjust .conf.dist to accurately describe what the config settings do
Diffstat (limited to 'src/server/game/Handlers/ChatHandler.cpp')
-rw-r--r-- | src/server/game/Handlers/ChatHandler.cpp | 65 |
1 files changed, 32 insertions, 33 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) { |