Core/PacketIO: Validate utf8 in every client packet

(cherry picked from commit 0a2a96efaa)
This commit is contained in:
Shauren
2020-03-15 14:28:29 +01:00
parent bf81c39bbd
commit 09967ad7fd
5 changed files with 57 additions and 45 deletions

View File

@@ -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>();