From c9620d7824e58bdc79a0fde09003ec047b1af3f6 Mon Sep 17 00:00:00 2001 From: Ladislav Zezula Date: Tue, 22 Apr 2025 22:40:25 +0200 Subject: Fixed more bugs from POCs --- src/SBaseCommon.cpp | 7 ++++-- src/SBaseFileTable.cpp | 4 ++-- src/SFileReadFile.cpp | 2 +- test/StormTest.cpp | 56 +++++++++++++++++++++++++++++++++++++++++++--- test/TLogHelper.cpp | 13 ++++++----- test/stormlib-test-001.txt | 6 +++++ 6 files changed, 74 insertions(+), 14 deletions(-) diff --git a/src/SBaseCommon.cpp b/src/SBaseCommon.cpp index 3284bb7..0d9598a 100644 --- a/src/SBaseCommon.cpp +++ b/src/SBaseCommon.cpp @@ -1365,14 +1365,17 @@ DWORD AllocateSectorOffsets(TMPQFile * hf, bool bLoadFromFile) if((hf->SectorOffsets[0] & 0xFFFFFFFC) > dwSectorOffsLen) { // MPQ protectors put some ridiculous values there. We must limit the extra bytes - if(hf->SectorOffsets[0] > (dwSectorOffsLen + 0x400)) { + if(hf->SectorOffsets[0] > (dwSectorOffsLen + 0x400)) + { STORM_FREE(hf->SectorOffsets); hf->SectorOffsets = NULL; return ERROR_FILE_CORRUPT; } + // The new length of the sector offset must be aligned to DWORD + dwSectorOffsLen = (hf->SectorOffsets[0] & 0xFFFFFFFC); + // Free the old sector offset table - dwSectorOffsLen = hf->SectorOffsets[0]; STORM_FREE(hf->SectorOffsets); goto __LoadSectorOffsets; } diff --git a/src/SBaseFileTable.cpp b/src/SBaseFileTable.cpp index 0461be2..d2d5bc3 100644 --- a/src/SBaseFileTable.cpp +++ b/src/SBaseFileTable.cpp @@ -651,7 +651,7 @@ DWORD ConvertMpqHeaderToFormat4( // Size of the block table if(BlockTablePos64) { - if(BlockTablePos64 > FileSize) + if(BlockTablePos64 > FileSize || BlockTablePos64 >= MaxOffset) return ERROR_FILE_CORRUPT; pHeader->BlockTableSize64 = MaxOffset - BlockTablePos64; MaxOffset = BlockTablePos64; @@ -660,7 +660,7 @@ DWORD ConvertMpqHeaderToFormat4( // Size of the hash table if(HashTablePos64) { - if(HashTablePos64 > FileSize) + if(HashTablePos64 > FileSize || HashTablePos64 >= MaxOffset) return ERROR_FILE_CORRUPT; pHeader->HashTableSize64 = MaxOffset - HashTablePos64; MaxOffset = HashTablePos64; diff --git a/src/SFileReadFile.cpp b/src/SFileReadFile.cpp index 1e990aa..f2c17ba 100644 --- a/src/SFileReadFile.cpp +++ b/src/SFileReadFile.cpp @@ -310,7 +310,7 @@ static DWORD ReadMpqFileSingleUnit(TMPQFile * hf, void * pvBuffer, DWORD dwFileP // deDE\DBFilesClient\MountCapability.dbc 0x93->0x77 0x77 0x77 No // - if(pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE) + if(pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE && cbInBuffer > sizeof(TPatchInfo)) cbInBuffer = cbInBuffer - sizeof(TPatchInfo); // Is the file compressed by Blizzard's multiple compression ? diff --git a/test/StormTest.cpp b/test/StormTest.cpp index ad6ab6b..686fbbb 100755 --- a/test/StormTest.cpp +++ b/test/StormTest.cpp @@ -3864,9 +3864,54 @@ static DWORD TestUtf8Conversions(const BYTE * szTestString, const TCHAR * szList static void Test_PlayingSpace() { - HANDLE hFile = NULL; - HANDLE hMpq = NULL; - +/* + LPCSTR fuzzData = "e:\\MPQ_2025_05_AddFileError.mpq"; + + HANDLE SFileOpenArchivevar0; + memset(&SFileOpenArchivevar0, 0, (sizeof SFileOpenArchivevar0)); + + bool SFileOpenArchiveval1 = SFileOpenArchive(fuzzData, (DWORD)strlen(fuzzData), 0, &SFileOpenArchivevar0); + //if(strcmp(argv[1], fuzzData)) + //{ + // fprintf(stderr, "err1"); + // exit(0); + //} + printf("Test"); + if((size_t)SFileOpenArchiveval1 < 1) + { + fprintf(stderr, "err2"); + exit(0); + } + bool SFileAddWaveval1 = SFileAddWave(SFileOpenArchivevar0, fuzzData, fuzzData, (DWORD)strlen(fuzzData), 1); + //if(strcmp(argv[1], fuzzData)) + //{ + // fprintf(stderr, "err3"); + // exit(0); + //} + if((size_t)SFileAddWaveval1 < 1) + { + fprintf(stderr, "err4"); + exit(0); + } + bool SFileRemoveFileval1 = SFileRemoveFile(SFileOpenArchivevar0, fuzzData, (DWORD)_tcslen(fuzzData)); + //if(strcmp(argv[1], fuzzData)) + //{ + // fprintf(stderr, "err5"); + // exit(0); + //} + if((size_t)SFileRemoveFileval1 < 1) + { + fprintf(stderr, "err6"); + exit(0); + } + DWORD SFileVerifyArchiveval1 = SFileVerifyArchive(SFileOpenArchivevar0); + if(SFileVerifyArchiveval1 < 0) + { + fprintf(stderr, "err7"); + exit(0); + } + */ +/* if(SFileOpenArchive(_T("E:\\DIABDAT.MPQ"), 0, 0, &hMpq)) { if(SFileOpenFileEx(hMpq, "d1221a.mpq", 0, &hFile)) @@ -3879,6 +3924,7 @@ static void Test_PlayingSpace() } SFileCloseArchive(hMpq); } +*/ } //----------------------------------------------------------------------------- @@ -4152,6 +4198,10 @@ static const TEST_INFO1 Test_OpenMpqs[] = {_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}, + {_T("pocs/MPQ_2025_02_SectorOffsetSizeNotAligned.mpq"), NULL, "0cc175b9c0f1b6a831c399e269772661", TFLG_WILL_FAIL}, + {_T("pocs/MPQ_2025_03_InvalidPatchInfo.mpq"), NULL, "93b885adfe0da089cdf634904fd59f71", TFLG_WILL_FAIL}, + {_T("pocs/MPQ_2025_04_InvalidArchiveSize64.mpq"), NULL, "--------------------------------", TFLG_WILL_FAIL}, + {_T("pocs/MPQ_2025_05_AddFileError.mpq"), NULL, "ce9b8afed4221a53663d391f10691ba6", 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/TLogHelper.cpp b/test/TLogHelper.cpp index 6eb97f6..ad8a067 100644 --- a/test/TLogHelper.cpp +++ b/test/TLogHelper.cpp @@ -17,6 +17,7 @@ #endif #ifdef _MSC_VER +#define fmt_I64u_w L"%I64u" #define fmt_I64u_t _T("%I64u") #define fmt_I64u_a "%I64u" #define fmt_I64X_t _T("%I64X") @@ -65,25 +66,25 @@ inline DWORD Test_GetLastError() #ifdef STORMLIB_WINDOWS wchar_t * CopyFormatCharacter(wchar_t * szBuffer, const wchar_t *& szFormat) { - static const wchar_t * szStringFormat = _T("%s"); - static const wchar_t * szUint64Format = fmt_I64u_t; + static const wchar_t * szStringFormat = L"%s"; + static const wchar_t * szUint64Format = fmt_I64u_w; // String format if(szFormat[0] == '%') { if(szFormat[1] == 's') { - _tcscpy(szBuffer, szStringFormat); + wcscpy(szBuffer, szStringFormat); szFormat += 2; - return szBuffer + _tcslen(szStringFormat); + return szBuffer + wcslen(szStringFormat); } // Replace %I64u with the proper platform-dependent suffix if(szFormat[1] == 'I' && szFormat[2] == '6' && szFormat[3] == '4' && szFormat[4] == 'u') { - _tcscpy(szBuffer, szUint64Format); + wcscpy(szBuffer, szUint64Format); szFormat += 5; - return szBuffer + _tcslen(szUint64Format); + return szBuffer + wcslen(szUint64Format); } } diff --git a/test/stormlib-test-001.txt b/test/stormlib-test-001.txt index d2610ae..54ba71d 100644 --- a/test/stormlib-test-001.txt +++ b/test/stormlib-test-001.txt @@ -30,6 +30,12 @@ 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: Warning: CRC32 error on (listfile) +TestReadingMpq: Warning: CRC32 error on (listfile) +TestReadingMpq (pocs/MPQ_2025_02_SectorOffsetSizeNotAligned.mpq) succeeded. +TestReadingMpq (pocs/MPQ_2025_03_InvalidPatchInfo.mpq) succeeded. +TestReadingMpq (pocs/MPQ_2025_04_InvalidArchiveSize64.mpq) succeeded. +TestReadingMpq (pocs/MPQ_2025_05_AddFileError.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