diff options
-rw-r--r-- | src/server/game/Server/Packets/PacketUtilities.cpp | 14 | ||||
-rw-r--r-- | src/server/game/Server/Packets/PacketUtilities.h | 38 | ||||
-rw-r--r-- | src/server/shared/Packets/ByteBuffer.cpp | 36 | ||||
-rw-r--r-- | src/server/shared/Packets/ByteBuffer.h | 6 |
4 files changed, 55 insertions, 39 deletions
diff --git a/src/server/game/Server/Packets/PacketUtilities.cpp b/src/server/game/Server/Packets/PacketUtilities.cpp index 2175ed46b29..044a8c5113f 100644 --- a/src/server/game/Server/Packets/PacketUtilities.cpp +++ b/src/server/game/Server/Packets/PacketUtilities.cpp @@ -20,37 +20,37 @@ #include "StringFormat.h" #include <utf8.h> -WorldPackets::InvalidStringValueException::InvalidStringValueException(std::string const& value) : ByteBufferInvalidValueException("string", value.c_str()) +WorldPackets::InvalidStringValueException::InvalidStringValueException(std::string_view value) : ByteBufferInvalidValueException("string", value), _value(value) { } -WorldPackets::InvalidUtf8ValueException::InvalidUtf8ValueException(std::string const& value) : InvalidStringValueException(value) +WorldPackets::InvalidUtf8ValueException::InvalidUtf8ValueException(std::string_view value) : InvalidStringValueException(value) { } -WorldPackets::InvalidHyperlinkException::InvalidHyperlinkException(std::string const& value) : InvalidStringValueException(value) +WorldPackets::InvalidHyperlinkException::InvalidHyperlinkException(std::string_view value) : InvalidStringValueException(value) { } -WorldPackets::IllegalHyperlinkException::IllegalHyperlinkException(std::string const& value) : InvalidStringValueException(value) +WorldPackets::IllegalHyperlinkException::IllegalHyperlinkException(std::string_view value) : InvalidStringValueException(value) { } -bool WorldPackets::Strings::Utf8::Validate(std::string const& value) +bool WorldPackets::Strings::Utf8::Validate(std::string_view value) { if (!utf8::is_valid(value.begin(), value.end())) throw InvalidUtf8ValueException(value); return true; } -bool WorldPackets::Strings::Hyperlinks::Validate(std::string const& value) +bool WorldPackets::Strings::Hyperlinks::Validate(std::string_view value) { if (!Trinity::Hyperlinks::CheckAllLinks(value)) throw InvalidHyperlinkException(value); return true; } -bool WorldPackets::Strings::NoHyperlinks::Validate(std::string const& value) +bool WorldPackets::Strings::NoHyperlinks::Validate(std::string_view value) { if (value.find('|') != std::string::npos) throw IllegalHyperlinkException(value); diff --git a/src/server/game/Server/Packets/PacketUtilities.h b/src/server/game/Server/Packets/PacketUtilities.h index 30973bb3f07..ae28e15606e 100644 --- a/src/server/game/Server/Packets/PacketUtilities.h +++ b/src/server/game/Server/Packets/PacketUtilities.h @@ -31,7 +31,7 @@ namespace WorldPackets class InvalidStringValueException : public ByteBufferInvalidValueException { public: - InvalidStringValueException(std::string const& value); + InvalidStringValueException(std::string_view value); std::string const& GetInvalidValue() const { return _value; } @@ -42,29 +42,29 @@ namespace WorldPackets class InvalidUtf8ValueException : public InvalidStringValueException { public: - InvalidUtf8ValueException(std::string const& value); + InvalidUtf8ValueException(std::string_view value); }; class InvalidHyperlinkException : public InvalidStringValueException { public: - InvalidHyperlinkException(std::string const& value); + InvalidHyperlinkException(std::string_view value); }; class IllegalHyperlinkException : public InvalidStringValueException { public: - IllegalHyperlinkException(std::string const& value); + IllegalHyperlinkException(std::string_view value); }; namespace Strings { - struct RawBytes { static bool Validate(std::string const& /*value*/) { return true; } }; + struct RawBytes { static bool Validate(std::string_view /*value*/) { return true; } }; template<std::size_t MaxBytesWithoutNullTerminator> - struct ByteSize { static bool Validate(std::string const& value) { return value.size() <= MaxBytesWithoutNullTerminator; } }; - struct Utf8 { static bool Validate(std::string const& value); }; - struct Hyperlinks { static bool Validate(std::string const& value); }; - struct NoHyperlinks { static bool Validate(std::string const& value); }; + struct ByteSize { static bool Validate(std::string_view value) { return value.size() <= MaxBytesWithoutNullTerminator; } }; + struct Utf8 { static bool Validate(std::string_view value); }; + struct Hyperlinks { static bool Validate(std::string_view value); }; + struct NoHyperlinks { static bool Validate(std::string_view value); }; } /** @@ -90,9 +90,7 @@ namespace WorldPackets friend ByteBuffer& operator>>(ByteBuffer& data, String& value) { - std::string string = data.ReadCString(false); - Validate(string); - value._storage = std::move(string); + value = data.ReadCString(false); return data; } @@ -110,14 +108,26 @@ namespace WorldPackets return *this; } + String& operator=(std::string_view value) + { + Validate(value); + _storage = std::move(value); + return *this; + } + + String& operator=(char const* value) + { + return *this = std::string_view(value); + } + private: - static bool Validate(std::string const& value) + static bool Validate(std::string_view value) { return ValidateNth(value, std::make_index_sequence<std::tuple_size_v<ValidatorList>>{}); } template<std::size_t... indexes> - static bool ValidateNth(std::string const& value, std::index_sequence<indexes...>) + static bool ValidateNth(std::string_view value, std::index_sequence<indexes...>) { return (std::tuple_element_t<indexes, ValidatorList>::Validate(value) && ...); } diff --git a/src/server/shared/Packets/ByteBuffer.cpp b/src/server/shared/Packets/ByteBuffer.cpp index 07a21a3e73a..a575e52bc1e 100644 --- a/src/server/shared/Packets/ByteBuffer.cpp +++ b/src/server/shared/Packets/ByteBuffer.cpp @@ -21,6 +21,7 @@ #include "Log.h" #include "Util.h" #include <utf8.h> +#include <algorithm> #include <sstream> #include <cmath> @@ -33,7 +34,7 @@ ByteBufferPositionException::ByteBufferPositionException(size_t pos, size_t size { } -ByteBufferInvalidValueException::ByteBufferInvalidValueException(char const* type, char const* value) +ByteBufferInvalidValueException::ByteBufferInvalidValueException(char const* type, std::string_view value) : ByteBufferException(Trinity::StringFormat("Invalid {} value ({}) found in ByteBuffer", type, value)) { } @@ -54,34 +55,39 @@ ByteBuffer& ByteBuffer::operator>>(double& value) return *this; } -std::string ByteBuffer::ReadCString(bool requireValidUtf8 /*= true*/) +std::string_view 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 (_rpos >= size()) + throw ByteBufferPositionException(_rpos, 1, size()); + + ResetBitPos(); + + char const* begin = reinterpret_cast<char const*>(_storage.data()) + _rpos; + char const* end = reinterpret_cast<char const*>(_storage.data()) + size(); + char const* stringEnd = std::ranges::find(begin, end, '\0'); + if (stringEnd == end) + throw ByteBufferPositionException(size(), 1, size()); + + std::string_view value(begin, stringEnd); + _rpos += value.length() + 1; if (requireValidUtf8 && !utf8::is_valid(value.begin(), value.end())) - throw ByteBufferInvalidValueException("string", value.c_str()); + throw ByteBufferInvalidValueException("string", value); return value; } -std::string ByteBuffer::ReadString(uint32 length, bool requireValidUtf8 /*= true*/) +std::string_view ByteBuffer::ReadString(uint32 length, bool requireValidUtf8 /*= true*/) { if (_rpos + length > size()) throw ByteBufferPositionException(_rpos, length, size()); ResetBitPos(); if (!length) - return std::string(); + return {}; - std::string value(reinterpret_cast<char const*>(&_storage[_rpos]), length); + std::string_view value(reinterpret_cast<char const*>(&_storage[_rpos]), length); _rpos += length; if (requireValidUtf8 && !utf8::is_valid(value.begin(), value.end())) - throw ByteBufferInvalidValueException("string", value.c_str()); + throw ByteBufferInvalidValueException("string", value); return value; } diff --git a/src/server/shared/Packets/ByteBuffer.h b/src/server/shared/Packets/ByteBuffer.h index 7de0dde99e7..9233c4f5150 100644 --- a/src/server/shared/Packets/ByteBuffer.h +++ b/src/server/shared/Packets/ByteBuffer.h @@ -49,7 +49,7 @@ public: class TC_SHARED_API ByteBufferInvalidValueException : public ByteBufferException { public: - ByteBufferInvalidValueException(char const* type, char const* value); + ByteBufferInvalidValueException(char const* type, std::string_view value); }; class TC_SHARED_API ByteBuffer @@ -509,9 +509,9 @@ class TC_SHARED_API ByteBuffer append(str, len); } - std::string ReadCString(bool requireValidUtf8 = true); + std::string_view ReadCString(bool requireValidUtf8 = true); - std::string ReadString(uint32 length, bool requireValidUtf8 = true); + std::string_view ReadString(uint32 length, bool requireValidUtf8 = true); uint8* contents() { |