aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2024-08-03 13:40:17 +0200
committerShauren <shauren.trinity@gmail.com>2024-08-03 13:40:17 +0200
commitd72e91bee27f766c1f7e50640473522a07fc5389 (patch)
tree5a6ec18da5e98f5dfc0297de146084ab4aae47b9
parent2bd96253f3842e331973f4323cd254e1df846c11 (diff)
Core/PacketIO: Use std::string_view to read strings from ByteBuffer
-rw-r--r--src/server/game/Server/Packets/PacketUtilities.cpp14
-rw-r--r--src/server/game/Server/Packets/PacketUtilities.h38
-rw-r--r--src/server/shared/Packets/ByteBuffer.cpp36
-rw-r--r--src/server/shared/Packets/ByteBuffer.h6
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()
{