mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-15 23:20:36 +01:00
Core/PacketIO: Use std::string_view to read strings from ByteBuffer
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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) && ...);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user