From c4e3490d729ba42e92803b7f2ef90ed86b0b0eca Mon Sep 17 00:00:00 2001 From: Ladislav Zezula Date: Sun, 21 Apr 2024 20:21:38 +0200 Subject: Added buffer overflow checks to the Sparse decompression (https://github.com/ladislav-zezula/StormLib/issues/337) --- src/huffman/huff.h | 2 +- src/sparse/sparse.cpp | 5 +++++ test/StormTest.cpp | 4 +++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/huffman/huff.h b/src/huffman/huff.h index e6f9e42..b2c6370 100644 --- a/src/huffman/huff.h +++ b/src/huffman/huff.h @@ -29,7 +29,7 @@ class TInputStream TInputStream(void * pvInBuffer, size_t cbInBuffer); bool Get1Bit(unsigned int & BitValue); - unsigned int Get8Bits(); + bool Get8Bits(unsigned int & ByteValue); bool Peek7Bits(unsigned int & Value); void SkipBits(unsigned int BitCount); diff --git a/src/sparse/sparse.cpp b/src/sparse/sparse.cpp index 6d1b621..6cf2df2 100644 --- a/src/sparse/sparse.cpp +++ b/src/sparse/sparse.cpp @@ -261,7 +261,12 @@ int DecompressSparse(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, // If highest bit, it means that that normal data follow if(OneByte & 0x80) { + // Check the length of one chunk. Check for overflows cbChunkSize = (OneByte & 0x7F) + 1; + if((pbInBuffer + cbChunkSize) > pbInBufferEnd) + return 0; + + // Copy the chunk. Make sure that the buffer won't overflow cbChunkSize = (cbChunkSize < cbOutBuffer) ? cbChunkSize : cbOutBuffer; memcpy(pbOutBuffer, pbInBuffer, cbChunkSize); pbInBuffer += cbChunkSize; diff --git a/test/StormTest.cpp b/test/StormTest.cpp index 60e2167..721ee19 100755 --- a/test/StormTest.cpp +++ b/test/StormTest.cpp @@ -3789,7 +3789,7 @@ static void Test_PlayingSpace() { HANDLE hMpq = NULL; - if(SFileOpenArchive(_T("e:\\poc18"), 0, 0, &hMpq)) + if(SFileOpenArchive(_T("e:\\poc21"), 0, 0, &hMpq)) { SFileCompactArchive(hMpq, _T("e:\\Ladik\\Incoming\\poc18"), true); SFileCloseArchive(hMpq); @@ -4008,6 +4008,8 @@ static const TEST_INFO1 Test_OpenMpqs[] = {_T("pocs/MPQ_2024_07_InvalidBitmapFooter.mpq"), NULL, "--------------------------------", TFLG_WILL_FAIL}, {_T("pocs/MPQ_2024_08_InvalidSectorSize.mpq"), NULL, "--------------------------------", TFLG_WILL_FAIL}, {_T("pocs/MPQ_2024_09_InvalidSectorSize.mpq"), NULL, "--------------------------------", TFLG_WILL_FAIL}, + {_T("pocs/MPQ_2024_10_HuffDecompressError.mpq"), NULL, "--------------------------------", TFLG_WILL_FAIL}, + {_T("pocs/MPQ_2024_10_SparseDecompressError.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 -- cgit v1.2.3