From 4f4e2154cd9bb788186e4985104b58c4a5ee3d72 Mon Sep 17 00:00:00 2001 From: Ladislav Zezula Date: Sun, 20 Apr 2025 21:16:05 +0200 Subject: Added check for loading CRC table --- src/SBaseCommon.cpp | 9 ++++++++- src/SBaseFileTable.cpp | 5 ----- src/SFileReadFile.cpp | 4 ++-- test/StormTest.cpp | 3 ++- test/stormlib-test-001.txt | 2 ++ 5 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/SBaseCommon.cpp b/src/SBaseCommon.cpp index ecbfc05..3284bb7 100644 --- a/src/SBaseCommon.cpp +++ b/src/SBaseCommon.cpp @@ -1026,12 +1026,19 @@ void * LoadMpqTable( // and the table is loaded from the current file offset if(ByteOffset == SFILE_INVALID_POS) FileStream_GetPos(ha->pStream, &ByteOffset); + FileStream_GetSize(ha->pStream, &FileSize); + + // Is the sector table within the file? + if(ByteOffset >= FileSize) + { + STORM_FREE(pbMpqTable); + return NULL; + } // The hash table and block table can go beyond EOF. // Storm.dll reads as much as possible, then fills the missing part with zeros. // Abused by Spazzler map protector which sets hash table size to 0x00100000 // Abused by NP_Protect in MPQs v4 as well - FileStream_GetSize(ha->pStream, &FileSize); if((ByteOffset + dwBytesToRead) > FileSize) { // Fill the extra data with zeros diff --git a/src/SBaseFileTable.cpp b/src/SBaseFileTable.cpp index 843f81e..0461be2 100644 --- a/src/SBaseFileTable.cpp +++ b/src/SBaseFileTable.cpp @@ -2560,12 +2560,7 @@ DWORD LoadAnyHashTable(TMPQArchive * ha) // Note that we load the classic hash table even when HET table exists, // because if the MPQ gets modified and saved, hash table must be there if(pHeader->dwHashTableSize) - { - // hash-table size must be a power or 2 - if ((pHeader->dwHashTableSize & (pHeader->dwHashTableSize - 1)) != 0) - return ERROR_FILE_CORRUPT; ha->pHashTable = LoadHashTable(ha); - } // At least one of the tables must be present if(ha->pHetTable == NULL && ha->pHashTable == NULL) diff --git a/src/SFileReadFile.cpp b/src/SFileReadFile.cpp index 180d428..1e990aa 100644 --- a/src/SFileReadFile.cpp +++ b/src/SFileReadFile.cpp @@ -73,8 +73,8 @@ static DWORD ReadMpqSectors(TMPQFile * hf, LPBYTE pbBuffer, DWORD dwByteOffset, // or not, we won't try that again for the given file. // - AllocateSectorChecksums(hf, true); - hf->bLoadedSectorCRCs = true; + if(AllocateSectorChecksums(hf, true) == ERROR_SUCCESS) + hf->bLoadedSectorCRCs = true; } // TODO: If the raw data MD5s are not loaded yet, load them now diff --git a/test/StormTest.cpp b/test/StormTest.cpp index 5a442a5..ad6ab6b 100755 --- a/test/StormTest.cpp +++ b/test/StormTest.cpp @@ -4138,7 +4138,7 @@ static const TEST_INFO1 TestList_MasterMirror[] = static const TEST_INFO1 Test_OpenMpqs[] = { - // PoC's by Gabe Sherman from FuturesLab + // PoC's by Gabe Sherman, tinh0. {_T("pocs/MPQ_2024_01_HeapOverrun.mpq"), NULL, "7008f95dcbc4e5d840830c176dec6969", 14}, {_T("pocs/MPQ_2024_02_StackOverflow.mpq"), NULL, "7093fcbcc9674b3e152e74e8e8a937bb", 4}, {_T("pocs/MPQ_2024_03_TooBigAlloc.mpq"), NULL, "--------------------------------", TFLG_WILL_FAIL}, @@ -4151,6 +4151,7 @@ static const TEST_INFO1 Test_OpenMpqs[] = {_T("pocs/MPQ_2024_10_HuffDecompressError.mpq"), NULL, "--------------------------------", TFLG_WILL_FAIL}, {_T("pocs/MPQ_2024_10_SparseDecompressError.mpq"), NULL, "--------------------------------", TFLG_WILL_FAIL}, {_T("pocs/MPQ_2024_11_HiBlockTablePosInvalid.mpq"), NULL, "--------------------------------", TFLG_WILL_FAIL}, + {_T("pocs/MPQ_2025_01_SectorTableBeyondEOF.mpq"), NULL, "--------------------------------", TFLG_WILL_FAIL}, // Correct or damaged archives {_T("MPQ_1997_v1_Diablo1_DIABDAT.MPQ"), NULL, "554b538541e42170ed41cb236483489e", 2910, &TwoFilesD1}, // Base MPQ from Diablo 1 diff --git a/test/stormlib-test-001.txt b/test/stormlib-test-001.txt index a1b2449..d2610ae 100644 --- a/test/stormlib-test-001.txt +++ b/test/stormlib-test-001.txt @@ -28,6 +28,8 @@ TestReadingMpq (pocs/MPQ_2024_09_InvalidSectorSize.mpq) succeeded. TestReadingMpq (pocs/MPQ_2024_10_HuffDecompressError.mpq) succeeded. TestReadingMpq (pocs/MPQ_2024_10_SparseDecompressError.mpq) succeeded. TestReadingMpq (pocs/MPQ_2024_11_HiBlockTablePosInvalid.mpq) succeeded. +TestReadingMpq: Error loading the file (listfile) (error code: 38) +TestReadingMpq (pocs/MPQ_2025_01_SectorTableBeyondEOF.mpq) succeeded. TestReadingMpq (MPQ_1997_v1_Diablo1_DIABDAT.MPQ) succeeded. TestReadingMpq (MPQ_1997_v1_patch_rt_SC1B.mpq) succeeded. TestReadingMpq (MPQ_1997_v1_StarDat_SC1B.mpq) succeeded. -- cgit v1.2.3