Fix strdup() leaks

This commit is contained in:
Alexander 'z33ky' Hirsch 2021-04-25 22:47:55 +02:00
parent a75b0b7d58
commit 036fbda906
4 changed files with 43 additions and 32 deletions

View File

@ -1240,7 +1240,7 @@ char *CAI_Expresser::ParseApplyContext( const char *szContext )
{ {
// If it's really 0, then this is a waste of time // If it's really 0, then this is a waste of time
Warning("\"%s\" was detected by applyContext operators as an operable number, but it's not.\n", szValue); Warning("\"%s\" was detected by applyContext operators as an operable number, but it's not.\n", szValue);
return strdup(szContext); return szContext;
} }
// This is the existing value; will be operated upon and become the final assignment // This is the existing value; will be operated upon and become the final assignment

View File

@ -2511,7 +2511,7 @@ class CBreakableGibShooter : public CBaseEntity
DECLARE_DATADESC(); DECLARE_DATADESC();
public: public:
const char *GetRandomTemplateModel( CPointTemplate *pTemplate ); int GetRandomTemplateModelIndex( CPointTemplate *pTemplate );
void Precache( void ); void Precache( void );
@ -2560,19 +2560,20 @@ END_DATADESC()
LINK_ENTITY_TO_CLASS( env_break_shooter, CBreakableGibShooter ); LINK_ENTITY_TO_CLASS( env_break_shooter, CBreakableGibShooter );
const char *CBreakableGibShooter::GetRandomTemplateModel( CPointTemplate *pTemplate ) int CBreakableGibShooter::GetRandomTemplateModelIndex( CPointTemplate *pTemplate )
{ {
int iIndex = RandomInt( 0, pTemplate->GetNumTemplates() ); int iIndex = RandomInt( 0, pTemplate->GetNumTemplates() );
char *iszTemplate = (char*)(STRING(Templates_FindByIndex(pTemplate->GetTemplateIndexForTemplate(iIndex)))); char *iszTemplate = strdup(STRING(Templates_FindByIndex(pTemplate->GetTemplateIndexForTemplate(iIndex))));
CEntityMapData entData( iszTemplate ); CEntityMapData entData( iszTemplate );
// This might seem a little messy, but I think it's cheaper than creating the entity. // This might seem a little messy, but I think it's cheaper than creating the entity.
char szModel[MAPKEY_MAXLENGTH]; char szModel[MAPKEY_MAXLENGTH];
if (!entData.ExtractValue("model", szModel)) bool modelExtracted = entData.ExtractValue("model", szModel);
return NULL;
return strdup(szModel); free(iszTemplate);
return modelinfo->GetModelIndex( modelExtracted ? szModel : NULL );
} }
void CBreakableGibShooter::Precache( void ) void CBreakableGibShooter::Precache( void )
@ -2604,7 +2605,7 @@ void CBreakableGibShooter::Shoot( void )
if (m_iModelType == MODELTYPE_BREAKABLECHUNKS) if (m_iModelType == MODELTYPE_BREAKABLECHUNKS)
iModelIndex = modelinfo->GetModelIndex( g_PropDataSystem.GetRandomChunkModel( STRING( GetModelName() ) ) ); iModelIndex = modelinfo->GetModelIndex( g_PropDataSystem.GetRandomChunkModel( STRING( GetModelName() ) ) );
else if (m_iModelType == MODELTYPE_TEMPLATE) else if (m_iModelType == MODELTYPE_TEMPLATE)
iModelIndex = modelinfo->GetModelIndex( GetRandomTemplateModel(pTemplate) ); iModelIndex = GetRandomTemplateModelIndex( pTemplate );
// All objects except the first one in this run are marked as slaves... // All objects except the first one in this run are marked as slaves...
int slaveFlag = 0; int slaveFlag = 0;

View File

