Fix heap corruption in CUtlVector destructor (#1165)
This commit is contained in:
parent
452338dc11
commit
739c07ca9b
@ -1212,6 +1212,45 @@ bool IsWindowsReservedDeviceName(const char *pMapname)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if SOURCE_ENGINE >= SE_LEFT4DEAD && defined PLATFORM_WINDOWS
|
||||||
|
// This frees memory allocated by the game using the game's CRT on Windows,
|
||||||
|
// avoiding a crash due to heap corruption (issue #910).
|
||||||
|
template< class T, class I >
|
||||||
|
class CUtlMemoryGlobalMalloc : public CUtlMemory< T, I >
|
||||||
|
{
|
||||||
|
typedef CUtlMemory< T, I > BaseClass;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using BaseClass::BaseClass;
|
||||||
|
|
||||||
|
void Purge()
|
||||||
|
{
|
||||||
|
if (!IsExternallyAllocated())
|
||||||
|
{
|
||||||
|
if (m_pMemory)
|
||||||
|
{
|
||||||
|
UTLMEMORY_TRACK_FREE();
|
||||||
|
g_pMemAlloc->Free((void*)m_pMemory);
|
||||||
|
m_pMemory = 0;
|
||||||
|
}
|
||||||
|
m_nAllocationCount = 0;
|
||||||
|
}
|
||||||
|
BaseClass::Purge();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void CHalfLife2::FreeUtlVectorUtlString(CUtlVector<CUtlString, CUtlMemoryGlobalMalloc<CUtlString>> &vec)
|
||||||
|
{
|
||||||
|
CUtlMemoryGlobalMalloc<unsigned char> *pMemory;
|
||||||
|
FOR_EACH_VEC(vec, i)
|
||||||
|
{
|
||||||
|
pMemory = (CUtlMemoryGlobalMalloc<unsigned char> *) &vec[i].m_Storage.m_Memory;
|
||||||
|
pMemory->Purge();
|
||||||
|
vec[i].m_Storage.SetLength(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
SMFindMapResult CHalfLife2::FindMap(const char *pMapName, char *pFoundMap, size_t nMapNameMax)
|
SMFindMapResult CHalfLife2::FindMap(const char *pMapName, char *pFoundMap, size_t nMapNameMax)
|
||||||
{
|
{
|
||||||
/* We need to ensure user input does not contain reserved device names on windows */
|
/* We need to ensure user input does not contain reserved device names on windows */
|
||||||
@ -1245,8 +1284,13 @@ SMFindMapResult CHalfLife2::FindMap(const char *pMapName, char *pFoundMap, size_
|
|||||||
|
|
||||||
static size_t helperCmdLen = strlen(pHelperCmd->GetName());
|
static size_t helperCmdLen = strlen(pHelperCmd->GetName());
|
||||||
|
|
||||||
|
#ifdef PLATFORM_WINDOWS
|
||||||
|
CUtlVector<CUtlString, CUtlMemoryGlobalMalloc<CUtlString>> results;
|
||||||
|
pHelperCmd->AutoCompleteSuggest(pMapName, *(CUtlVector<CUtlString, CUtlMemory<CUtlString>>*)&results);
|
||||||
|
#else
|
||||||
CUtlVector<CUtlString> results;
|
CUtlVector<CUtlString> results;
|
||||||
pHelperCmd->AutoCompleteSuggest(pMapName, results);
|
pHelperCmd->AutoCompleteSuggest(pMapName, results);
|
||||||
|
#endif
|
||||||
if (results.Count() == 0)
|
if (results.Count() == 0)
|
||||||
return SMFindMapResult::NotFound;
|
return SMFindMapResult::NotFound;
|
||||||
|
|
||||||
@ -1258,11 +1302,17 @@ SMFindMapResult CHalfLife2::FindMap(const char *pMapName, char *pFoundMap, size_
|
|||||||
bool bExactMatch = Q_strcmp(pMapName, &results[0][helperCmdLen + 1]) == 0;
|
bool bExactMatch = Q_strcmp(pMapName, &results[0][helperCmdLen + 1]) == 0;
|
||||||
if (bExactMatch)
|
if (bExactMatch)
|
||||||
{
|
{
|
||||||
|
#ifdef PLATFORM_WINDOWS
|
||||||
|
FreeUtlVectorUtlString(results);
|
||||||
|
#endif
|
||||||
return SMFindMapResult::Found;
|
return SMFindMapResult::Found;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ke::SafeStrcpy(pFoundMap, nMapNameMax, &results[0][helperCmdLen + 1]);
|
ke::SafeStrcpy(pFoundMap, nMapNameMax, &results[0][helperCmdLen + 1]);
|
||||||
|
#ifdef PLATFORM_WINDOWS
|
||||||
|
FreeUtlVectorUtlString(results);
|
||||||
|
#endif
|
||||||
return SMFindMapResult::FuzzyMatch;
|
return SMFindMapResult::FuzzyMatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,6 +179,12 @@ enum class SMFindMapResult : cell_t {
|
|||||||
PossiblyAvailable
|
PossiblyAvailable
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if SOURCE_ENGINE >= SE_LEFT4DEAD && defined PLATFORM_WINDOWS
|
||||||
|
template< class T, class I = int >
|
||||||
|
class CUtlMemoryGlobalMalloc;
|
||||||
|
class CUtlString;
|
||||||
|
#endif
|
||||||
|
|
||||||
class CHalfLife2 :
|
class CHalfLife2 :
|
||||||
public SMGlobalClass,
|
public SMGlobalClass,
|
||||||
public IGameHelpers
|
public IGameHelpers
|
||||||
@ -229,6 +235,9 @@ public: //IGameHelpers
|
|||||||
bool IsMapValid(const char *map);
|
bool IsMapValid(const char *map);
|
||||||
SMFindMapResult FindMap(char *pMapName, size_t nMapNameMax);
|
SMFindMapResult FindMap(char *pMapName, size_t nMapNameMax);
|
||||||
SMFindMapResult FindMap(const char *pMapName, char *pFoundMap = NULL, size_t nMapNameMax = 0);
|
SMFindMapResult FindMap(const char *pMapName, char *pFoundMap = NULL, size_t nMapNameMax = 0);
|
||||||
|
#if SOURCE_ENGINE >= SE_LEFT4DEAD && defined PLATFORM_WINDOWS
|
||||||
|
void FreeUtlVectorUtlString(CUtlVector<CUtlString, CUtlMemoryGlobalMalloc<CUtlString>> &vec);
|
||||||
|
#endif
|
||||||
bool GetMapDisplayName(const char *pMapName, char *pDisplayname, size_t nMapNameMax);
|
bool GetMapDisplayName(const char *pMapName, char *pDisplayname, size_t nMapNameMax);
|
||||||
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||||
string_t AllocPooledString(const char *pszValue);
|
string_t AllocPooledString(const char *pszValue);
|
||||||
|
Loading…
Reference in New Issue
Block a user