Fix pointer returns being incorrectly set and freed.

This commit is contained in:
Dr!fter 2015-05-14 12:03:48 -04:00
parent 46af85d743
commit c04ce19b7c
3 changed files with 87 additions and 44 deletions

View File

@ -360,9 +360,9 @@ cell_t Native_GetReturn(IPluginContext *pContext, const cell_t *params)
case ReturnType_Bool: case ReturnType_Bool:
return *(bool *)returnStruct->orgResult? 1 : 0; return *(bool *)returnStruct->orgResult? 1 : 0;
case ReturnType_CBaseEntity: case ReturnType_CBaseEntity:
return gamehelpers->EntityToBCompatRef(*(CBaseEntity **)returnStruct->orgResult); return gamehelpers->EntityToBCompatRef((CBaseEntity *)returnStruct->orgResult);
case ReturnType_Edict: case ReturnType_Edict:
return gamehelpers->IndexOfEdict(*(edict_t **)returnStruct->orgResult); return gamehelpers->IndexOfEdict((edict_t *)returnStruct->orgResult);
case ReturnType_Float: case ReturnType_Float:
return sp_ftoc(*(float *)returnStruct->orgResult); return sp_ftoc(*(float *)returnStruct->orgResult);
default: 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"); return pContext->ThrowNativeError("Invalid entity index passed for return value");
} }
*(CBaseEntity **)returnStruct->newResult = pEnt; returnStruct->newResult = pEnt;
break; break;
} }
case ReturnType_Edict: 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"); pContext->ThrowNativeError("Invalid entity index passed for return value");
} }
*(edict_t **)returnStruct->newResult = pEdict; returnStruct->newResult = pEdict;
break; break;
} }
case ReturnType_Float: 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)); pContext->StringToLocal(params[2], params[3], (*(string_t *)returnStruct->orgResult == NULL_STRING) ? "" : STRING(*(string_t *)returnStruct->orgResult));
return 1; return 1;
case ReturnType_StringPtr: 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; return 1;
case ReturnType_CharPtr: 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; return 1;
default: 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 string.");
@ -554,12 +554,12 @@ cell_t Native_SetReturnString(IPluginContext *pContext, const cell_t *params)
switch(returnStruct->type) switch(returnStruct->type)
{ {
case ReturnType_CharPtr: case ReturnType_CharPtr:
*(char **)returnStruct->newResult = new char[strlen(value)+1]; returnStruct->newResult = new char[strlen(value)+1];
strcpy(*(char **)returnStruct->newResult, value); strcpy((char *)returnStruct->newResult, value);
returnStruct->isChanged = true; returnStruct->isChanged = true;
return 1; return 1;
default: 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; cell_t *buffer;
pContext->LocalToPhysAddr(params[2], &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[0] = sp_ftoc((*(Vector *)returnStruct->orgResult).x);
buffer[1] = sp_ftoc((*(Vector **)returnStruct->orgResult)->y); buffer[1] = sp_ftoc((*(Vector *)returnStruct->orgResult).y);
buffer[2] = sp_ftoc((*(Vector **)returnStruct->orgResult)->z); 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; return 1;
} }
@ -974,17 +982,16 @@ cell_t Native_SetReturnVector(IPluginContext *pContext, const cell_t *params)
cell_t *buffer; cell_t *buffer;
pContext->LocalToPhysAddr(params[2], &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) *(Vector *)returnStruct->newResult = Vector(sp_ctof(buffer[0]), sp_ctof(buffer[1]), sp_ctof(buffer[2]));
{
delete *(Vector **)returnStruct->newResult;
}
*(Vector **)returnStruct->newResult = new Vector(sp_ctof(buffer[0]), sp_ctof(buffer[1]), sp_ctof(buffer[2]));
return 1; 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"); return pContext->ThrowNativeError("Return type is not a vector type");
} }

View File

