Skip to content

Commit

Permalink
Merge pull request ddnet#9271 from Robyt3/Client-Ghost-Integer-Wrapping
Browse files Browse the repository at this point in the history
Ensure integer wrapping for ghost data to prevent over/underflow
  • Loading branch information
heinrich5991 authored Nov 20, 2024
2 parents 6f3cb5e + 971c665 commit 1d3033d
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 13 deletions.
14 changes: 7 additions & 7 deletions src/engine/client/ghost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ void CGhostRecorder::ResetBuffer()
m_BufferNumItems = 0;
}

static void DiffItem(const int32_t *pPast, const int32_t *pCurrent, int32_t *pOut, size_t Size)
static void DiffItem(const uint32_t *pPast, const uint32_t *pCurrent, uint32_t *pOut, size_t Size)
{
while(Size)
{
Expand All @@ -97,7 +97,7 @@ void CGhostRecorder::WriteData(int Type, const void *pData, size_t Size)
{
dbg_assert((bool)m_File, "File not open");
dbg_assert(Type >= 0 && Type <= (int)std::numeric_limits<unsigned char>::max(), "Type invalid");
dbg_assert(Size > 0 && Size <= MAX_ITEM_SIZE && Size % sizeof(int32_t) == 0, "Size invalid");
dbg_assert(Size > 0 && Size <= MAX_ITEM_SIZE && Size % sizeof(uint32_t) == 0, "Size invalid");

if((size_t)(m_pBufferEnd - m_pBufferPos) < Size)
{
Expand All @@ -108,7 +108,7 @@ void CGhostRecorder::WriteData(int Type, const void *pData, size_t Size)
mem_copy(Data.m_aData, pData, Size);
if(m_LastItem.m_Type == Data.m_Type)
{
DiffItem((const int32_t *)m_LastItem.m_aData, (const int32_t *)Data.m_aData, (int32_t *)m_pBufferPos, Size / sizeof(int32_t));
DiffItem((const uint32_t *)m_LastItem.m_aData, (const uint32_t *)Data.m_aData, (uint32_t *)m_pBufferPos, Size / sizeof(uint32_t));
}
else
{
Expand All @@ -134,7 +134,7 @@ void CGhostRecorder::FlushChunk()
{
return;
}
dbg_assert(Size % sizeof(int32_t) == 0, "Chunk size invalid");
dbg_assert(Size % sizeof(uint32_t) == 0, "Chunk size invalid");

Size = CVariableInt::Compress(m_aBuffer, Size, m_aBufferTemp, sizeof(m_aBufferTemp));
if(Size < 0)
Expand Down Expand Up @@ -426,7 +426,7 @@ bool CGhostLoader::ReadNextType(int *pType)
return true;
}

static void UndiffItem(const int32_t *pPast, const int32_t *pDiff, int32_t *pOut, size_t Size)
static void UndiffItem(const uint32_t *pPast, const uint32_t *pDiff, uint32_t *pOut, size_t Size)
{
while(Size)
{
Expand All @@ -442,7 +442,7 @@ bool CGhostLoader::ReadData(int Type, void *pData, size_t Size)
{
dbg_assert((bool)m_File, "File not open");
dbg_assert(Type >= 0 && Type <= (int)std::numeric_limits<unsigned char>::max(), "Type invalid");
dbg_assert(Size > 0 && Size <= MAX_ITEM_SIZE && Size % sizeof(int32_t) == 0, "Size invalid");
dbg_assert(Size > 0 && Size <= MAX_ITEM_SIZE && Size % sizeof(uint32_t) == 0, "Size invalid");

if((size_t)(m_pBufferEnd - m_pBufferPos) < Size)
{
Expand All @@ -453,7 +453,7 @@ bool CGhostLoader::ReadData(int Type, void *pData, size_t Size)
CGhostItem Data(Type);
if(m_LastItem.m_Type == Data.m_Type)
{
UndiffItem((const int32_t *)m_LastItem.m_aData, (const int32_t *)m_pBufferPos, (int32_t *)Data.m_aData, Size / sizeof(int32_t));
UndiffItem((const uint32_t *)m_LastItem.m_aData, (const uint32_t *)m_pBufferPos, (uint32_t *)Data.m_aData, Size / sizeof(uint32_t));
}
else
{
Expand Down
12 changes: 6 additions & 6 deletions src/engine/client/ghost.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ enum
NUM_ITEMS_PER_CHUNK = 50,
MAX_CHUNK_SIZE = MAX_ITEM_SIZE * NUM_ITEMS_PER_CHUNK,
};
static_assert(MAX_CHUNK_SIZE % sizeof(int32_t) == 0, "Chunk size must be aligned with int32_t");
static_assert(MAX_CHUNK_SIZE % sizeof(uint32_t) == 0, "Chunk size must be aligned with uint32_t");

// version 4-6
struct CGhostHeader
Expand All @@ -33,7 +33,7 @@ struct CGhostHeader
class CGhostItem
{
public:
alignas(int32_t) unsigned char m_aData[MAX_ITEM_SIZE];
alignas(uint32_t) unsigned char m_aData[MAX_ITEM_SIZE];
int m_Type;

CGhostItem() :
Expand All @@ -49,8 +49,8 @@ class CGhostRecorder : public IGhostRecorder
char m_aFilename[IO_MAX_PATH_LENGTH];
class IStorage *m_pStorage;

alignas(int32_t) char m_aBuffer[MAX_CHUNK_SIZE];
alignas(int32_t) char m_aBufferTemp[MAX_CHUNK_SIZE];
alignas(uint32_t) char m_aBuffer[MAX_CHUNK_SIZE];
alignas(uint32_t) char m_aBufferTemp[MAX_CHUNK_SIZE];
char *m_pBufferPos;
const char *m_pBufferEnd;
int m_BufferNumItems;
Expand Down Expand Up @@ -80,8 +80,8 @@ class CGhostLoader : public IGhostLoader
CGhostHeader m_Header;
CGhostInfo m_Info;

alignas(int32_t) char m_aBuffer[MAX_CHUNK_SIZE];
alignas(int32_t) char m_aBufferTemp[MAX_CHUNK_SIZE];
alignas(uint32_t) char m_aBuffer[MAX_CHUNK_SIZE];
alignas(uint32_t) char m_aBufferTemp[MAX_CHUNK_SIZE];
char *m_pBufferPos;
const char *m_pBufferEnd;
int m_BufferNumItems;
Expand Down

0 comments on commit 1d3033d

Please sign in to comment.