From c04ce19b7c8b6f1f56e5330d004fbf16ce03c6f5 Mon Sep 17 00:00:00 2001 From: Dr!fter Date: Thu, 14 May 2015 12:03:48 -0400 Subject: [PATCH] Fix pointer returns being incorrectly set and freed. --- natives.cpp | 47 +++++++++++++++++++++----------------- vhook.cpp | 65 ++++++++++++++++++++++++++++++++++++++++++++--------- vhook.h | 19 +++++----------- 3 files changed, 87 insertions(+), 44 deletions(-) diff --git a/natives.cpp b/natives.cpp index 657c9ae..43ac838 100644 --- a/natives.cpp +++ b/natives.cpp @@ -360,9 +360,9 @@ cell_t Native_GetReturn(IPluginContext *pContext, const cell_t *params) case ReturnType_Bool: return *(bool *)returnStruct->orgResult? 1 : 0; case ReturnType_CBaseEntity: - return gamehelpers->EntityToBCompatRef(*(CBaseEntity **)returnStruct->orgResult); + return gamehelpers->EntityToBCompatRef((CBaseEntity *)returnStruct->orgResult); case ReturnType_Edict: - return gamehelpers->IndexOfEdict(*(edict_t **)returnStruct->orgResult); + return gamehelpers->IndexOfEdict((edict_t *)returnStruct->orgResult); case ReturnType_Float: return sp_ftoc(*(float *)returnStruct->orgResult); default: @@ -395,7 +395,7 @@ cell_t Native_SetReturn(IPluginContext *pContext, const cell_t *params) { return pContext->ThrowNativeError("Invalid entity index passed for return value"); } - *(CBaseEntity **)returnStruct->newResult = pEnt; + returnStruct->newResult = pEnt; break; } case ReturnType_Edict: @@ -405,7 +405,7 @@ cell_t Native_SetReturn(IPluginContext *pContext, const cell_t *params) { pContext->ThrowNativeError("Invalid entity index passed for return value"); } - *(edict_t **)returnStruct->newResult = pEdict; + returnStruct->newResult = pEdict; break; } case ReturnType_Float: @@ -528,10 +528,10 @@ cell_t Native_GetReturnString(IPluginContext *pContext, const cell_t *params) pContext->StringToLocal(params[2], params[3], (*(string_t *)returnStruct->orgResult == NULL_STRING) ? "" : STRING(*(string_t *)returnStruct->orgResult)); return 1; case ReturnType_StringPtr: - pContext->StringToLocal(params[2], params[3], (*(string_t **)returnStruct->orgResult == NULL) ? "" : (*(string_t **)returnStruct->orgResult)->ToCStr()); + pContext->StringToLocal(params[2], params[3], ((string_t *)returnStruct->orgResult == NULL) ? "" : ((string_t *)returnStruct->orgResult)->ToCStr()); return 1; case ReturnType_CharPtr: - pContext->StringToLocal(params[2], params[3], (*(char **)returnStruct->orgResult == NULL) ? "" : *(const char **)returnStruct->orgResult); + pContext->StringToLocal(params[2], params[3], ((char *)returnStruct->orgResult == NULL) ? "" : (const char *)returnStruct->orgResult); return 1; default: return pContext->ThrowNativeError("Invalid param type to get. Param is not a string."); @@ -554,12 +554,12 @@ cell_t Native_SetReturnString(IPluginContext *pContext, const cell_t *params) switch(returnStruct->type) { case ReturnType_CharPtr: - *(char **)returnStruct->newResult = new char[strlen(value)+1]; - strcpy(*(char **)returnStruct->newResult, value); + returnStruct->newResult = new char[strlen(value)+1]; + strcpy((char *)returnStruct->newResult, value); returnStruct->isChanged = true; return 1; default: - return pContext->ThrowNativeError("Invalid param type to get. Param is not a string."); + return pContext->ThrowNativeError("Invalid param type to get. Param is not a char pointer."); } } @@ -950,11 +950,19 @@ cell_t Native_GetReturnVector(IPluginContext *pContext, const cell_t *params) cell_t *buffer; pContext->LocalToPhysAddr(params[2], &buffer); - if(returnStruct->type == ReturnType_Vector || returnStruct->type == ReturnType_VectorPtr) + if(returnStruct->type == ReturnType_Vector) { - buffer[0] = sp_ftoc((*(Vector **)returnStruct->orgResult)->x); - buffer[1] = sp_ftoc((*(Vector **)returnStruct->orgResult)->y); - buffer[2] = sp_ftoc((*(Vector **)returnStruct->orgResult)->z); + buffer[0] = sp_ftoc((*(Vector *)returnStruct->orgResult).x); + buffer[1] = sp_ftoc((*(Vector *)returnStruct->orgResult).y); + buffer[2] = sp_ftoc((*(Vector *)returnStruct->orgResult).z); + + return 1; + } + else if(returnStruct->type == ReturnType_VectorPtr) + { + buffer[0] = sp_ftoc(((Vector *)returnStruct->orgResult)->x); + buffer[1] = sp_ftoc(((Vector *)returnStruct->orgResult)->y); + buffer[2] = sp_ftoc(((Vector *)returnStruct->orgResult)->z); return 1; } @@ -974,17 +982,16 @@ cell_t Native_SetReturnVector(IPluginContext *pContext, const cell_t *params) cell_t *buffer; pContext->LocalToPhysAddr(params[2], &buffer); - if(returnStruct->type == ReturnType_Vector || returnStruct->type == ReturnType_VectorPtr) + if(returnStruct->type == ReturnType_Vector) { - if(*(Vector **)returnStruct->newResult != NULL) - { - delete *(Vector **)returnStruct->newResult; - } - - *(Vector **)returnStruct->newResult = new Vector(sp_ctof(buffer[0]), sp_ctof(buffer[1]), sp_ctof(buffer[2])); + *(Vector *)returnStruct->newResult = Vector(sp_ctof(buffer[0]), sp_ctof(buffer[1]), sp_ctof(buffer[2])); return 1; } + else if(returnStruct->type == ReturnType_VectorPtr) + { + returnStruct->newResult = new Vector(sp_ctof(buffer[0]), sp_ctof(buffer[1]), sp_ctof(buffer[2])); + } return pContext->ThrowNativeError("Return type is not a vector type"); } diff --git a/vhook.cpp b/vhook.cpp index e6dddae..ed44086 100644 --- a/vhook.cpp +++ b/vhook.cpp @@ -158,35 +158,43 @@ HookReturnStruct *GetReturnStruct(DHooksCallback *dg) HookReturnStruct *res = new HookReturnStruct(); res->isChanged = false; res->type = dg->returnType; - res->newResult = malloc(sizeof(void *)); - *(void **)res->newResult = NULL; - res->orgResult = malloc(sizeof(void *)); + res->orgResult = NULL; + res->newResult = NULL; if(g_SHPtr->GetOrigRet() && dg->post) { switch(dg->returnType) { case ReturnType_String: + res->orgResult = malloc(sizeof(string_t)); + res->newResult = malloc(sizeof(string_t)); *(string_t *)res->orgResult = META_RESULT_ORIG_RET(string_t); break; case ReturnType_Int: + res->orgResult = malloc(sizeof(int)); + res->newResult = malloc(sizeof(int)); *(int *)res->orgResult = META_RESULT_ORIG_RET(int); break; case ReturnType_Bool: + res->orgResult = malloc(sizeof(bool)); + res->newResult = malloc(sizeof(bool)); *(bool *)res->orgResult = META_RESULT_ORIG_RET(bool); break; case ReturnType_Float: + res->orgResult = malloc(sizeof(float)); + res->newResult = malloc(sizeof(float)); *(float *)res->orgResult = META_RESULT_ORIG_RET(float); break; case ReturnType_Vector: { + res->orgResult = malloc(sizeof(Vector)); + res->newResult = malloc(sizeof(Vector)); Vector vec = META_RESULT_ORIG_RET(Vector); - *(Vector **)res->orgResult = new Vector(vec); + *(Vector *)res->orgResult = vec; break; } default: - *(void **)res->orgResult = malloc(sizeof(void **)); - *(void **)res->orgResult = META_RESULT_ORIG_RET(void *); + res->orgResult = META_RESULT_ORIG_RET(void *); break; } } @@ -195,26 +203,40 @@ HookReturnStruct *GetReturnStruct(DHooksCallback *dg) switch(dg->returnType) { case ReturnType_String: + res->orgResult = malloc(sizeof(string_t)); + res->newResult = malloc(sizeof(string_t)); *(string_t *)res->orgResult = NULL_STRING; break; - //ReturnType_Vector, + case ReturnType_Vector: + res->orgResult = malloc(sizeof(Vector)); + res->newResult = malloc(sizeof(Vector)); + *(Vector *)res->orgResult = Vector(); + break; case ReturnType_Int: + res->orgResult = malloc(sizeof(int)); + res->newResult = malloc(sizeof(int)); *(int *)res->orgResult = 0; break; case ReturnType_Bool: + res->orgResult = malloc(sizeof(bool)); + res->newResult = malloc(sizeof(bool)); *(bool *)res->orgResult = false; break; case ReturnType_Float: + res->orgResult = malloc(sizeof(float)); + res->newResult = malloc(sizeof(float)); *(float *)res->orgResult = 0.0; break; default: - *(void **)res->orgResult = NULL; + res->orgResult = malloc(sizeof(void *)); + res->orgResult = NULL; break; } } return res; } + cell_t GetThisPtr(void *iface, ThisPointerType type) { if(type == ThisPointer_CBaseEntity) @@ -309,7 +331,14 @@ void *Callback(DHooksCallback *dg, void **argStack) { if(returnStruct->isChanged) { - ret = *(void **)returnStruct->newResult; + if(dg->returnType == ReturnType_String || dg->returnType == ReturnType_Int || dg->returnType == ReturnType_Bool) + { + ret = *(void **)returnStruct->newResult; + } + else + { + ret = returnStruct->newResult; + } } else //Throw an error if no override was set { @@ -331,7 +360,14 @@ void *Callback(DHooksCallback *dg, void **argStack) { g_SHPtr->SetRes(MRES_OVERRIDE); mres = MRES_OVERRIDE; - ret = *(void **)returnStruct->newResult; + if(dg->returnType == ReturnType_String || dg->returnType == ReturnType_Int || dg->returnType == ReturnType_Bool) + { + ret = *(void **)returnStruct->newResult; + } + else + { + ret = returnStruct->newResult; + } } else //Throw an error if no override was set { @@ -348,7 +384,14 @@ void *Callback(DHooksCallback *dg, void **argStack) { g_SHPtr->SetRes(MRES_SUPERCEDE); mres = MRES_SUPERCEDE; - ret = *(void **)returnStruct->newResult; + if(dg->returnType == ReturnType_String || dg->returnType == ReturnType_Int || dg->returnType == ReturnType_Bool) + { + ret = *(void **)returnStruct->newResult; + } + else + { + ret = returnStruct->newResult; + } } else //Throw an error if no override was set { diff --git a/vhook.h b/vhook.h index 7867bbd..fb6260c 100644 --- a/vhook.h +++ b/vhook.h @@ -91,30 +91,23 @@ class HookReturnStruct public: ~HookReturnStruct() { - if(this->type != ReturnType_CharPtr && this->type != ReturnType_Vector && this->type != ReturnType_VectorPtr) + if(this->type == ReturnType_String || this->type == ReturnType_Int || this->type == ReturnType_Bool || this->type == ReturnType_Float || this->type == ReturnType_Vector) { free(this->newResult); + free(this->orgResult); } else if(this->isChanged) { if(this->type == ReturnType_CharPtr) { - delete *(char **)this->newResult; + delete [] (char *)this->newResult; } - else if(this->type == ReturnType_Vector || this->type == ReturnType_VectorPtr) + else if(this->type == ReturnType_VectorPtr) { - delete *(Vector **)this->newResult; + delete (Vector *)this->newResult; } } - if(this->type == ReturnType_Vector || this->type == ReturnType_VectorPtr) - { - delete *(Vector **)this->orgResult; - } - else if(this->type != ReturnType_String && this->type != ReturnType_Int && this->type != ReturnType_Bool && this->type != ReturnType_Float) - { - free(*(void **)this->orgResult); - } - free(this->orgResult); + } public: ReturnType type;