From ce074eaf7ace51fdb642f491e217d4f50e30150e Mon Sep 17 00:00:00 2001 From: Ladislav Zezula Date: Fri, 2 Jul 2021 23:53:06 +0200 Subject: Fixed infinite loop in BZIP decompression --- src/SCompression.cpp | 47 +++++++++++++++-------------------------------- test/StormTest.cpp | 9 +++++++++ 2 files changed, 24 insertions(+), 32 deletions(-) diff --git a/src/SCompression.cpp b/src/SCompression.cpp index 93f80e1..df4ee16 100644 --- a/src/SCompression.cpp +++ b/src/SCompression.cpp @@ -168,14 +168,15 @@ int Decompress_ZLIB(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, i z.zfree = NULL; // Initialize the decompression structure. Storm.dll uses zlib version 1.1.3 - if((nResult = inflateInit(&z)) == 0) + if((nResult = inflateInit(&z)) == Z_OK) { // Call zlib to decompress the data nResult = inflate(&z, Z_FINISH); *pcbOutBuffer = z.total_out; inflateEnd(&z); } - return nResult; + + return (nResult == Z_OK); } /******************************************************************************/ @@ -357,45 +358,27 @@ static void Compress_BZIP2(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBu static int Decompress_BZIP2(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer) { bz_stream strm; - int nResult = BZ_OK; + int nResult; // Initialize the BZIP2 decompression - strm.bzalloc = NULL; - strm.bzfree = NULL; - strm.opaque = NULL; + strm.next_in = (char *)pvInBuffer; + strm.avail_in = cbInBuffer; + strm.next_out = (char *)pvOutBuffer; + strm.avail_out = *pcbOutBuffer; + strm.bzalloc = NULL; + strm.bzfree = NULL; + strm.opaque = NULL; // Initialize decompression - if(BZ2_bzDecompressInit(&strm, 0, 0) == BZ_OK) + if((nResult = BZ2_bzDecompressInit(&strm, 0, 0)) == BZ_OK) { - strm.next_in = (char *)pvInBuffer; - strm.avail_in = cbInBuffer; - strm.next_out = (char *)pvOutBuffer; - strm.avail_out = *pcbOutBuffer; - // Perform the decompression - while(nResult != BZ_STREAM_END) - { - nResult = BZ2_bzDecompress(&strm); - - // If any error there, break the loop - if(nResult < BZ_OK) - break; - } - - // Put the stream into idle state + nResult = BZ2_bzDecompress(&strm); + *pcbOutBuffer = strm.total_out_lo32; BZ2_bzDecompressEnd(&strm); - - // If all succeeded, set the number of output bytes - if(nResult >= BZ_OK) - { - *pcbOutBuffer = strm.total_out_lo32; - return 1; - } } - // Something failed, so set number of output bytes to zero - *pcbOutBuffer = 0; - return 1; + return (nResult >= BZ_OK); } /******************************************************************************/ diff --git a/test/StormTest.cpp b/test/StormTest.cpp index 5b32dc1..8786b06 100644 --- a/test/StormTest.cpp +++ b/test/StormTest.cpp @@ -342,6 +342,8 @@ static bool IsMpqExtension(LPCTSTR szFileName) return true; if(!_tcsicmp(szExtension, _T(".SC2Mod"))) return true; + if(!_tcsicmp(szExtension, _T(".SC2Replay"))) + return true; if(!_tcsicmp(szExtension, _T(".0"))) // .MPQ.0 return true; // if(!_tcsicmp(szExtension, ".link")) @@ -1522,6 +1524,9 @@ static TFileData * LoadMpqFile(TLogHelper * pLogger, HANDLE hMpq, LPCSTR szFileN // Load the entire file if(dwErrCode == ERROR_SUCCESS) { + if(!stricmp(szFileName, "replay.game.events")) + __debugbreak(); + // Read the file data SFileReadFile(hFile, pFileData->FileData, dwFileSizeLo, &dwBytesRead, NULL); if(dwBytesRead != dwFileSizeLo) @@ -4218,6 +4223,9 @@ static const TEST_INFO TestList_MasterMirror[] = static const TEST_INFO Test_Mpqs[] = { + + {_T("ProblemMpqArchive.SC2Replay"), NULL, 0, "replay.game.events"}, + // Correct or damaged archives {_T("MPQ_1997_v1_Diablo1_DIABDAT.MPQ"), NULL, 0, "music\\dintro.wav", "File00000023.xxx"}, {_T("MPQ_2016_v1_D2XP_IX86_1xx_114a.mpq"), NULL, 0, "waitingroombkgd.dc6"}, // Update MPQ from Diablo II (patch 2016) @@ -4296,6 +4304,7 @@ int _tmain(int argc, TCHAR * argv[]) // Open all files from the command line // + TestArchive(_T("ProblemMpqArchive.SC2Replay"), NULL, 0, "replay.game.events", NULL); for(int i = 1; i < argc; i++) { ForEachFile_OpenArchive(argv[i]); -- cgit v1.2.3