Skip to content

Commit f35d106

Browse files
author
Zezula Ladislav
committed
+ Fixed arbitrarily large allocations caused by TQMPHeader::dwBlockTableSize
1 parent 4ad0bff commit f35d106

6 files changed

+50
-15
lines changed

StormLib_vs08.vcproj

+8
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
IntermediateDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
2626
ConfigurationType="4"
2727
CharacterSet="2"
28+
WholeProgramOptimization="0"
2829
>
2930
<Tool
3031
Name="VCPreBuildEventTool"
@@ -88,6 +89,7 @@
8889
IntermediateDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
8990
ConfigurationType="4"
9091
CharacterSet="2"
92+
WholeProgramOptimization="0"
9193
>
9294
<Tool
9395
Name="VCPreBuildEventTool"
@@ -152,6 +154,7 @@
152154
IntermediateDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
153155
ConfigurationType="4"
154156
CharacterSet="2"
157+
WholeProgramOptimization="0"
155158
>
156159
<Tool
157160
Name="VCPreBuildEventTool"
@@ -215,6 +218,7 @@
215218
IntermediateDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
216219
ConfigurationType="4"
217220
CharacterSet="2"
221+
WholeProgramOptimization="0"
218222
>
219223
<Tool
220224
Name="VCPreBuildEventTool"
@@ -529,6 +533,7 @@
529533
IntermediateDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
530534
ConfigurationType="4"
531535
CharacterSet="1"
536+
WholeProgramOptimization="0"
532537
>
533538
<Tool
534539
Name="VCPreBuildEventTool"
@@ -592,6 +597,7 @@
592597
IntermediateDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
593598
ConfigurationType="4"
594599
CharacterSet="1"
600+
WholeProgramOptimization="0"
595601
>
596602
<Tool
597603
Name="VCPreBuildEventTool"
@@ -656,6 +662,7 @@
656662
IntermediateDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
657663
ConfigurationType="4"
658664
CharacterSet="1"
665+
WholeProgramOptimization="0"
659666
>
660667
<Tool
661668
Name="VCPreBuildEventTool"
@@ -719,6 +726,7 @@
719726
IntermediateDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
720727
ConfigurationType="4"
721728
CharacterSet="1"
729+
WholeProgramOptimization="0"
722730
>
723731
<Tool
724732
Name="VCPreBuildEventTool"

src/FileStream.cpp

+13
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,19 @@ static bool BaseHttp_Open(TFileStream * pStream, const TCHAR * szFileName, DWORD
652652
DWORD dwFileSize = 0;
653653
DWORD dwDataSize;
654654
DWORD dwIndex = 0;
655+
TCHAR StatusCode[0x08];
656+
657+
// Check if the file succeeded to open
658+
dwDataSize = sizeof(StatusCode);
659+
if(HttpQueryInfo(hRequest, HTTP_QUERY_STATUS_CODE, StatusCode, &dwDataSize, &dwIndex))
660+
{
661+
if(_tcscmp(StatusCode, _T("200")))
662+
{
663+
InternetCloseHandle(hRequest);
664+
SetLastError(ERROR_FILE_NOT_FOUND);
665+
return false;
666+
}
667+
}
655668

656669
// Check if the MPQ has Last Modified field
657670
dwDataSize = sizeof(ULONGLONG);

src/SBaseFileTable.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,14 @@ int ConvertMpqHeaderToFormat4(
406406
pHeader->ArchiveSize64 = DetermineArchiveSize_V1(ha, pHeader, MpqOffset, FileSize);
407407
pHeader->dwArchiveSize = (DWORD)pHeader->ArchiveSize64;
408408
}
409+
410+
// EWIX_v8_7.w3x: TMPQHeader::dwBlockTableSize = 0x00319601
411+
// Size of TFileTable goes to ~200MB, so we artificially cut it
412+
if(BlockTablePos64 + (pHeader->dwBlockTableSize * sizeof(TMPQBlock)) > FileSize)
413+
{
414+
pHeader->dwBlockTableSize = (DWORD)((FileSize - BlockTablePos64) / sizeof(TMPQBlock));
415+
pHeader->BlockTableSize64 = pHeader->dwBlockTableSize * sizeof(TMPQBlock);
416+
}
409417
break;
410418

411419
case MPQ_FORMAT_VERSION_2:

src/SFileOpenArchive.cpp

-1
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,6 @@ static int VerifyMpqTablePositions(TMPQArchive * ha, ULONGLONG FileSize)
118118
return ERROR_SUCCESS;
119119
}
120120

121-
122121
/*****************************************************************************/
123122
/* Public functions */
124123
/*****************************************************************************/

src/SFileOpenFileEx.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,10 @@ bool WINAPI SFileOpenFileEx(HANDLE hMpq, const char * szFileName, DWORD dwSearch
308308
}
309309
}
310310

311-
nError = ERROR_FILE_NOT_FOUND;
311+
if(pFileEntry == NULL)
312+
{
313+
nError = ERROR_FILE_NOT_FOUND;
314+
}
312315
}
313316

314317
// Ignore unknown loading flags (example: MPQ_2016_v1_WME4_4.w3x)

test/StormTest.cpp

+17-13
Original file line numberDiff line numberDiff line change
@@ -1611,7 +1611,8 @@ static TFileData * LoadMpqFile(TLogHelper * pLogger, HANDLE hMpq, LPCSTR szFileN
16111611
// Read the file data
16121612
SFileReadFile(hFile, pFileData->FileData, dwFileSizeLo, &dwBytesRead, NULL);
16131613
if(dwBytesRead != dwFileSizeLo)
1614-
nError = pLogger->PrintError("Read failed: %s", szFileName);
1614+
// nError = pLogger->PrintError("Read failed: %s", szFileName);
1615+
nError = ERROR_FILE_CORRUPT;
16151616
}
16161617

