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"); |