Hopefully fix bug with some malformed maps that can make the client crash

This commit is contained in:
def 2014-01-11 00:46:32 +01:00
parent b768cb1e81
commit 4a3f75884e
6 changed files with 144 additions and 96 deletions

View file

@ -10,6 +10,7 @@ class IMap : public IInterface
MACRO_INTERFACE("map", 0) MACRO_INTERFACE("map", 0)
public: public:
virtual void *GetData(int Index) = 0; virtual void *GetData(int Index) = 0;
virtual int GetUncompressedDataSize(int Index) = 0;
virtual void *GetDataSwapped(int Index) = 0; virtual void *GetDataSwapped(int Index) = 0;
virtual void UnloadData(int Index) = 0; virtual void UnloadData(int Index) = 0;
virtual void *GetItem(int Index, int *Type, int *pID) = 0; virtual void *GetItem(int Index, int *Type, int *pID) = 0;

View file

@ -264,6 +264,17 @@ int CDataFileReader::GetDataSize(int Index)
return m_pDataFile->m_Info.m_pDataOffsets[Index+1]-m_pDataFile->m_Info.m_pDataOffsets[Index]; return m_pDataFile->m_Info.m_pDataOffsets[Index+1]-m_pDataFile->m_Info.m_pDataOffsets[Index];
} }
// always returns the size in the file
int CDataFileReader::GetUncompressedDataSize(int Index)
{
if(!m_pDataFile) { return 0; }
if(m_pDataFile->m_Header.m_Version == 4)
return m_pDataFile->m_Info.m_pDataSizes[Index];
else
return GetDataSize(Index);
}
void *CDataFileReader::GetDataImpl(int Index, int Swap) void *CDataFileReader::GetDataImpl(int Index, int Swap)
{ {
if(!m_pDataFile) { return 0; } if(!m_pDataFile) { return 0; }

View file

@ -22,6 +22,7 @@ public:
void *GetData(int Index); void *GetData(int Index);
void *GetDataSwapped(int Index); // makes sure that the data is 32bit LE ints when saved void *GetDataSwapped(int Index); // makes sure that the data is 32bit LE ints when saved
int GetDataSize(int Index); int GetDataSize(int Index);
int GetUncompressedDataSize(int Index);
void UnloadData(int Index); void UnloadData(int Index);
void *GetItem(int Index, int *pType, int *pID); void *GetItem(int Index, int *pType, int *pID);
int GetItemSize(int Index); int GetItemSize(int Index);

View file

@ -12,6 +12,7 @@ public:
CMap() {} CMap() {}
virtual void *GetData(int Index) { return m_DataFile.GetData(Index); } virtual void *GetData(int Index) { return m_DataFile.GetData(Index); }
virtual int GetUncompressedDataSize(int Index) { return m_DataFile.GetUncompressedDataSize(Index); }
virtual void *GetDataSwapped(int Index) { return m_DataFile.GetDataSwapped(Index); } virtual void *GetDataSwapped(int Index) { return m_DataFile.GetDataSwapped(Index); }
virtual void UnloadData(int Index) { m_DataFile.UnloadData(Index); } virtual void UnloadData(int Index) { m_DataFile.UnloadData(Index); }
virtual void *GetItem(int Index, int *pType, int *pID) { return m_DataFile.GetItem(Index, pType, pID); } virtual void *GetItem(int Index, int *pType, int *pID) { return m_DataFile.GetItem(Index, pType, pID); }

View file

@ -40,14 +40,25 @@ void CCollision::Init(class CLayers *pLayers)
m_pTiles = static_cast<CTile *>(m_pLayers->Map()->GetData(m_pLayers->GameLayer()->m_Data)); m_pTiles = static_cast<CTile *>(m_pLayers->Map()->GetData(m_pLayers->GameLayer()->m_Data));
if(m_pLayers->TeleLayer()) if(m_pLayers->TeleLayer())
{
int Size = m_pLayers->Map()->GetUncompressedDataSize(m_pLayers->TeleLayer()->m_Tele);
if (Size >= m_Width*m_Height*sizeof(CTeleTile))
m_pTele = static_cast<CTeleTile *>(m_pLayers->Map()->GetData(m_pLayers->TeleLayer()->m_Tele)); m_pTele = static_cast<CTeleTile *>(m_pLayers->Map()->GetData(m_pLayers->TeleLayer()->m_Tele));
}
if(m_pLayers->SpeedupLayer()) if(m_pLayers->SpeedupLayer())
{
int Size = m_pLayers->Map()->GetUncompressedDataSize(m_pLayers->SpeedupLayer()->m_Speedup);
if (Size >= m_Width*m_Height*sizeof(CSpeedupTile))
m_pSpeedup = static_cast<CSpeedupTile *>(m_pLayers->Map()->GetData(m_pLayers->SpeedupLayer()->m_Speedup)); m_pSpeedup = static_cast<CSpeedupTile *>(m_pLayers->Map()->GetData(m_pLayers->SpeedupLayer()->m_Speedup));
}
if(m_pLayers->SwitchLayer()) if(m_pLayers->SwitchLayer())
{ {
int Size = m_pLayers->Map()->GetUncompressedDataSize(m_pLayers->SwitchLayer()->m_Switch);
if (Size >= m_Width*m_Height*sizeof(CSwitchTile))
m_pSwitch = static_cast<CSwitchTile *>(m_pLayers->Map()->GetData(m_pLayers->SwitchLayer()->m_Switch)); m_pSwitch = static_cast<CSwitchTile *>(m_pLayers->Map()->GetData(m_pLayers->SwitchLayer()->m_Switch));
m_pDoor = new CDoorTile[m_Width*m_Height]; m_pDoor = new CDoorTile[m_Width*m_Height];
mem_zero(m_pDoor, m_Width * m_Height * sizeof(CDoorTile)); mem_zero(m_pDoor, m_Width * m_Height * sizeof(CDoorTile));
} }
@ -58,7 +69,11 @@ void CCollision::Init(class CLayers *pLayers)
} }
if(m_pLayers->FrontLayer()) if(m_pLayers->FrontLayer())
{
int Size = m_pLayers->Map()->GetUncompressedDataSize(m_pLayers->FrontLayer()->m_Front);
if (Size >= m_Width*m_Height*sizeof(CFrontTile))
m_pFront = static_cast<CTile *>(m_pLayers->Map()->GetData(m_pLayers->FrontLayer()->m_Front)); m_pFront = static_cast<CTile *>(m_pLayers->Map()->GetData(m_pLayers->FrontLayer()->m_Front));
}
for(int i = 0; i < m_Width*m_Height; i++) for(int i = 0; i < m_Width*m_Height; i++)
{ {

View file

@ -657,6 +657,7 @@ int CEditorMap::Load(class IStorage *pStorage, const char *pFileName, int Storag
pGroup->AddLayer(pTiles); pGroup->AddLayer(pTiles);
void *pData = DataFile.GetData(pTilemapItem->m_Data); void *pData = DataFile.GetData(pTilemapItem->m_Data);
int Size = DataFile.GetUncompressedDataSize(pTilemapItem->m_Data);
pTiles->m_Image = pTilemapItem->m_Image; pTiles->m_Image = pTilemapItem->m_Image;
pTiles->m_Game = pTilemapItem->m_Flags&TILESLAYERFLAG_GAME; pTiles->m_Game = pTilemapItem->m_Flags&TILESLAYERFLAG_GAME;
@ -664,6 +665,8 @@ int CEditorMap::Load(class IStorage *pStorage, const char *pFileName, int Storag
if(pTilemapItem->m_Version >= 3) if(pTilemapItem->m_Version >= 3)
IntsToStr(pTilemapItem->m_aName, sizeof(pTiles->m_aName)/sizeof(int), pTiles->m_aName); IntsToStr(pTilemapItem->m_aName, sizeof(pTiles->m_aName)/sizeof(int), pTiles->m_aName);
if (Size >= pTiles->m_Width*pTiles->m_Height*sizeof(CTile))
{
mem_copy(pTiles->m_pTiles, pData, pTiles->m_Width*pTiles->m_Height*sizeof(CTile)); mem_copy(pTiles->m_pTiles, pData, pTiles->m_Width*pTiles->m_Height*sizeof(CTile));
if(pTiles->m_Game && pTilemapItem->m_Version == MakeVersion(1, *pTilemapItem)) if(pTiles->m_Game && pTilemapItem->m_Version == MakeVersion(1, *pTilemapItem))
@ -674,12 +677,16 @@ int CEditorMap::Load(class IStorage *pStorage, const char *pFileName, int Storag
pTiles->m_pTiles[i].m_Index += ENTITY_OFFSET; pTiles->m_pTiles[i].m_Index += ENTITY_OFFSET;
} }
} }
}
DataFile.UnloadData(pTilemapItem->m_Data); DataFile.UnloadData(pTilemapItem->m_Data);
if(pTiles->m_Tele) if(pTiles->m_Tele)
{ {
void *pTeleData = DataFile.GetData(pTilemapItem->m_Tele); void *pTeleData = DataFile.GetData(pTilemapItem->m_Tele);
int Size = DataFile.GetUncompressedDataSize(pTilemapItem->m_Tele);
if (Size >= pTiles->m_Width*pTiles->m_Height*sizeof(CTeleTile))
{
mem_copy(((CLayerTele*)pTiles)->m_pTeleTile, pTeleData, pTiles->m_Width*pTiles->m_Height*sizeof(CTeleTile)); mem_copy(((CLayerTele*)pTiles)->m_pTeleTile, pTeleData, pTiles->m_Width*pTiles->m_Height*sizeof(CTeleTile));
for(int i = 0; i < pTiles->m_Width*pTiles->m_Height; i++) for(int i = 0; i < pTiles->m_Width*pTiles->m_Height; i++)
@ -703,11 +710,16 @@ int CEditorMap::Load(class IStorage *pStorage, const char *pFileName, int Storag
else else
((CLayerTiles*)pTiles)->m_pTiles[i].m_Index = 0; ((CLayerTiles*)pTiles)->m_pTiles[i].m_Index = 0;
} }
}
DataFile.UnloadData(pTilemapItem->m_Tele); DataFile.UnloadData(pTilemapItem->m_Tele);
} }
else if(pTiles->m_Speedup) else if(pTiles->m_Speedup)
{ {
void *pSpeedupData = DataFile.GetData(pTilemapItem->m_Speedup); void *pSpeedupData = DataFile.GetData(pTilemapItem->m_Speedup);
int Size = DataFile.GetUncompressedDataSize(pTilemapItem->m_Speedup);
if (Size >= pTiles->m_Width*pTiles->m_Height*sizeof(CSpeedupTile))
{
mem_copy(((CLayerSpeedup*)pTiles)->m_pSpeedupTile, pSpeedupData, pTiles->m_Width*pTiles->m_Height*sizeof(CSpeedupTile)); mem_copy(((CLayerSpeedup*)pTiles)->m_pSpeedupTile, pSpeedupData, pTiles->m_Width*pTiles->m_Height*sizeof(CSpeedupTile));
for(int i = 0; i < pTiles->m_Width*pTiles->m_Height; i++) for(int i = 0; i < pTiles->m_Width*pTiles->m_Height; i++)
@ -717,12 +729,15 @@ int CEditorMap::Load(class IStorage *pStorage, const char *pFileName, int Storag
else else
((CLayerTiles*)pTiles)->m_pTiles[i].m_Index = 0; ((CLayerTiles*)pTiles)->m_pTiles[i].m_Index = 0;
} }
}
DataFile.UnloadData(pTilemapItem->m_Speedup); DataFile.UnloadData(pTilemapItem->m_Speedup);
} }
else if(pTiles->m_Front) else if(pTiles->m_Front)
{ {
void *pFrontData = DataFile.GetData(pTilemapItem->m_Front); void *pFrontData = DataFile.GetData(pTilemapItem->m_Front);
int Size = DataFile.GetUncompressedDataSize(pTilemapItem->m_Front);
if (Size >= pTiles->m_Width*pTiles->m_Height*sizeof(CTile))
mem_copy(((CLayerFront*)pTiles)->m_pTiles, pFrontData, pTiles->m_Width*pTiles->m_Height*sizeof(CTile)); mem_copy(((CLayerFront*)pTiles)->m_pTiles, pFrontData, pTiles->m_Width*pTiles->m_Height*sizeof(CTile));
DataFile.UnloadData(pTilemapItem->m_Front); DataFile.UnloadData(pTilemapItem->m_Front);
@ -730,6 +745,9 @@ int CEditorMap::Load(class IStorage *pStorage, const char *pFileName, int Storag
else if(pTiles->m_Switch) else if(pTiles->m_Switch)
{ {
void *pSwitchData = DataFile.GetData(pTilemapItem->m_Switch); void *pSwitchData = DataFile.GetData(pTilemapItem->m_Switch);
int Size = DataFile.GetUncompressedDataSize(pTilemapItem->m_Switch);
if (Size >= pTiles->m_Width*pTiles->m_Height*sizeof(CSwitchTile))
{
mem_copy(((CLayerSwitch*)pTiles)->m_pSwitchTile, pSwitchData, pTiles->m_Width*pTiles->m_Height*sizeof(CSwitchTile)); mem_copy(((CLayerSwitch*)pTiles)->m_pSwitchTile, pSwitchData, pTiles->m_Width*pTiles->m_Height*sizeof(CSwitchTile));
for(int i = 0; i < pTiles->m_Width*pTiles->m_Height; i++) for(int i = 0; i < pTiles->m_Width*pTiles->m_Height; i++)
@ -792,6 +810,7 @@ int CEditorMap::Load(class IStorage *pStorage, const char *pFileName, int Storag
((CLayerTiles*)pTiles)->m_pTiles[i].m_Flags = ((CLayerSwitch*)pTiles)->m_pSwitchTile[i].m_Flags; ((CLayerTiles*)pTiles)->m_pTiles[i].m_Flags = ((CLayerSwitch*)pTiles)->m_pSwitchTile[i].m_Flags;
} }
} }
}
DataFile.UnloadData(pTilemapItem->m_Switch); DataFile.UnloadData(pTilemapItem->m_Switch);
} }
} }