@ -672,6 +672,33 @@ int CAI_Monitor::TranslateScheduleString(const char *schedName)
return 0; return 0;
} }
template<typename Translator>
static void SetForEachDelimited( CAI_Monitor &monitor, const char *szValue, const char *delimiters, void (CAI_Monitor::*setter)(int), Translator translator)
{
char *value = strdup(szValue);
char *token = strtok(value, ":");
while (token)
{
(monitor.*setter)(translator(token));
token = strtok(NULL, ":");
}
free(value);
}
template<int (CAI_Monitor::*translator)(const char*)>
struct CAI_MonitorTranslator
{
CAI_Monitor &monitor;
CAI_MonitorTranslator(CAI_Monitor &monitor) : monitor(monitor) {}
int operator()(const char *value)
{
return (monitor.*translator)(value);
}
};
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: Cache user entity field values until spawn is called. // Purpose: Cache user entity field values until spawn is called.
// Input : szKeyName - Key to handle. // Input : szKeyName - Key to handle.
@ -688,13 +715,7 @@ bool CAI_Monitor::KeyValue( const char *szKeyName, const char *szValue )
} }
else if (FStrEq(szKeyName, "Conditions")) else if (FStrEq(szKeyName, "Conditions"))
{ {
char *token = strtok(strdup(szValue), ":"); SetForEachDelimited(*this, szValue, ":", &CAI_Monitor::SetCondition, CAI_MonitorTranslator<&CAI_Monitor::TranslateConditionString>(*this));
while (token)
{
SetCondition(TranslateConditionString(token));
token = strtok(NULL, ":");
}
} }
else if (FStrEq(szKeyName, "SchedulesSimple")) else if (FStrEq(szKeyName, "SchedulesSimple"))
{ {
@ -703,13 +724,7 @@ bool CAI_Monitor::KeyValue( const char *szKeyName, const char *szValue )
} }
else if (FStrEq(szKeyName, "Schedules")) else if (FStrEq(szKeyName, "Schedules"))
{ {
char *token = strtok(strdup(szValue), ":"); SetForEachDelimited(*this, szValue, ":", &CAI_Monitor::SetSchedule, CAI_MonitorTranslator<&CAI_Monitor::TranslateScheduleString>(*this));
while (token)
{
SetSchedule(TranslateScheduleString(token));
token = strtok(NULL, ":");
}
} }
else if (FStrEq(szKeyName, "HintsSimple")) else if (FStrEq(szKeyName, "HintsSimple"))
{ {
@ -718,13 +733,7 @@ bool CAI_Monitor::KeyValue( const char *szKeyName, const char *szValue )
} }
else if (FStrEq(szKeyName, "Hints")) else if (FStrEq(szKeyName, "Hints"))
{ {
char *token = strtok(strdup(szValue), ":"); SetForEachDelimited(*this, szValue, ":", &CAI_Monitor::SetHint, atoi);
while (token)
{
SetHint(atoi(szValue));
token = strtok(NULL, ":");
}
} }
else else
return CBaseEntity::KeyValue( szKeyName, szValue ); return CBaseEntity::KeyValue( szKeyName, szValue );

View File

@ -464,7 +464,7 @@ public:
{ {
pNodeName = pName->GetName(); pNodeName = pName->GetName();
const char *pInputName = NULL; string_t pInputName = NULL_STRING;
variant_t varInputParam; variant_t varInputParam;
float flInputDelay = 0.0f; float flInputDelay = 0.0f;
CBaseEntity *pActivator = NULL; CBaseEntity *pActivator = NULL;
@ -480,7 +480,7 @@ public:
{ {
// Input name // Input name
case 0: case 0:
pInputName = inputparams; break; pInputName = AllocPooledString(inputparams); break;
// Input parameter // Input parameter
case 1: case 1:
varInputParam.SetString(AllocPooledString(inputparams)); break; varInputParam.SetString(AllocPooledString(inputparams)); break;
@ -500,9 +500,10 @@ public:
iter++; iter++;
inputparams = strtok(NULL, ","); inputparams = strtok(NULL, ",");
} }
free(pszValue);
DebugMsg("MapEdit Debug: Firing input %s on %s\n", pInputName, pNodeName); DebugMsg("MapEdit Debug: Firing input %s on %s\n", pInputName, pNodeName);
g_EventQueue.AddEvent(pNodeName, pInputName, varInputParam, flInputDelay, pActivator, pCaller, iOutputID); g_EventQueue.AddEvent(pNodeName, STRING(pInputName), varInputParam, flInputDelay, pActivator, pCaller, iOutputID);
pName = pName->GetNextKey(); pName = pName->GetNextKey();
} }