mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-17 21:48:19 +00:00
Merge pull request #8995 from Robyt3/Snapshot-Builder-Size-Fix
Fix snapshot builder creating too large snapshots, do not add snap item if extended item type could not be added, fix snapshot handling when converting 0.7 demo snapshot fails
This commit is contained in:
commit
6086a93bd6
|
@ -2006,10 +2006,11 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket, int Conn, bool Dummy)
|
|||
if(DemoSnapSize < 0)
|
||||
{
|
||||
dbg_msg("sixup", "demo snapshot failed. error=%d", DemoSnapSize);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(DemoSnapSize >= 0)
|
||||
{
|
||||
// add snapshot to demo
|
||||
for(auto &DemoRecorder : m_aDemoRecorder)
|
||||
{
|
||||
|
@ -2020,6 +2021,7 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket, int Conn, bool Dummy)
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// apply snapshot, cycle pointers
|
||||
m_aReceivedSnapshots[Conn]++;
|
||||
|
|
|
@ -8,17 +8,6 @@ void CSnapshotBuilder::Init7(const CSnapshot *pSnapshot)
|
|||
// but the snap we are building is a 0.6 snap
|
||||
m_Sixup = false;
|
||||
|
||||
if(pSnapshot->m_DataSize + sizeof(CSnapshot) + pSnapshot->m_NumItems * sizeof(int) * 2 > CSnapshot::MAX_SIZE || pSnapshot->m_NumItems > CSnapshot::MAX_ITEMS)
|
||||
{
|
||||
// key and offset per item
|
||||
dbg_assert(m_DataSize + sizeof(CSnapshot) + m_NumItems * sizeof(int) * 2 < CSnapshot::MAX_SIZE, "too much data");
|
||||
dbg_assert(m_NumItems < CSnapshot::MAX_ITEMS, "too many items");
|
||||
dbg_msg("sixup", "demo recording failed on invalid snapshot");
|
||||
m_DataSize = 0;
|
||||
m_NumItems = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
m_DataSize = pSnapshot->m_DataSize;
|
||||
m_NumItems = pSnapshot->m_NumItems;
|
||||
mem_copy(m_aOffsets, pSnapshot->Offsets(), sizeof(int) * m_NumItems);
|
||||
|
|
|
@ -135,8 +135,15 @@ void CSnapshot::DebugDump() const
|
|||
bool CSnapshot::IsValid(size_t ActualSize) const
|
||||
{
|
||||
// validate total size
|
||||
if(ActualSize < sizeof(CSnapshot) || m_NumItems < 0 || m_DataSize < 0 || ActualSize != TotalSize())
|
||||
if(ActualSize < sizeof(CSnapshot) ||
|
||||
ActualSize > MAX_SIZE ||
|
||||
m_NumItems < 0 ||
|
||||
m_NumItems > MAX_ITEMS ||
|
||||
m_DataSize < 0 ||
|
||||
ActualSize != TotalSize())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// validate item offsets
|
||||
const int *pOffsets = Offsets();
|
||||
|
@ -735,8 +742,11 @@ int *CSnapshotBuilder::GetItemData(int Key)
|
|||
{
|
||||
for(int i = 0; i < m_NumItems; i++)
|
||||
{
|
||||
if(GetItem(i)->Key() == Key)
|
||||
return GetItem(i)->Data();
|
||||
CSnapshotItem *pItem = GetItem(i);
|
||||
if(pItem->Key() == Key)
|
||||
{
|
||||
return pItem->Data();
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -744,12 +754,15 @@ int *CSnapshotBuilder::GetItemData(int Key)
|
|||
int CSnapshotBuilder::Finish(void *pSnapData)
|
||||
{
|
||||
// flatten and make the snapshot
|
||||
dbg_assert(m_NumItems <= CSnapshot::MAX_ITEMS, "Too many snap items");
|
||||
CSnapshot *pSnap = (CSnapshot *)pSnapData;
|
||||
pSnap->m_DataSize = m_DataSize;
|
||||
pSnap->m_NumItems = m_NumItems;
|
||||
const size_t TotalSize = pSnap->TotalSize();
|
||||
dbg_assert(TotalSize <= (size_t)CSnapshot::MAX_SIZE, "Snapshot too large");
|
||||
mem_copy(pSnap->Offsets(), m_aOffsets, pSnap->OffsetSize());
|
||||
mem_copy(pSnap->DataStart(), m_aData, m_DataSize);
|
||||
return pSnap->TotalSize();
|
||||
return TotalSize;
|
||||
}
|
||||
|
||||
int CSnapshotBuilder::GetTypeFromIndex(int Index) const
|
||||
|
@ -757,17 +770,22 @@ int CSnapshotBuilder::GetTypeFromIndex(int Index) const
|
|||
return CSnapshot::MAX_TYPE - Index;
|
||||
}
|
||||
|
||||
void CSnapshotBuilder::AddExtendedItemType(int Index)
|
||||
bool CSnapshotBuilder::AddExtendedItemType(int Index)
|
||||
{
|
||||
dbg_assert(0 <= Index && Index < m_NumExtendedItemTypes, "index out of range");
|
||||
int TypeId = m_aExtendedItemTypes[Index];
|
||||
CUuid Uuid = g_UuidManager.GetUuid(TypeId);
|
||||
int *pUuidItem = (int *)NewItem(0, GetTypeFromIndex(Index), sizeof(Uuid)); // NETOBJTYPE_EX
|
||||
if(pUuidItem)
|
||||
int *pUuidItem = static_cast<int *>(NewItem(0, GetTypeFromIndex(Index), sizeof(CUuid))); // NETOBJTYPE_EX
|
||||
if(pUuidItem == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const int TypeId = m_aExtendedItemTypes[Index];
|
||||
const CUuid Uuid = g_UuidManager.GetUuid(TypeId);
|
||||
for(size_t i = 0; i < sizeof(CUuid) / sizeof(int32_t); i++)
|
||||
{
|
||||
pUuidItem[i] = bytes_be_to_uint(&Uuid.m_aData[i * sizeof(int32_t)]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int CSnapshotBuilder::GetExtendedItemTypeIndex(int TypeId)
|
||||
|
@ -783,9 +801,13 @@ int CSnapshotBuilder::GetExtendedItemTypeIndex(int TypeId)
|
|||
int Index = m_NumExtendedItemTypes;
|
||||
m_NumExtendedItemTypes++;
|
||||
m_aExtendedItemTypes[Index] = TypeId;
|
||||
AddExtendedItemType(Index);
|
||||
if(AddExtendedItemType(Index))
|
||||
{
|
||||
return Index;
|
||||
}
|
||||
m_NumExtendedItemTypes--;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void *CSnapshotBuilder::NewItem(int Type, int Id, int Size)
|
||||
{
|
||||
|
@ -794,19 +816,27 @@ void *CSnapshotBuilder::NewItem(int Type, int Id, int Size)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
if(m_DataSize + sizeof(CSnapshotItem) + Size >= CSnapshot::MAX_SIZE ||
|
||||
m_NumItems + 1 >= CSnapshot::MAX_ITEMS)
|
||||
if(m_NumItems >= CSnapshot::MAX_ITEMS)
|
||||
{
|
||||
dbg_assert(m_DataSize < CSnapshot::MAX_SIZE, "too much data");
|
||||
dbg_assert(m_NumItems < CSnapshot::MAX_ITEMS, "too many items");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool Extended = false;
|
||||
if(Type >= OFFSET_UUID)
|
||||
const size_t OffsetSize = (m_NumItems + 1) * sizeof(int);
|
||||
const size_t ItemSize = sizeof(CSnapshotItem) + Size;
|
||||
if(sizeof(CSnapshot) + OffsetSize + m_DataSize + ItemSize > CSnapshot::MAX_SIZE)
|
||||
{
|
||||
Extended = true;
|
||||
Type = GetTypeFromIndex(GetExtendedItemTypeIndex(Type));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const bool Extended = Type >= OFFSET_UUID;
|
||||
if(Extended)
|
||||
{
|
||||
const int ExtendedItemTypeIndex = GetExtendedItemTypeIndex(Type);
|
||||
if(ExtendedItemTypeIndex == -1)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
Type = GetTypeFromIndex(ExtendedItemTypeIndex);
|
||||
}
|
||||
|
||||
CSnapshotItem *pObj = (CSnapshotItem *)(m_aData + m_DataSize);
|
||||
|
@ -824,11 +854,11 @@ void *CSnapshotBuilder::NewItem(int Type, int Id, int Size)
|
|||
else if(Type < 0)
|
||||
return nullptr;
|
||||
|
||||
mem_zero(pObj, sizeof(CSnapshotItem) + Size);
|
||||
pObj->m_TypeAndId = (Type << 16) | Id;
|
||||
m_aOffsets[m_NumItems] = m_DataSize;
|
||||
m_DataSize += sizeof(CSnapshotItem) + Size;
|
||||
m_DataSize += ItemSize;
|
||||
m_NumItems++;
|
||||
|
||||
mem_zero(pObj->Data(), Size);
|
||||
return pObj->Data();
|
||||
}
|
||||
|
|
|
@ -158,7 +158,7 @@ class CSnapshotBuilder
|
|||
int m_aExtendedItemTypes[MAX_EXTENDED_ITEM_TYPES];
|
||||
int m_NumExtendedItemTypes;
|
||||
|
||||
void AddExtendedItemType(int Index);
|
||||
bool AddExtendedItemType(int Index);
|
||||
int GetExtendedItemTypeIndex(int TypeId);
|
||||
int GetTypeFromIndex(int Index) const;
|
||||
|
||||
|
|
Loading…
Reference in a new issue