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)
|
if(DemoSnapSize < 0)
|
||||||
{
|
{
|
||||||
dbg_msg("sixup", "demo snapshot failed. error=%d", DemoSnapSize);
|
dbg_msg("sixup", "demo snapshot failed. error=%d", DemoSnapSize);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(DemoSnapSize >= 0)
|
||||||
|
{
|
||||||
// add snapshot to demo
|
// add snapshot to demo
|
||||||
for(auto &DemoRecorder : m_aDemoRecorder)
|
for(auto &DemoRecorder : m_aDemoRecorder)
|
||||||
{
|
{
|
||||||
|
@ -2020,6 +2021,7 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket, int Conn, bool Dummy)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// apply snapshot, cycle pointers
|
// apply snapshot, cycle pointers
|
||||||
m_aReceivedSnapshots[Conn]++;
|
m_aReceivedSnapshots[Conn]++;
|
||||||
|
|
|
@ -8,17 +8,6 @@ void CSnapshotBuilder::Init7(const CSnapshot *pSnapshot)
|
||||||
// but the snap we are building is a 0.6 snap
|
// but the snap we are building is a 0.6 snap
|
||||||
m_Sixup = false;
|
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_DataSize = pSnapshot->m_DataSize;
|
||||||
m_NumItems = pSnapshot->m_NumItems;
|
m_NumItems = pSnapshot->m_NumItems;
|
||||||
mem_copy(m_aOffsets, pSnapshot->Offsets(), sizeof(int) * 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
|
bool CSnapshot::IsValid(size_t ActualSize) const
|
||||||
{
|
{
|
||||||
// validate total size
|
// 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;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// validate item offsets
|
// validate item offsets
|
||||||
const int *pOffsets = Offsets();
|
const int *pOffsets = Offsets();
|
||||||
|
@ -735,8 +742,11 @@ int *CSnapshotBuilder::GetItemData(int Key)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < m_NumItems; i++)
|
for(int i = 0; i < m_NumItems; i++)
|
||||||
{
|
{
|
||||||
if(GetItem(i)->Key() == Key)
|
CSnapshotItem *pItem = GetItem(i);
|
||||||
return GetItem(i)->Data();
|
if(pItem->Key() == Key)
|
||||||
|
{
|
||||||
|
return pItem->Data();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -744,12 +754,15 @@ int *CSnapshotBuilder::GetItemData(int Key)
|
||||||
int CSnapshotBuilder::Finish(void *pSnapData)
|
int CSnapshotBuilder::Finish(void *pSnapData)
|
||||||
{
|
{
|
||||||
// flatten and make the snapshot
|
// flatten and make the snapshot
|
||||||
|
dbg_assert(m_NumItems <= CSnapshot::MAX_ITEMS, "Too many snap items");
|
||||||
CSnapshot *pSnap = (CSnapshot *)pSnapData;
|
CSnapshot *pSnap = (CSnapshot *)pSnapData;
|
||||||
pSnap->m_DataSize = m_DataSize;
|
pSnap->m_DataSize = m_DataSize;
|
||||||
pSnap->m_NumItems = m_NumItems;
|
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->Offsets(), m_aOffsets, pSnap->OffsetSize());
|
||||||
mem_copy(pSnap->DataStart(), m_aData, m_DataSize);
|
mem_copy(pSnap->DataStart(), m_aData, m_DataSize);
|
||||||
return pSnap->TotalSize();
|
return TotalSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CSnapshotBuilder::GetTypeFromIndex(int Index) const
|
int CSnapshotBuilder::GetTypeFromIndex(int Index) const
|
||||||
|
@ -757,17 +770,22 @@ int CSnapshotBuilder::GetTypeFromIndex(int Index) const
|
||||||
return CSnapshot::MAX_TYPE - Index;
|
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");
|
dbg_assert(0 <= Index && Index < m_NumExtendedItemTypes, "index out of range");
|
||||||
int TypeId = m_aExtendedItemTypes[Index];
|
int *pUuidItem = static_cast<int *>(NewItem(0, GetTypeFromIndex(Index), sizeof(CUuid))); // NETOBJTYPE_EX
|
||||||
CUuid Uuid = g_UuidManager.GetUuid(TypeId);
|
if(pUuidItem == nullptr)
|
||||||
int *pUuidItem = (int *)NewItem(0, GetTypeFromIndex(Index), sizeof(Uuid)); // NETOBJTYPE_EX
|
|
||||||
if(pUuidItem)
|
|
||||||
{
|
{
|
||||||
|
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++)
|
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)]);
|
pUuidItem[i] = bytes_be_to_uint(&Uuid.m_aData[i * sizeof(int32_t)]);
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CSnapshotBuilder::GetExtendedItemTypeIndex(int TypeId)
|
int CSnapshotBuilder::GetExtendedItemTypeIndex(int TypeId)
|
||||||
|
@ -783,8 +801,12 @@ int CSnapshotBuilder::GetExtendedItemTypeIndex(int TypeId)
|
||||||
int Index = m_NumExtendedItemTypes;
|
int Index = m_NumExtendedItemTypes;
|
||||||
m_NumExtendedItemTypes++;
|
m_NumExtendedItemTypes++;
|
||||||
m_aExtendedItemTypes[Index] = TypeId;
|
m_aExtendedItemTypes[Index] = TypeId;
|
||||||
AddExtendedItemType(Index);
|
if(AddExtendedItemType(Index))
|
||||||
|
{
|
||||||
return Index;
|
return Index;
|
||||||
|
}
|
||||||
|
m_NumExtendedItemTypes--;
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *CSnapshotBuilder::NewItem(int Type, int Id, int Size)
|
void *CSnapshotBuilder::NewItem(int Type, int Id, int Size)
|
||||||
|
@ -794,19 +816,27 @@ void *CSnapshotBuilder::NewItem(int Type, int Id, int Size)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_DataSize + sizeof(CSnapshotItem) + Size >= CSnapshot::MAX_SIZE ||
|
if(m_NumItems >= CSnapshot::MAX_ITEMS)
|
||||||
m_NumItems + 1 >= 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;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Extended = false;
|
const size_t OffsetSize = (m_NumItems + 1) * sizeof(int);
|
||||||
if(Type >= OFFSET_UUID)
|
const size_t ItemSize = sizeof(CSnapshotItem) + Size;
|
||||||
|
if(sizeof(CSnapshot) + OffsetSize + m_DataSize + ItemSize > CSnapshot::MAX_SIZE)
|
||||||
{
|
{
|
||||||
Extended = true;
|
return nullptr;
|
||||||
Type = GetTypeFromIndex(GetExtendedItemTypeIndex(Type));
|
}
|
||||||
|
|
||||||
|
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);
|
CSnapshotItem *pObj = (CSnapshotItem *)(m_aData + m_DataSize);
|
||||||
|
@ -824,11 +854,11 @@ void *CSnapshotBuilder::NewItem(int Type, int Id, int Size)
|
||||||
else if(Type < 0)
|
else if(Type < 0)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
mem_zero(pObj, sizeof(CSnapshotItem) + Size);
|
|
||||||
pObj->m_TypeAndId = (Type << 16) | Id;
|
pObj->m_TypeAndId = (Type << 16) | Id;
|
||||||
m_aOffsets[m_NumItems] = m_DataSize;
|
m_aOffsets[m_NumItems] = m_DataSize;
|
||||||
m_DataSize += sizeof(CSnapshotItem) + Size;
|
m_DataSize += ItemSize;
|
||||||
m_NumItems++;
|
m_NumItems++;
|
||||||
|
|
||||||
|
mem_zero(pObj->Data(), Size);
|
||||||
return pObj->Data();
|
return pObj->Data();
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,7 +158,7 @@ class CSnapshotBuilder
|
||||||
int m_aExtendedItemTypes[MAX_EXTENDED_ITEM_TYPES];
|
int m_aExtendedItemTypes[MAX_EXTENDED_ITEM_TYPES];
|
||||||
int m_NumExtendedItemTypes;
|
int m_NumExtendedItemTypes;
|
||||||
|
|
||||||
void AddExtendedItemType(int Index);
|
bool AddExtendedItemType(int Index);
|
||||||
int GetExtendedItemTypeIndex(int TypeId);
|
int GetExtendedItemTypeIndex(int TypeId);
|
||||||
int GetTypeFromIndex(int Index) const;
|
int GetTypeFromIndex(int Index) const;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue