diff options
| author | Ladislav Zezula <zezula@volny.cz> | 2024-04-21 20:21:38 +0200 | 
|---|---|---|
| committer | Ladislav Zezula <zezula@volny.cz> | 2024-04-21 20:21:38 +0200 | 
| commit | c4e3490d729ba42e92803b7f2ef90ed86b0b0eca (patch) | |
| tree | 4bdb5d39a85932c9be7ddb74306814d7682089f5 | |
| parent | a26f04c11dd86e949e649a8c0a01eeaeae268c26 (diff) | |
Added buffer overflow checks to the Sparse decompression (https://github.com/ladislav-zezula/StormLib/issues/337)
| -rw-r--r-- | src/huffman/huff.h | 2 | ||||
| -rw-r--r-- | src/sparse/sparse.cpp | 5 | ||||
| -rwxr-xr-x | 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
  | 
