From ed29c837fa685314325bc582760c2698eedc34bb Mon Sep 17 00:00:00 2001 From: David Anderson Date: Wed, 29 Oct 2008 01:27:56 -0700 Subject: [PATCH] Fixed failed timers leaking dangling plugin references (bug 3381). --- core/smn_timers.cpp | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/core/smn_timers.cpp b/core/smn_timers.cpp index be8bc64f..3ccc8118 100644 --- a/core/smn_timers.cpp +++ b/core/smn_timers.cpp @@ -160,16 +160,19 @@ void TimerNatives::OnTimerEnd(ITimer *pTimer, void *pData) } } - if ((herr=g_HandleSys.FreeHandle(pInfo->TimerHandle, &sec)) != HandleError_None) + if (pInfo->TimerHandle != BAD_HANDLE) { - g_DbgReporter.GenerateError(pInfo->pContext, - pInfo->Hook->GetFunctionID(), - SP_ERROR_NATIVE, - "Invalid timer handle %x (error %d) during timer end, displayed function is timer callback, not the stack trace", - pInfo->TimerHandle, - herr); - return; + if ((herr=g_HandleSys.FreeHandle(pInfo->TimerHandle, &sec)) != HandleError_None) + { + g_DbgReporter.GenerateError(pInfo->pContext, + pInfo->Hook->GetFunctionID(), + SP_ERROR_NATIVE, + "Invalid timer handle %x (error %d) during timer end, displayed function is timer callback, not the stack trace", + pInfo->TimerHandle, + herr); + } } + DeleteTimerInfo(pInfo); } @@ -206,6 +209,24 @@ static cell_t smn_CreateTimer(IPluginContext *pCtx, const cell_t *params) hndl = g_HandleSys.CreateHandle(g_TimerType, pInfo, pCtx->GetIdentity(), g_pCoreIdent, NULL); + /* If we can't get a handle, the timer isn't refcounted against the plugin and + * we need to bail out to prevent a crash. + */ + if (hndl == BAD_HANDLE) + { + /* Free this for completeness. */ + if (flags & TIMER_HNDL_CLOSE) + { + HandleSecurity sec(pCtx->GetIdentity(), g_pCoreIdent); + g_HandleSys.FreeHandle(params[3], &sec); + } + /* Zero everything so there's no conflicts */ + memset(pInfo, 0, sizeof(TimerInfo)); + g_Timers.KillTimer(pTimer); + + return pCtx->ThrowNativeError("Could not create timer, no more handles"); + } + pInfo->UserData = params[3]; pInfo->Flags = flags; pInfo->TimerHandle = hndl;