aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Handlers/ChatHandler.cpp65
-rw-r--r--src/server/worldserver/worldserver.conf.dist7
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)