aboutsummaryrefslogtreecommitdiff
path: root/src/SFileListFile.cpp
diff options
context:
space:
mode:
authorLadislav Zezula <ladislav.zezula@avg.com>2013-01-28 12:46:18 +0100
committerLadislav Zezula <ladislav.zezula@avg.com>2013-01-28 12:46:18 +0100
commit46af69aeb25c5a4c5f967067862aa33a36d2c786 (patch)
tree7b9e8582870d80e6ec79de56328bbc7fc573de47 /src/SFileListFile.cpp
parent46eb01bf662c7756c59b32089cac87fd6be3a58d (diff)
+ Fixed double-free for list file cache
+ Fixed bug with patch prefixes + Fixed bug in SFileDecompression2
Diffstat (limited to 'src/SFileListFile.cpp')
-rw-r--r--src/SFileListFile.cpp114
1 files changed, 54 insertions, 60 deletions
diff --git a/src/SFileListFile.cpp b/src/SFileListFile.cpp
index 2293403..38a9601 100644
--- a/src/SFileListFile.cpp
+++ b/src/SFileListFile.cpp
@@ -21,14 +21,15 @@
struct TListFileCache
{
HANDLE hFile; // Stormlib file handle
- char * szMask; // File mask
+ char * szMask; // Self-relative pointer to file mask
DWORD dwFileSize; // Total size of the cached file
DWORD dwFilePos; // Position of the cache in the file
BYTE * pBegin; // The begin of the listfile cache
BYTE * pPos;
BYTE * pEnd; // The last character in the file cache
- BYTE Buffer[CACHE_BUFFER_SIZE]; // Listfile cache itself
+ BYTE Buffer[CACHE_BUFFER_SIZE];
+// char MaskBuff[1] // Followed by the name mask (if any)
};
//-----------------------------------------------------------------------------
@@ -40,9 +41,12 @@ static bool FreeListFileCache(TListFileCache * pCache)
if(pCache == NULL)
return false;
+ //
+ // Note: don't close the pCache->hFile handle.
+ // This has to be done by the creator of the listfile cache
+ //
+
// Free all allocated buffers
- if(pCache->hFile != NULL)
- SFileCloseFile(pCache->hFile);
if(pCache->szMask != NULL)
STORM_FREE(pCache->szMask);
STORM_FREE(pCache);
@@ -52,54 +56,48 @@ static bool FreeListFileCache(TListFileCache * pCache)
static TListFileCache * CreateListFileCache(HANDLE hListFile, const char * szMask)
{
TListFileCache * pCache = NULL;
+ size_t nMaskLength = 0;
DWORD dwBytesRead = 0;
- int nError = ERROR_SUCCESS;
+ DWORD dwFileSize;
- // Allocate cache for one file block
- pCache = (TListFileCache *)STORM_ALLOC(TListFileCache, 1);
- if(pCache == NULL)
- nError = ERROR_NOT_ENOUGH_MEMORY;
+ // Get the amount of bytes that need to be allocated
+ dwFileSize = SFileGetFileSize(hListFile, NULL);
+ if(dwFileSize == 0)
+ return NULL;
- // Clear the entire structure
- if(nError == ERROR_SUCCESS)
+ // Append buffer for name mask, if any
+ if(szMask != NULL)
+ nMaskLength = strlen(szMask) + 1;
+
+ // Allocate cache for one file block
+ pCache = (TListFileCache *)STORM_ALLOC(BYTE, sizeof(TListFileCache));
+ if(pCache != NULL)
{
- memset(pCache, 0, sizeof(TListFileCache));
- pCache->hFile = hListFile;
+ // Clear the entire structure
+ memset(pCache, 0, sizeof(TListFileCache) + nMaskLength);
- // Shall we allocate a mask?
+ // Shall we copy the mask?
if(szMask != NULL)
{
- pCache->szMask = STORM_ALLOC(char, strlen(szMask) + 1);
- if(pCache->szMask != NULL)
- strcpy(pCache->szMask, szMask);
- else
- nError = ERROR_NOT_ENOUGH_MEMORY;
+ pCache->szMask = (char *)(pCache + 1);
+ memcpy(pCache->szMask, szMask, nMaskLength);
}
- }
-
- // Initialize the file cache
- if(nError == ERROR_SUCCESS)
- {
- pCache->dwFileSize = SFileGetFileSize(pCache->hFile, NULL);
- // Fill the cache
- SFileReadFile(pCache->hFile, pCache->Buffer, CACHE_BUFFER_SIZE, &dwBytesRead, NULL);
- if(dwBytesRead == 0)
- nError = GetLastError();
- }
-
- // Allocate pointers
- if(nError == ERROR_SUCCESS)
- {
- pCache->pBegin =
- pCache->pPos = &pCache->Buffer[0];
- pCache->pEnd = pCache->pBegin + dwBytesRead;
- }
- else
- {
- FreeListFileCache(pCache);
- SetLastError(nError);
- pCache = NULL;
+ // Load the file cache from the file
+ SFileReadFile(hListFile, pCache->Buffer, CACHE_BUFFER_SIZE, &dwBytesRead, NULL);
+ if(dwBytesRead != 0)
+ {
+ // Allocate pointers
+ pCache->pBegin = pCache->pPos = &pCache->Buffer[0];
+ pCache->pEnd = pCache->pBegin + dwBytesRead;
+ pCache->dwFileSize = dwFileSize;
+ pCache->hFile = hListFile;
+ }
+ else
+ {
+ FreeListFileCache(pCache);
+ pCache = NULL;
+ }
}
// Return the cache
@@ -116,8 +114,6 @@ static DWORD ReloadListFileCache(TListFileCache * pCache)
// Only do something if the cache is empty
if(pCache->pPos >= pCache->pEnd)
{
-// __TryReadBlock:
-
// Move the file position forward
pCache->dwFilePos += CACHE_BUFFER_SIZE;
if(pCache->dwFilePos >= pCache->dwFileSize)
@@ -415,25 +411,20 @@ static int SFileAddArbitraryListFile(
TListFileCache * pCache = NULL;
size_t nLength;
char szFileName[MAX_PATH];
- int nError = ERROR_SUCCESS;
// Create the listfile cache for that file
pCache = CreateListFileCache(hListFile, NULL);
- if(pCache == NULL)
- nError = GetLastError();
-
- // Load the node list. Add the node for every locale in the archive
- if(nError == ERROR_SUCCESS)
+ if(pCache != NULL)
{
+ // Load the node list. Add the node for every locale in the archive
while((nLength = ReadListFileLine(pCache, szFileName, sizeof(szFileName))) > 0)
SListFileCreateNodeForAllLocales(ha, szFileName);
- pCache->hFile = NULL;
- }
- // Delete the cache
- if(pCache != NULL)
+ // Delete the cache
FreeListFileCache(pCache);
- return nError;
+ }
+
+ return (pCache != NULL) ? ERROR_SUCCESS : ERROR_FILE_CORRUPT;
}
static int SFileAddExternalListFile(
@@ -540,7 +531,7 @@ int WINAPI SFileAddListFile(HANDLE hMpq, const char * szListFile)
HANDLE WINAPI SListFileFindFirstFile(HANDLE hMpq, const char * szListFile, const char * szMask, SFILE_FIND_DATA * lpFindFileData)
{
TListFileCache * pCache = NULL;
- HANDLE hListFile;
+ HANDLE hListFile = NULL;
size_t nLength = 0;
DWORD dwSearchScope = SFILE_OPEN_LOCAL_FILE;
int nError = ERROR_SUCCESS;
@@ -566,7 +557,7 @@ HANDLE WINAPI SListFileFindFirstFile(HANDLE hMpq, const char * szListFile, const
{
pCache = CreateListFileCache(hListFile, szMask);
if(pCache == NULL)
- nError = GetLastError();
+ nError = ERROR_FILE_CORRUPT;
}
// Perform file search
@@ -592,10 +583,13 @@ HANDLE WINAPI SListFileFindFirstFile(HANDLE hMpq, const char * szListFile, const
if(nError != ERROR_SUCCESS)
{
memset(lpFindFileData, 0, sizeof(SFILE_FIND_DATA));
- FreeListFileCache(pCache);
SetLastError(nError);
- pCache = NULL;
}
+
+ if(pCache != NULL)
+ FreeListFileCache(pCache);
+ if(hListFile != NULL)
+ SFileCloseFile(hListFile);
return (HANDLE)pCache;
}