16171618
// If failed, free the buffer
@@ -2503,10 +2504,10 @@ static int TestOpenFile_OpenById(LPCTSTR szPlainName)
25032504

25042505
static int TestOpenFile_OpenByName(LPCTSTR szPlainName, LPCSTR szFileName)
25052506
{
2506-
TLogHelper Logger("OpenFileById", szPlainName);
2507+
TLogHelper Logger("OpenFileByName", szPlainName);
25072508
TFileData * pFileData = NULL;
2508-
HANDLE hFile;
2509-
HANDLE hMpq;
2509+
HANDLE hFile = NULL;
2510+
HANDLE hMpq = NULL;
25102511
DWORD dwCrc32_1 = 0;
25112512
DWORD dwCrc32_2 = 0;
25122513
int nError;
@@ -2541,11 +2542,11 @@ static int TestOpenFile_OpenByName(LPCTSTR szPlainName, LPCSTR szFileName)
25412542
if(dwCrc32_1 != dwCrc32_2)
25422543
Logger.PrintError("Warning: CRC32 error on %s", szFileName);
25432544
}
2544-
}
25452545

2546-
// Close the archive
2547-
if(hMpq != NULL)
2546+
// Close the archive
25482547
SFileCloseArchive(hMpq);
2548+
}
2549+
25492550
return nError;
25502551
}
25512552

@@ -4462,11 +4463,11 @@ int _tmain(int argc, TCHAR * argv[])
44624463
// Open a stream, paired with local master
44634464
if(nError == ERROR_SUCCESS)
44644465
nError = TestReadFile_MasterMirror(_T("MPQ_2013_v4_alternate-complete.MPQ"), _T("MPQ_2013_v4_alternate-original.MPQ"), true);
4465-
4466+
*/
44664467
// Open a stream, paired with remote master (takes hell lot of time!!!)
44674468
if(nError == ERROR_SUCCESS)
44684469
nError = TestReadFile_MasterMirror(_T("MPQ_2013_v4_alternate-downloaded.MPQ"), _T("http://www.zezula.net\\mpqs\\alternate.zip"), false);
4469-
4470+
/*
44704471
// Search in listfile
44714472
if(nError == ERROR_SUCCESS)
44724473
nError = TestSearchListFile(_T("ListFile_Blizzard.txt"));
@@ -4482,10 +4483,10 @@ int _tmain(int argc, TCHAR * argv[])
44824483
// Open the update MPQ from Diablo II (patch 2016)
44834484
if(nError == ERROR_SUCCESS)
44844485
nError = TestOpenFile_OpenByName(_T("MPQ_2016_v1_D2XP_IX86_1xx_114a.mpq"), "waitingroombkgd.dc6");
4485-
*/
4486+
44864487
if(nError == ERROR_SUCCESS)
44874488
nError = TestOpenFile_OpenByName(_T("MPQ_2018_v1_icon_error.w3m"), "file00000002.blp");
4488-
/*
4489+
44894490
// Open a file whose archive's (signature) file has flags = 0x90000000
44904491
if(nError == ERROR_SUCCESS)
44914492
nError = TestOpenArchive(_T("MPQ_1997_v1_Diablo1_STANDARD.SNP"), _T("ListFile_Blizzard.txt"));
@@ -4625,6 +4626,9 @@ int _tmain(int argc, TCHAR * argv[])
46254626
if(nError == ERROR_SUCCESS)
46264627
nError = TestOpenArchive(_T("MPQ_2017_v1_TildeInFileName.mpq"), NULL, "1.blp");
46274628
4629+
if(nError == ERROR_SUCCESS)
4630+
nError = TestOpenArchive(_T("MPQ_2018_v1_EWIX_v8_7.w3x"), NULL, "BlueCrystal.mdx");
4631+
46284632
// Open the multi-file archive with wrong prefix to see how StormLib deals with it
46294633
if(nError == ERROR_SUCCESS)
46304634
nError = TestOpenArchive_WillFail(_T("flat-file://streaming/model.MPQ.0"));
@@ -4696,7 +4700,7 @@ int _tmain(int argc, TCHAR * argv[])
46964700
// Check the SFileGetFileInfo function
46974701
if(nError == ERROR_SUCCESS)
46984702
nError = TestOpenArchive_GetFileInfo(_T("MPQ_2002_v1_StrongSignature.w3m"), _T("MPQ_2013_v4_SC2_EmptyMap.SC2Map"));
4699-
4703+
*/
47004704
// Downloadable MPQ archive
47014705
if(nError == ERROR_SUCCESS)
47024706
nError = TestOpenArchive_MasterMirror(_T("part-file://MPQ_2009_v1_patch-partial.MPQ.part"), _T("MPQ_2009_v1_patch-original.MPQ"), "world\\Azeroth\\DEADMINES\\PASSIVEDOODADS\\GOBLINMELTINGPOT\\DUST2.BLP", false);
@@ -4835,7 +4839,7 @@ int _tmain(int argc, TCHAR * argv[])
48354839
// Test replacing a file with zero size file
48364840
if(nError == ERROR_SUCCESS)
48374841
nError = TestModifyArchive_ReplaceFile(_T("MPQ_2014_v4_Base.StormReplay"), _T("AddFile-replay.message.events"));
4838-
*/
4842+
48394843
#ifdef _MSC_VER
48404844
_CrtDumpMemoryLeaks();
48414845
#endif // _MSC_VER

0 commit comments

Comments
 (0)