From 07f7869d100c59492aefc922d5d28cf85440af79 Mon Sep 17 00:00:00 2001 From: Dr!fter Date: Wed, 21 Aug 2013 13:36:23 -0400 Subject: [PATCH] Really fix return values now... Error out when overriding return but not given one. --- natives.cpp | 10 ++++++---- vfunc_call.cpp | 2 +- vhook.cpp | 43 ++++++++++++++++++++++++++++--------------- 3 files changed, 35 insertions(+), 20 deletions(-) diff --git a/natives.cpp b/natives.cpp index 0573f94..c634502 100644 --- a/natives.cpp +++ b/natives.cpp @@ -221,8 +221,6 @@ cell_t Native_SetReturn(IPluginContext *pContext, const cell_t *params) return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err); } - CBaseEntity *pEnt; - edict_t *pEdict; switch(returnStruct->type) { case ReturnType_Int: @@ -232,21 +230,25 @@ cell_t Native_SetReturn(IPluginContext *pContext, const cell_t *params) *(bool *)returnStruct->newResult = params[2] != 0; break; case ReturnType_CBaseEntity: - pEnt = UTIL_GetCBaseEntity(params[2]); + { + CBaseEntity *pEnt = UTIL_GetCBaseEntity(params[2]); if(!pEnt) { return pContext->ThrowNativeError("Invalid entity index passed for return value"); } *(CBaseEntity **)returnStruct->newResult = pEnt; break; + } case ReturnType_Edict: - pEdict = gamehelpers->EdictOfIndex(params[2]); + { + edict_t *pEdict = gamehelpers->EdictOfIndex(params[2]); if(!pEdict || pEdict->IsFree()) { pContext->ThrowNativeError("Invalid entity index passed for return value"); } *(edict_t **)returnStruct->newResult = pEdict; break; + } case ReturnType_Float: *(float *)returnStruct->newResult = sp_ctof(params[2]); break; diff --git a/vfunc_call.cpp b/vfunc_call.cpp index 231ee1d..8616484 100644 --- a/vfunc_call.cpp +++ b/vfunc_call.cpp @@ -53,7 +53,7 @@ void *CallVFunction(DHooksCallback *dg, HookParamsStruct *paramStruct, void *ifa unsigned char *vstk = (unsigned char *)malloc(sizeof(void *) + size); unsigned char *vptr = vstk; - *(void **)vptr = iface; + *(void **)vptr = iface; if(paramStruct) { diff --git a/vhook.cpp b/vhook.cpp index 63ffd78..0ab76f5 100644 --- a/vhook.cpp +++ b/vhook.cpp @@ -126,13 +126,13 @@ HookReturnStruct *GetReturnStruct(DHooksCallback *dg, const void *result) case ReturnType_Int: *(int *)res->orgResult = *(int *)result; case ReturnType_Bool: - *(int *)res->orgResult = *(bool *)result; + *(bool *)res->orgResult = *(bool *)result; break; case ReturnType_Float: *(float *)res->orgResult = *(float *)result; break; default: - res->orgResult = *(void **)result; + *(void **)res->orgResult = (void *)result; break; } } @@ -180,6 +180,7 @@ void *Callback(DHooksCallback *dg, void **argStack) rHndl = handlesys->CreateHandle(g_HookReturnHandle, returnStruct, dg->plugin_callback->GetParentRuntime()->GetDefaultContext()->GetIdentity(), myself->GetIdentity(), NULL); if(!rHndl) { + dg->plugin_callback->Cancel(); if(returnStruct) { delete returnStruct; @@ -202,6 +203,7 @@ void *Callback(DHooksCallback *dg, void **argStack) pHndl = handlesys->CreateHandle(g_HookParamsHandle, paramStruct, dg->plugin_callback->GetParentRuntime()->GetDefaultContext()->GetIdentity(), myself->GetIdentity(), NULL); if(!pHndl) { + dg->plugin_callback->Cancel(); if(returnStruct) { delete returnStruct; @@ -228,42 +230,53 @@ void *Callback(DHooksCallback *dg, void **argStack) ret = CallVFunction(dg, paramStruct, g_SHPtr->GetIfacePtr()); break; case MRES_ChangedOverride: - g_SHPtr->DoRecall(); - g_SHPtr->SetRes(MRES_SUPERCEDE); - ret = CallVFunction(dg, paramStruct, g_SHPtr->GetIfacePtr()); if(dg->returnType != ReturnType_Void) { if(returnStruct->isChanged) { - *(void **)ret = returnStruct->newResult; + ret = *(void **)returnStruct->newResult; + } + else //Throw an error if no override was set + { + g_SHPtr->SetRes(MRES_IGNORED); + IPlugin *plugin = plsys->FindPluginByContext(dg->plugin_callback->GetParentContext()->GetContext()); + smutils->LogError(myself, "Plugin %s tried to override a return without a return being set", plugin->GetFilename()); + break; } } + g_SHPtr->DoRecall(); + g_SHPtr->SetRes(MRES_SUPERCEDE); + CallVFunction(dg, paramStruct, g_SHPtr->GetIfacePtr()); break; case MRES_Override: - g_SHPtr->SetRes(MRES_OVERRIDE); if(dg->returnType != ReturnType_Void) { if(returnStruct->isChanged) { - *(void **)ret = returnStruct->newResult; + g_SHPtr->SetRes(MRES_OVERRIDE); + ret = *(void **)returnStruct->newResult; } - else if(dg->post) + else //Throw an error if no override was set { - *(void **)ret = returnStruct->orgResult; + g_SHPtr->SetRes(MRES_IGNORED); + IPlugin *plugin = plsys->FindPluginByContext(dg->plugin_callback->GetParentContext()->GetContext()); + smutils->LogError(myself, "Plugin %s tried to override a return without a return being set", plugin->GetFilename()); } } break; case MRES_Supercede: - g_SHPtr->SetRes(MRES_SUPERCEDE); if(dg->returnType != ReturnType_Void) { if(returnStruct->isChanged) { - *(void **)ret = returnStruct->newResult; + g_SHPtr->SetRes(MRES_SUPERCEDE); + ret = *(void **)returnStruct->newResult; } - else if(dg->post) + else //Throw an error if no override was set { - *(void **)ret = returnStruct->orgResult; + g_SHPtr->SetRes(MRES_IGNORED); + IPlugin *plugin = plsys->FindPluginByContext(dg->plugin_callback->GetParentContext()->GetContext()); + smutils->LogError(myself, "Plugin %s tried to override a return without a return being set", plugin->GetFilename()); } } break; @@ -283,7 +296,7 @@ void *Callback(DHooksCallback *dg, void **argStack) handlesys->FreeHandle(pHndl, &sec); } - if(dg->returnType != ReturnType_Void) + if(dg->returnType == ReturnType_Void || g_SHPtr->GetStatus() <= MRES_HANDLED) { return NULL; }