Core/Chat: Prevent client crashes with invalid chat language and message type combinations

Fixes #8083
This commit is contained in:
leak committed 2012-11-01 20:04:35 +01:00
1 parent 76bdeb5c44
commit 6bf9cb56a9
4 files changed
+51 -46

No files matched your search

+7 -7
View File
@@ -425,7 +425,7 @@ bool ChatHandler::SetDataForCommandInTable(ChatCommand* table, char const* text,
return false; return false;
} }
int ChatHandler::ParseCommands(char const* text) bool ChatHandler::ParseCommands(char const* text)
{ {
ASSERT(text); ASSERT(text);
ASSERT(*text); ASSERT(*text);
@@ -433,23 +433,23 @@ int ChatHandler::ParseCommands(char const* text)
std::string fullcmd = text; std::string fullcmd = text;
if (m_session && AccountMgr::IsPlayerAccount(m_session->GetSecurity()) && !sWorld->getBoolConfig(CONFIG_ALLOW_PLAYER_COMMANDS)) if (m_session && AccountMgr::IsPlayerAccount(m_session->GetSecurity()) && !sWorld->getBoolConfig(CONFIG_ALLOW_PLAYER_COMMANDS))
return 0; return false;
/// chat case (.command or !command format) /// chat case (.command or !command format)
if (m_session) if (m_session)
{ {
if (text[0] != '!' && text[0] != '.') if (text[0] != '!' && text[0] != '.')
return 0; return false;
} }
/// ignore single . and ! in line /// ignore single . and ! in line
if (strlen(text) < 2) if (strlen(text) < 2)
return 0; return false;
// original `text` can't be used. It content destroyed in command code processing. // original `text` can't be used. It content destroyed in command code processing.
/// ignore messages staring from many dots. /// ignore messages staring from many dots.
if ((text[0] == '.' && text[1] == '.') || (text[0] == '!' && text[1] == '!')) if ((text[0] == '.' && text[1] == '.') || (text[0] == '!' && text[1] == '!'))
return 0; return false;
/// skip first . or ! (in console allowed use command with . and ! and without its) /// skip first . or ! (in console allowed use command with . and ! and without its)
if (text[0] == '!' || text[0] == '.') if (text[0] == '!' || text[0] == '.')
@@ -458,11 +458,11 @@ int ChatHandler::ParseCommands(char const* text)
if (!ExecuteCommandInTable(getCommandTable(), text, fullcmd)) if (!ExecuteCommandInTable(getCommandTable(), text, fullcmd))
{ {
if (m_session && AccountMgr::IsPlayerAccount(m_session->GetSecurity())) if (m_session && AccountMgr::IsPlayerAccount(m_session->GetSecurity()))
return 0; return false;
SendSysMessage(LANG_NO_CMD); SendSysMessage(LANG_NO_CMD);
} }
return 1; return true;
} }
bool ChatHandler::isValidChatMessage(char const* message) bool ChatHandler::isValidChatMessage(char const* message)
+1 -1
View File
@@ -74,7 +74,7 @@ class ChatHandler
void PSendSysMessage(int32 entry, ...); void PSendSysMessage(int32 entry, ...);
std::string PGetParseString(int32 entry, ...) const; std::string PGetParseString(int32 entry, ...) const;
int ParseCommands(const char* text); bool ParseCommands(const char* text);
static ChatCommand* getCommandTable(); static ChatCommand* getCommandTable();
+43 -37
View File
@@ -40,28 +40,6 @@
#include "ScriptMgr.h" #include "ScriptMgr.h"
#include "AccountMgr.h" #include "AccountMgr.h"
bool WorldSession::processChatmessageFurtherAfterSecurityChecks(std::string& msg, uint32 lang)
{
if (lang != LANG_ADDON)
{
// strip invisible characters for non-addon messages
if (sWorld->getBoolConfig(CONFIG_CHAT_FAKE_MESSAGE_PREVENTING))
stripLineInvisibleChars(msg);
if (sWorld->getIntConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_SEVERITY) && AccountMgr::IsPlayerAccount(GetSecurity())
&& !ChatHandler(this).isValidChatMessage(msg.c_str()))
{
sLog->outError(LOG_FILTER_NETWORKIO, "Player %s (GUID: %u) sent a chatmessage with an invalid link: %s", GetPlayer()->GetName().c_str(),
GetPlayer()->GetGUIDLow(), msg.c_str());
if (sWorld->getIntConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_KICK))
KickPlayer();
return false;
}
}
return true;
}
void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
{ {
uint32 type; uint32 type;
@@ -112,20 +90,36 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
if (lang == LANG_ADDON) if (lang == LANG_ADDON)
{ {
if (sWorld->getBoolConfig(CONFIG_CHATLOG_ADDON)) // LANG_ADDON is only valid for the following message types
switch (type)
{ {
std::string msg = ""; case CHAT_MSG_PARTY:
recvData >> msg; case CHAT_MSG_RAID:
case CHAT_MSG_GUILD:
case CHAT_MSG_BATTLEGROUND:
case CHAT_MSG_WHISPER:
if (sWorld->getBoolConfig(CONFIG_CHATLOG_ADDON))
{
std::string msg = "";
recvData >> msg;
if (msg.empty()) if (msg.empty())
return;
sScriptMgr->OnPlayerChat(sender, uint32(CHAT_MSG_ADDON), lang, msg);
}
// Disabled addon channel?
if (!sWorld->getBoolConfig(CONFIG_ADDON_CHANNEL))
return;
break;
default:
sLog->outError(LOG_FILTER_NETWORKIO, "Player %s (GUID: %u) sent a chatmessage with an invalid language/message type combination",
GetPlayer()->GetName().c_str(), GetPlayer()->GetGUIDLow());
recvData.rfinish();
return; return;
sScriptMgr->OnPlayerChat(sender, uint32(CHAT_MSG_ADDON), lang, msg);
} }
// Disabled addon channel?
if (!sWorld->getBoolConfig(CONFIG_ADDON_CHANNEL))
return;
} }
// LANG_ADDON should not be changed nor be affected by flood control // LANG_ADDON should not be changed nor be affected by flood control
else else
@@ -223,14 +217,26 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
if (msg.empty()) if (msg.empty())
return; return;
if (ChatHandler(this).ParseCommands(msg.c_str()) > 0) if (ChatHandler(this).ParseCommands(msg.c_str()))
return; return;
if (!processChatmessageFurtherAfterSecurityChecks(msg, lang)) if (lang != LANG_ADDON)
return; {
// Strip invisible characters for non-addon messages
if (sWorld->getBoolConfig(CONFIG_CHAT_FAKE_MESSAGE_PREVENTING))
stripLineInvisibleChars(msg);
if (msg.empty()) if (sWorld->getIntConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_SEVERITY) && !ChatHandler(this).isValidChatMessage(msg.c_str()))
return; {
sLog->outError(LOG_FILTER_NETWORKIO, "Player %s (GUID: %u) sent a chatmessage with an invalid link: %s", GetPlayer()->GetName().c_str(),
GetPlayer()->GetGUIDLow(), msg.c_str());
if (sWorld->getIntConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_KICK))
KickPlayer();
return;
}
}
} }
switch (type) switch (type)
-1
View File
@@ -702,7 +702,6 @@ class WorldSession
void HandlePushQuestToParty(WorldPacket& recvPacket); void HandlePushQuestToParty(WorldPacket& recvPacket);
void HandleQuestPushResult(WorldPacket& recvPacket); void HandleQuestPushResult(WorldPacket& recvPacket);
bool processChatmessageFurtherAfterSecurityChecks(std::string&, uint32);
void HandleMessagechatOpcode(WorldPacket& recvPacket); void HandleMessagechatOpcode(WorldPacket& recvPacket);
void SendPlayerNotFoundNotice(std::string const& name); void SendPlayerNotFoundNotice(std::string const& name);
void SendPlayerAmbiguousNotice(std::string const& name); void SendPlayerAmbiguousNotice(std::string const& name);