@ -158,35 +158,43 @@ HookReturnStruct *GetReturnStruct(DHooksCallback *dg)
HookReturnStruct *res = new HookReturnStruct(); HookReturnStruct *res = new HookReturnStruct();
res->isChanged = false; res->isChanged = false;
res->type = dg->returnType; res->type = dg->returnType;
res->newResult = malloc(sizeof(void *)); res->orgResult = NULL;
*(void **)res->newResult = NULL; res->newResult = NULL;
res->orgResult = malloc(sizeof(void *));
if(g_SHPtr->GetOrigRet() && dg->post) if(g_SHPtr->GetOrigRet() && dg->post)
{ {
switch(dg->returnType) switch(dg->returnType)
{ {
case ReturnType_String: 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); *(string_t *)res->orgResult = META_RESULT_ORIG_RET(string_t);
break; break;
case ReturnType_Int: case ReturnType_Int:
res->orgResult = malloc(sizeof(int));
res->newResult = malloc(sizeof(int));
*(int *)res->orgResult = META_RESULT_ORIG_RET(int); *(int *)res->orgResult = META_RESULT_ORIG_RET(int);
break; break;
case ReturnType_Bool: case ReturnType_Bool:
res->orgResult = malloc(sizeof(bool));
res->newResult = malloc(sizeof(bool));
*(bool *)res->orgResult = META_RESULT_ORIG_RET(bool); *(bool *)res->orgResult = META_RESULT_ORIG_RET(bool);
break; break;
case ReturnType_Float: case ReturnType_Float:
res->orgResult = malloc(sizeof(float));
res->newResult = malloc(sizeof(float));
*(float *)res->orgResult = META_RESULT_ORIG_RET(float); *(float *)res->orgResult = META_RESULT_ORIG_RET(float);
break; break;
case ReturnType_Vector: case ReturnType_Vector:
{ {
res->orgResult = malloc(sizeof(Vector));
res->newResult = malloc(sizeof(Vector));
Vector vec = META_RESULT_ORIG_RET(Vector); Vector vec = META_RESULT_ORIG_RET(Vector);
*(Vector **)res->orgResult = new Vector(vec); *(Vector *)res->orgResult = vec;
break; break;
} }
default: default:
*(void **)res->orgResult = malloc(sizeof(void **)); res->orgResult = META_RESULT_ORIG_RET(void *);
*(void **)res->orgResult = META_RESULT_ORIG_RET(void *);
break; break;
} }
} }
@ -195,26 +203,40 @@ HookReturnStruct *GetReturnStruct(DHooksCallback *dg)
switch(dg->returnType) switch(dg->returnType)
{ {
case ReturnType_String: case ReturnType_String:
res->orgResult = malloc(sizeof(string_t));
res->newResult = malloc(sizeof(string_t));
*(string_t *)res->orgResult = NULL_STRING; *(string_t *)res->orgResult = NULL_STRING;
break; break;
//ReturnType_Vector, case ReturnType_Vector:
res->orgResult = malloc(sizeof(Vector));
res->newResult = malloc(sizeof(Vector));
*(Vector *)res->orgResult = Vector();
break;
case ReturnType_Int: case ReturnType_Int:
res->orgResult = malloc(sizeof(int));
res->newResult = malloc(sizeof(int));
*(int *)res->orgResult = 0; *(int *)res->orgResult = 0;
break; break;
case ReturnType_Bool: case ReturnType_Bool:
res->orgResult = malloc(sizeof(bool));
res->newResult = malloc(sizeof(bool));
*(bool *)res->orgResult = false; *(bool *)res->orgResult = false;
break; break;
case ReturnType_Float: case ReturnType_Float:
res->orgResult = malloc(sizeof(float));
res->newResult = malloc(sizeof(float));
*(float *)res->orgResult = 0.0; *(float *)res->orgResult = 0.0;
break; break;
default: default:
*(void **)res->orgResult = NULL; res->orgResult = malloc(sizeof(void *));
res->orgResult = NULL;
break; break;
} }
} }
return res; return res;
} }
cell_t GetThisPtr(void *iface, ThisPointerType type) cell_t GetThisPtr(void *iface, ThisPointerType type)
{ {
if(type == ThisPointer_CBaseEntity) if(type == ThisPointer_CBaseEntity)
@ -309,7 +331,14 @@ void *Callback(DHooksCallback *dg, void **argStack)
{ {
if(returnStruct->isChanged) 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 else //Throw an error if no override was set
{ {
@ -331,7 +360,14 @@ void *Callback(DHooksCallback *dg, void **argStack)
{ {
g_SHPtr->SetRes(MRES_OVERRIDE); g_SHPtr->SetRes(MRES_OVERRIDE);
mres = 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 else //Throw an error if no override was set
{ {
@ -348,7 +384,14 @@ void *Callback(DHooksCallback *dg, void **argStack)
{ {
g_SHPtr->SetRes(MRES_SUPERCEDE); g_SHPtr->SetRes(MRES_SUPERCEDE);
mres = 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 else //Throw an error if no override was set
{ {

19
vhook.h
View File

@ -91,30 +91,23 @@ class HookReturnStruct
public: public:
~HookReturnStruct() ~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->newResult);
free(this->orgResult);
} }
else if(this->isChanged) else if(this->isChanged)
{ {
if(this->type == ReturnType_CharPtr) 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: public:
ReturnType type; ReturnType type;