Fix vscript function parameter leaks

This commit is contained in:
samisalreadytaken 2024-11-20 15:43:34 +03:00
parent ba9cec70d6
commit 4e68a35149
5 changed files with 42 additions and 11 deletions

View File

@ -2610,9 +2610,17 @@ public:
static inline void SetHScript( HSCRIPT &var, HSCRIPT val ) static inline void SetHScript( HSCRIPT &var, HSCRIPT val )
{ {
if ( var && g_pScriptVM ) if ( g_pScriptVM )
g_pScriptVM->ReleaseScript( var ); {
var = val; if ( var )
g_pScriptVM->ReleaseScript( var );
var = g_pScriptVM->CopyObject( val );
}
else
{
var = NULL;
}
} }
#define CheckCallback(s)\ #define CheckCallback(s)\

View File

@ -3033,7 +3033,7 @@ void CBaseEntity::ScriptSetContextThink( const char* szContext, HSCRIPT hFunc, f
float nextthink = gpGlobals->curtime + flTime; float nextthink = gpGlobals->curtime + flTime;
pf->m_hfnThink = hFunc; pf->m_hfnThink = g_pScriptVM->CopyObject( hFunc );
pf->m_flNextThink = nextthink; pf->m_flNextThink = nextthink;
#ifdef GAME_DLL #ifdef GAME_DLL

View File

@ -2920,7 +2920,7 @@ int CScriptGameEventListener::ListenToGameEvent( const char* szEvent, HSCRIPT hF
if ( bValid ) if ( bValid )
{ {
m_iContextHash = HashContext( szContext ); m_iContextHash = HashContext( szContext );
m_hCallback = hFunc; m_hCallback = g_pScriptVM->CopyObject( hFunc );
m_bActive = true; m_bActive = true;
s_Listeners.AddToTail( this ); s_Listeners.AddToTail( this );
@ -4609,9 +4609,9 @@ public:
CScriptConCommand( const char *name, HSCRIPT fn, const char *helpString, int flags, ConCommand *pLinked = NULL ) CScriptConCommand( const char *name, HSCRIPT fn, const char *helpString, int flags, ConCommand *pLinked = NULL )
: BaseClass( name, this, helpString, flags, 0 ), : BaseClass( name, this, helpString, flags, 0 ),
m_pLinked(pLinked), m_pLinked(pLinked),
m_hCallback(fn),
m_hCompletionCallback(NULL) m_hCompletionCallback(NULL)
{ {
m_hCallback = g_pScriptVM->CopyObject( fn );
m_nCmdNameLen = V_strlen(name) + 1; m_nCmdNameLen = V_strlen(name) + 1;
Assert( m_nCmdNameLen - 1 <= 128 ); Assert( m_nCmdNameLen - 1 <= 128 );
} }
@ -4701,7 +4701,7 @@ public:
BaseClass::m_pCommandCompletionCallback = this; BaseClass::m_pCommandCompletionCallback = this;
BaseClass::m_bHasCompletionCallback = true; BaseClass::m_bHasCompletionCallback = true;
m_hCompletionCallback = fn; m_hCompletionCallback = g_pScriptVM->CopyObject( fn );
} }
else else
{ {
@ -4720,7 +4720,8 @@ public:
if ( m_hCallback ) if ( m_hCallback )
g_pScriptVM->ReleaseScript( m_hCallback ); g_pScriptVM->ReleaseScript( m_hCallback );
m_hCallback = fn;
m_hCallback = g_pScriptVM->CopyObject( fn );
} }
else else
{ {
@ -4781,7 +4782,7 @@ public:
if (fn) if (fn)
{ {
m_hCallback = fn; m_hCallback = g_pScriptVM->CopyObject( fn );
BaseClass::InstallChangeCallback( (FnChangeCallback_t)ScriptConVarCallback ); BaseClass::InstallChangeCallback( (FnChangeCallback_t)ScriptConVarCallback );
} }
else else

View File

@ -1028,6 +1028,8 @@ public:
#ifdef MAPBASE_VSCRIPT #ifdef MAPBASE_VSCRIPT
virtual void CreateArray(ScriptVariant_t &arr, int size = 0) = 0; virtual void CreateArray(ScriptVariant_t &arr, int size = 0) = 0;
virtual bool ArrayAppend(HSCRIPT hArray, const ScriptVariant_t &val) = 0; virtual bool ArrayAppend(HSCRIPT hArray, const ScriptVariant_t &val) = 0;
// To hold strong references to script objects
virtual HSCRIPT CopyObject(HSCRIPT obj) = 0;
#endif #endif
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------

View File

@ -225,6 +225,7 @@ public:
virtual void CreateArray(ScriptVariant_t &arr, int size = 0) override; virtual void CreateArray(ScriptVariant_t &arr, int size = 0) override;
virtual bool ArrayAppend(HSCRIPT hArray, const ScriptVariant_t &val) override; virtual bool ArrayAppend(HSCRIPT hArray, const ScriptVariant_t &val) override;
virtual HSCRIPT CopyObject(HSCRIPT obj) override;
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -1317,7 +1318,8 @@ SQInteger function_stub(HSQUIRRELVM vm)
ScriptFunctionBinding_t* pFunc = (ScriptFunctionBinding_t*)userptr; ScriptFunctionBinding_t* pFunc = (ScriptFunctionBinding_t*)userptr;
auto nargs = pFunc->m_desc.m_Parameters.Count(); int nargs = pFunc->m_desc.m_Parameters.Count();
int nLastHScriptIdx = -1;
if (nargs > top) if (nargs > top)
{ {
@ -1394,9 +1396,10 @@ SQInteger function_stub(HSQUIRRELVM vm)
{ {
HSQOBJECT* pObject = new HSQOBJECT; HSQOBJECT* pObject = new HSQOBJECT;
*pObject = val; *pObject = val;
sq_addref(vm, pObject);
params[i] = (HSCRIPT)pObject; params[i] = (HSCRIPT)pObject;
} }
nLastHScriptIdx = i;
break; break;
} }
default: default:
@ -1453,6 +1456,12 @@ SQInteger function_stub(HSQUIRRELVM vm)
delete (HSQOBJECT*)retval.m_hScript; delete (HSQOBJECT*)retval.m_hScript;
} }
for ( int i = 0; i <= nLastHScriptIdx; ++i )
{
if ( pFunc->m_desc.m_Parameters[i] == FIELD_HSCRIPT )
delete (HSQOBJECT*)params[i].m_hScript;
}
return pFunc->m_desc.m_ReturnType != FIELD_VOID; return pFunc->m_desc.m_ReturnType != FIELD_VOID;
} }
@ -3201,6 +3210,17 @@ bool SquirrelVM::ArrayAppend(HSCRIPT hArray, const ScriptVariant_t &val)
return ret; return ret;
} }
HSCRIPT SquirrelVM::CopyObject(HSCRIPT obj)
{
if ( !obj )
return NULL;
HSQOBJECT *ret = new HSQOBJECT;
*ret = *(HSQOBJECT*)obj;
sq_addref( vm_, ret );
return (HSCRIPT)ret;
}
//------------------------------------------------------------- //-------------------------------------------------------------
//------------------------------------------------------------- //-------------------------------------------------------------