From ea96e408fe794a2e218e4f263cb3d4209bbb9b4a Mon Sep 17 00:00:00 2001 From: Shauren Date: Sat, 3 Aug 2024 13:40:17 +0200 Subject: Core/PacketIO: Use std::string_view to read strings from ByteBuffer (cherry picked from commit d72e91bee27f766c1f7e50640473522a07fc5389) --- src/server/shared/Packets/ByteBuffer.cpp | 36 +++++++++++++++++++------------- src/server/shared/Packets/ByteBuffer.h | 6 +++--- 2 files changed, 24 insertions(+), 18 deletions(-) (limited to 'src/server/shared') 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 +#include #include #include @@ -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(); - if (c == 0) - break; - value += c; - } + if (_rpos >= size()) + throw ByteBufferPositionException(_rpos, 1, size()); + + ResetBitPos(); + + char const* begin = reinterpret_cast(_storage.data()) + _rpos; + char const* end = reinterpret_cast(_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(&_storage[_rpos]), length); + std::string_view value(reinterpret_cast(&_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() { -- cgit v1.2.3