aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/SBaseCommon.cpp24
-rw-r--r--src/SFileReadFile.cpp10
-rw-r--r--src/StormCommon.h14
-rw-r--r--test/StormTest.cpp22
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");