diff options
| -rw-r--r-- | src/SBaseCommon.cpp | 24 | ||||
| -rw-r--r-- | src/SFileReadFile.cpp | 10 | ||||
| -rw-r--r-- | src/StormCommon.h | 14 | ||||
| -rw-r--r-- | test/StormTest.cpp | 22 | 
4 files changed, 50 insertions, 20 deletions
diff --git a/src/SBaseCommon.cpp b/src/SBaseCommon.cpp index 23c9833..9509b6f 100644 --- a/src/SBaseCommon.cpp +++ b/src/SBaseCommon.cpp @@ -988,8 +988,13 @@ int AllocateSectorOffsets(TMPQFile * hf, bool bLoadFromFile)          {              ULONGLONG RawFilePos = hf->RawFilePos; +            // Append the length of the patch info, if any              if(hf->pPatchInfo != NULL) +            { +                if((RawFilePos + hf->pPatchInfo->dwLength) < RawFilePos) +                    return ERROR_FILE_CORRUPT;                  RawFilePos += hf->pPatchInfo->dwLength; +            }              // Load the sector offsets from the file              if(!FileStream_Read(ha->pStream, &RawFilePos, hf->SectorOffsets, dwSectorOffsLen)) @@ -1043,12 +1048,13 @@ int AllocateSectorOffsets(TMPQFile * hf, bool bLoadFromFile)                  // The sector size must not be bigger than compressed file size                  // Edit: Yes, but apparently, in original Storm.dll, the compressed -                // size is not checked anywhere -//              if((dwSectorOffset1 - dwSectorOffset0) > pFileEntry->dwCmpSize) -//              { -//                  bSectorOffsetTableCorrupt = true; -//                  break; -//              } +                // size is not checked anywhere. However, we need to do this check +                // in order to sector offset table malformed by MPQ protectors +                if((dwSectorOffset1 - dwSectorOffset0) > ha->dwSectorSize) +                { +                    bSectorOffsetTableCorrupt = true; +                    break; +                }              }              // If data corruption detected, free the sector offset table @@ -1070,9 +1076,13 @@ int AllocateSectorOffsets(TMPQFile * hf, bool bLoadFromFile)              if(hf->SectorOffsets[0] > dwSectorOffsLen)              { +                // MPQ protectors put some ridiculous values there. We must limit the extra bytes +                if(hf->SectorOffsets[0] > (dwSectorOffsLen + 0x400)) +                    return ERROR_FILE_CORRUPT; + +                // Free the old sector offset table                  dwSectorOffsLen = hf->SectorOffsets[0];                  STORM_FREE(hf->SectorOffsets); -                hf->SectorOffsets = NULL;                  goto __LoadSectorOffsets;              }          } diff --git a/src/SFileReadFile.cpp b/src/SFileReadFile.cpp index 02def18..2451865 100644 --- a/src/SFileReadFile.cpp +++ b/src/SFileReadFile.cpp @@ -81,14 +81,14 @@ static int ReadMpqSectors(TMPQFile * hf, LPBYTE pbBuffer, DWORD dwByteOffset, DW  //              return nError;  //      } -        // If the file is compressed, also allocate secondary buffer -        pbInSector = pbRawSector = STORM_ALLOC(BYTE, dwBytesToRead); -        if(pbRawSector == NULL) -            return ERROR_NOT_ENOUGH_MEMORY; -          // Assign the temporary buffer as target for read operation          dwRawSectorOffset = hf->SectorOffsets[dwSectorIndex];          dwRawBytesToRead = hf->SectorOffsets[dwSectorIndex + dwSectorsToRead] - dwRawSectorOffset; + +        // If the file is compressed, also allocate secondary buffer +        pbInSector = pbRawSector = STORM_ALLOC(BYTE, dwRawBytesToRead); +        if(pbRawSector == NULL) +            return ERROR_NOT_ENOUGH_MEMORY;      }      // Calculate raw file offset where the sector(s) are stored. diff --git a/src/StormCommon.h b/src/StormCommon.h index 93193cf..00ea3d8 100644 --- a/src/StormCommon.h +++ b/src/StormCommon.h @@ -105,17 +105,17 @@ typedef struct _MPQ_SIGNATURE_INFO  //  - Memory freeing function doesn't have to test the pointer to NULL  // -//#if defined(_MSC_VER) && defined(_DEBUG) -// -//#define STORM_ALLOC(type, nitems) (type *)HeapAlloc(GetProcessHeap(), 0, ((nitems) * sizeof(type))) -//#define STORM_FREE(ptr)           HeapFree(GetProcessHeap(), 0, ptr) -// -//#else +#if defined(_MSC_VER) && defined(_DEBUG) + +#define STORM_ALLOC(type, nitems) (type *)HeapAlloc(GetProcessHeap(), 0, ((nitems) * sizeof(type))) +#define STORM_FREE(ptr)           HeapFree(GetProcessHeap(), 0, ptr) + +#else  #define STORM_ALLOC(type, nitems) (type *)malloc((nitems) * sizeof(type))  #define STORM_FREE(ptr)           free(ptr) -//#endif +#endif  //-----------------------------------------------------------------------------  // StormLib internal global variables diff --git a/test/StormTest.cpp b/test/StormTest.cpp index 48beea5..1234722 100644 --- a/test/StormTest.cpp +++ b/test/StormTest.cpp @@ -177,6 +177,18 @@ static const char * PatchList_SC2_32283[] =      NULL  }; +static const char * PatchList_SC2_34644[] =  +{ +    "MPQ_2013_v4_Base1.SC2Data", +    "s2-update-base-23258.MPQ", +    "s2-update-base-24540.MPQ", +    "s2-update-base-26147.MPQ", +    "s2-update-base-28522.MPQ", +    "s2-update-base-32384.MPQ", +    "s2-update-base-34644.MPQ", +    NULL +}; +  static const char * PatchList_SC2_32283_enGB[] =   {      "MPQ_2013_v4_enGB.SC2Data", @@ -4114,6 +4126,10 @@ int main(int argc, char * argv[])      // Open an Warcraft III map whose "(attributes)" file has (BlockTableSize-1) entries      if(nError == ERROR_SUCCESS)          nError = TestOpenArchive("MPQ_2014_v1_AttributesOneEntryLess.w3x"); +*/ +    // Open an Warcraft III map whose "(attributes)" file has (BlockTableSize-1) entries +    if(nError == ERROR_SUCCESS) +        nError = TestOpenArchive("2.1.w3x");      // Open a MPQ archive v 3.0      if(nError == ERROR_SUCCESS) @@ -4169,6 +4185,10 @@ int main(int argc, char * argv[])      // Open a patched archive      if(nError == ERROR_SUCCESS) +        nError = TestOpenArchive_Patched(PatchList_SC2_34644, "TriggerLibs\\GameData\\GameData.galaxy", 2); + +    // Open a patched archive +    if(nError == ERROR_SUCCESS)          nError = TestOpenArchive_Patched(PatchList_SC2_32283_enGB, "LocalizedData\\GameHotkeys.txt", 6);      // Open a patched archive @@ -4198,7 +4218,7 @@ int main(int argc, char * argv[])      // Check archive signature      if(nError == ERROR_SUCCESS)          nError = TestOpenArchive_VerifySignature("MPQ_1999_v1_WeakSignature.exe", "War2Patch_202.exe"); -*/ +      if(nError == ERROR_SUCCESS)          nError = TestOpenArchive_VerifySignature("MPQ_2003_v1_WeakSignatureEmpty.exe", "WoW-1.2.3.4211-enUS-patch.exe");  | 
