diff options
-rw-r--r-- | src/server/game/Handlers/ChannelHandler.cpp | 7 | ||||
-rw-r--r-- | src/server/game/Handlers/ChatHandler.cpp | 9 | ||||
-rw-r--r-- | src/server/game/Server/Packets/ChatPackets.cpp | 2 | ||||
-rw-r--r-- | src/server/shared/Packets/ByteBuffer.cpp | 41 | ||||
-rw-r--r-- | src/server/shared/Packets/ByteBuffer.h | 43 |
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() |