mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2025-12-24 08:12:53 +01:00
Fix potential crash on corrupted network data
This commit is contained in:
@@ -2488,6 +2488,12 @@ void NetworkBase::Server_Handle_MAPREQUEST(NetworkConnection& connection, Networ
|
||||
for (uint32_t i = 0; i < size; i++)
|
||||
{
|
||||
const char* name = reinterpret_cast<const char*>(packet.Read(8));
|
||||
if (name == nullptr)
|
||||
{
|
||||
log_error("Client sent malformed object request data %s", connection.Socket->GetHostName());
|
||||
return;
|
||||
}
|
||||
|
||||
// This is required, as packet does not have null terminator
|
||||
std::string s(name, name + 8);
|
||||
log_verbose("Client requested object %s", s.c_str());
|
||||
|
||||
@@ -61,13 +61,14 @@ NetworkReadPacket NetworkConnection::ReadPacket()
|
||||
|
||||
// NOTE: For compatibility reasons for the master server we need to remove sizeof(Header.Id) from the size.
|
||||
// Previously the Id field was not part of the header rather part of the body.
|
||||
header.Size -= sizeof(header.Id);
|
||||
header.Size -= std::min<uint16_t>(header.Size, sizeof(header.Id));
|
||||
|
||||
// Fall-through: Read rest of packet.
|
||||
}
|
||||
|
||||
// Read packet body.
|
||||
{
|
||||
// NOTE: BytesTransfered includes the header length, this will not underflow.
|
||||
const size_t missingLength = header.Size - (InboundPacket.BytesTransferred - sizeof(header));
|
||||
|
||||
uint8_t buffer[NetworkBufferSize];
|
||||
|
||||
@@ -73,13 +73,13 @@ void NetworkPacket::WriteString(const utf8* string)
|
||||
|
||||
const uint8_t* NetworkPacket::Read(size_t size)
|
||||
{
|
||||
if (BytesRead + size > Header.Size)
|
||||
if (BytesRead + size > Data.size())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t* data = &GetData()[BytesRead];
|
||||
const uint8_t* data = Data.data() + BytesRead;
|
||||
BytesRead += size;
|
||||
return data;
|
||||
}
|
||||
@@ -87,18 +87,24 @@ const uint8_t* NetworkPacket::Read(size_t size)
|
||||
|
||||
const utf8* NetworkPacket::ReadString()
|
||||
{
|
||||
char* str = reinterpret_cast<char*>(&GetData()[BytesRead]);
|
||||
char* strend = str;
|
||||
while (BytesRead < Header.Size && *strend != 0)
|
||||
if (BytesRead >= Data.size())
|
||||
return nullptr;
|
||||
|
||||
const char* str = reinterpret_cast<const char*>(Data.data() + BytesRead);
|
||||
|
||||
size_t stringLen = 0;
|
||||
while (BytesRead < Data.size() && str[stringLen] != '\0')
|
||||
{
|
||||
BytesRead++;
|
||||
strend++;
|
||||
stringLen++;
|
||||
}
|
||||
if (*strend != 0)
|
||||
{
|
||||
|
||||
if (str[stringLen] != '\0')
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Skip null terminator.
|
||||
BytesRead++;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user