aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorunknown <E:\Ladik\Mail>2015-04-01 06:52:50 +0200
committerunknown <E:\Ladik\Mail>2015-04-01 06:52:50 +0200
commit93370897471cb7bff861f9e961ff36e6ce46a5e8 (patch)
tree2e650adc65630f70a76afe4f4e7647849c2ce5b2 /src
parente5b9f5132a9010a36db81788e10bb1be07ccf410 (diff)
+ Better handling of MPQs corrupted by yet another silly MPQ protector
Diffstat (limited to 'src')
-rw-r--r--src/SBaseCommon.cpp24
-rw-r--r--src/SFileReadFile.cpp10
-rw-r--r--src/StormCommon.h14
3 files changed, 29 insertions, 19 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