aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Handlers/ChannelHandler.cpp7
-rw-r--r--src/server/game/Handlers/ChatHandler.cpp9
-rw-r--r--src/server/game/Server/Packets/ChatPackets.cpp2
-rw-r--r--src/server/shared/Packets/ByteBuffer.cpp41
-rw-r--r--src/server/shared/Packets/ByteBuffer.h43
5 files changed, 57 insertions, 45 deletions
diff --git a/src/server/game/Handlers/ChannelHandler.cpp b/src/server/game/Handlers/ChannelHandler.cpp
index 161b5ea784d..3d55008db27 100644
--- a/src/server/game/Handlers/ChannelHandler.cpp
+++ b/src/server/game/Handlers/ChannelHandler.cpp
@@ -24,7 +24,6 @@
#include "ObjectMgr.h" // for normalizePlayerName
#include "Player.h"
#include <cctype>
-#include <utf8.h>
static size_t const MAX_CHANNEL_NAME_STR = 0x31;
static size_t const MAX_CHANNEL_PASS_STR = 31;
@@ -48,12 +47,6 @@ void WorldSession::HandleJoinChannel(WorldPackets::Channel::JoinChannel& packet)
if (packet.ChannelName.empty())
return;
- if (!utf8::is_valid(packet.ChannelName.begin(), packet.ChannelName.end()))
- {
- TC_LOG_ERROR("network", "Player %s tried to create a channel with an invalid UTF8 sequence - blocked", GetPlayer()->GetGUID().ToString().c_str());
- return;
- }
-
if (!ValidateHyperlinksAndMaybeKick(packet.ChannelName))
return;
diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp
index bbf607bfe5b..7effd8f9a8c 100644
--- a/src/server/game/Handlers/ChatHandler.cpp
+++ b/src/server/game/Handlers/ChatHandler.cpp
@@ -41,7 +41,6 @@
#include "Util.h"
#include "World.h"
#include "WorldPacket.h"
-#include <utf8.h>
#include <algorithm>
inline bool isNasty(uint8 c)
@@ -73,14 +72,6 @@ inline bool ValidateMessage(Player const* player, std::string& msg)
}
}
- // validate utf8
- if (!utf8::is_valid(msg.begin(), msg.end()))
- {
- TC_LOG_ERROR("network", "Player %s (%s) sent a message containing an invalid UTF8 sequence - blocked", player->GetName().c_str(),
- player->GetGUID().ToString().c_str());
- return false;
- }
-
// collapse multiple spaces into one
if (sWorld->getBoolConfig(CONFIG_CHAT_FAKE_MESSAGE_PREVENTING))
{
diff --git a/src/server/game/Server/Packets/ChatPackets.cpp b/src/server/game/Server/Packets/ChatPackets.cpp
index 41fd5249b11..ed8953d7eff 100644
--- a/src/server/game/Server/Packets/ChatPackets.cpp
+++ b/src/server/game/Server/Packets/ChatPackets.cpp
@@ -55,7 +55,7 @@ ByteBuffer& operator>>(ByteBuffer& data, WorldPackets::Chat::ChatAddonMessagePar
params.IsLogged = data.ReadBit();
params.Type = ChatMsg(data.read<int32>());
params.Prefix = data.ReadString(prefixLen);
- params.Text = data.ReadString(textLen);
+ params.Text = data.ReadString(textLen, false);
return data;
}
diff --git a/src/server/shared/Packets/ByteBuffer.cpp b/src/server/shared/Packets/ByteBuffer.cpp
index c8aecb24396..c0a4122d745 100644
--- a/src/server/shared/Packets/ByteBuffer.cpp
+++ b/src/server/shared/Packets/ByteBuffer.cpp
@@ -20,6 +20,7 @@
#include "MessageBuffer.h"
#include "Log.h"
#include "Util.h"
+#include <utf8.h>
#include <sstream>
#include <ctime>
@@ -38,11 +39,16 @@ ByteBufferPositionException::ByteBufferPositionException(size_t pos, size_t size
message().assign(ss.str());
}
+ByteBufferInvalidValueException::ByteBufferInvalidValueException(char const* type, size_t pos)
+{
+ message().assign(Trinity::StringFormat("Invalid %s value found in ByteBuffer at pos " SZFMTD));
+}
+
ByteBuffer& ByteBuffer::operator>>(float& value)
{
value = read<float>();
if (!std::isfinite(value))
- throw ByteBufferException();
+ throw ByteBufferInvalidValueException("float", _rpos - sizeof(float));
return *this;
}
@@ -50,10 +56,41 @@ ByteBuffer& ByteBuffer::operator>>(double& value)
{
value = read<double>();
if (!std::isfinite(value))
- throw ByteBufferException();
+ throw ByteBufferInvalidValueException("double", _rpos - sizeof(double));
return *this;
}
+std::string ByteBuffer::ReadCString(bool requireValidUtf8 /*= true*/)
+{
+ std::string value;
+ while (rpos() < size()) // prevent crash at wrong string format in packet
+ {
+ char c = read<char>();
+ if (c == 0)
+ break;
+ value += c;
+ }
+ if (requireValidUtf8 && !utf8::is_valid(value.begin(), value.end()))
+ throw ByteBufferInvalidValueException("string", _rpos - value.length() - 1);
+ return value;
+}
+
+std::string ByteBuffer::ReadString(uint32 length, bool requireValidUtf8 /*= true*/)
+{
+ if (_rpos + length > size())
+ throw ByteBufferPositionException(_rpos, length, size());
+
+ ResetBitPos();
+ if (!length)
+ return std::string();
+
+ std::string value(reinterpret_cast<char const*>(&_storage[_rpos]), length);
+ _rpos += length;
+ if (requireValidUtf8 && !utf8::is_valid(value.begin(), value.end()))
+ throw ByteBufferInvalidValueException("string", _rpos - value.length() - 1);
+ return value;
+}
+
uint32 ByteBuffer::ReadPackedTime()
{
uint32 packedDate = read<uint32>();
diff --git a/src/server/shared/Packets/ByteBuffer.h b/src/server/shared/Packets/ByteBuffer.h
index c629048922d..553c1a4c4ff 100644
--- a/src/server/shared/Packets/ByteBuffer.h
+++ b/src/server/shared/Packets/ByteBuffer.h
@@ -36,7 +36,7 @@ public:
char const* what() const noexcept override { return msg_.c_str(); }
protected:
- std::string& message() { return msg_; }
+ std::string & message() noexcept { return msg_; }
private:
std::string msg_;
@@ -50,11 +50,19 @@ public:
~ByteBufferPositionException() noexcept = default;
};
+class TC_SHARED_API ByteBufferInvalidValueException : public ByteBufferException
+{
+public:
+ ByteBufferInvalidValueException(char const* type, size_t pos);
+
+ ~ByteBufferInvalidValueException() noexcept = default;
+};
+
class TC_SHARED_API ByteBuffer
{
public:
- static size_t const DEFAULT_SIZE = 0x1000;
- static uint8 const InitialBitPos = 8;
+ constexpr static size_t DEFAULT_SIZE = 0x1000;
+ constexpr static uint8 InitialBitPos = 8;
// constructor
ByteBuffer() : _rpos(0), _wpos(0), _bitpos(InitialBitPos), _curbitval(0)
@@ -366,16 +374,9 @@ class TC_SHARED_API ByteBuffer
ByteBuffer &operator>>(float &value);
ByteBuffer &operator>>(double &value);
- ByteBuffer &operator>>(std::string& value)
+ ByteBuffer& operator>>(std::string& value)
{
- value.clear();
- while (rpos() < size()) // prevent crash at wrong string format in packet
- {
- char c = read<char>();
- if (c == 0)
- break;
- value += c;
- }
+ value = ReadCString(true);
return *this;
}
@@ -492,20 +493,6 @@ class TC_SHARED_API ByteBuffer
value |= (uint64(read<uint8>()) << (i * 8));
}
- std::string ReadString(uint32 length)
- {
- if (_rpos + length > size())
- throw ByteBufferPositionException(_rpos, length, size());
-
- ResetBitPos();
- if (!length)
- return std::string();
-
- std::string str((char const*)&_storage[_rpos], length);
- _rpos += length;
- return str;
- }
-
//! Method for writing strings that have their length sent separately in packet
//! without null-terminating the string
void WriteString(std::string const& str)
@@ -520,6 +507,10 @@ class TC_SHARED_API ByteBuffer
append(str, len);
}
+ std::string ReadCString(bool requireValidUtf8 = true);
+
+ std::string ReadString(uint32 length, bool requireValidUtf8 = true);
+
uint32 ReadPackedTime();
uint8* contents()