Fixed infinite loop in BZIP decompression

This commit is contained in:
Ladislav Zezula
2021-07-02 23:53:06 +02:00
parent 18e92b7592
commit ce074eaf7a
2 changed files with 24 additions and 32 deletions

View File

@@ -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);
}
/******************************************************************************/

View File

@@ -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]);