Skip to content

Commit

Permalink
Handle INVALID_FUNCTION mismatches at plugin boundaries, redux (#2136)
Browse files Browse the repository at this point in the history
  • Loading branch information
adriansmares committed Apr 20, 2024
1 parent d426d1f commit af93d81
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 12 deletions.
21 changes: 19 additions & 2 deletions core/logic/smn_datapacks.cpp
Expand Up @@ -244,7 +244,19 @@ static cell_t smn_WritePackFunction(IPluginContext *pContext, const cell_t *para
pDataPack->RemoveItem();
}

pDataPack->PackFunction(params[2]);
cell_t funcid = params[2];
if (pContext->IsNullFunctionId(funcid))
{
pDataPack->PackFunction(0);
}
else if (funcid <= 0)
{
return pContext->ThrowNativeError("Invalid function id (%X)", funcid);
}
else
{
pDataPack->PackFunction(funcid);
}

return 1;
}
Expand Down Expand Up @@ -365,7 +377,12 @@ static cell_t smn_ReadPackFunction(IPluginContext *pContext, const cell_t *param
return pContext->ThrowNativeError("Invalid data pack type (got %d / expected %d).", pDataPack->GetCurrentType(), CDataPackType::Function);
}

return pDataPack->ReadFunction();
cell_t funcid = pDataPack->ReadFunction();
if (!funcid)
{
return pContext->GetNullFunctionValue();
}
return funcid;
}

static cell_t smn_ReadPackCellArray(IPluginContext *pContext, const cell_t *params)
Expand Down
29 changes: 28 additions & 1 deletion core/logic/smn_fakenatives.cpp
Expand Up @@ -366,6 +366,33 @@ static cell_t SetNativeArray(IPluginContext *pContext, const cell_t *params)
return SP_ERROR_NONE;
}

static cell_t GetNativeFunction(IPluginContext *pContext, const cell_t *params)
{
if (!s_curnative || (s_curnative->ctx != pContext))
{
return pContext->ThrowNativeError("Not called from inside a native function");
}

cell_t param = params[1];
if (param < 1 || param > s_curparams[0])
{
return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", param);
}

cell_t funcid = s_curparams[param];
if (s_curcaller->IsNullFunctionId(funcid))
{
// see alliedmodders/sourcepawn#912, alliedmodders/sourcemod#2068
// convert null function to receiver's expected value so equality checks against INVALID_FUNCTION pass
return pContext->GetNullFunctionValue();
}
else if (funcid <= 0)
{
return pContext->ThrowNativeError("Invalid function id (%X)", funcid);
}
return funcid;
}

static cell_t FormatNativeString(IPluginContext *pContext, const cell_t *params)
{
if (!s_curnative || (s_curnative->ctx != pContext))
Expand Down Expand Up @@ -483,7 +510,7 @@ REGISTER_NATIVES(nativeNatives)
{"GetNativeArray", GetNativeArray},
{"GetNativeCell", GetNativeCell},
{"GetNativeCellRef", GetNativeCellRef},
{"GetNativeFunction", GetNativeCell},
{"GetNativeFunction", GetNativeFunction},
{"GetNativeString", GetNativeString},
{"GetNativeStringLength", GetNativeStringLength},
{"FormatNativeString", FormatNativeString},
Expand Down
30 changes: 21 additions & 9 deletions core/logic/smn_functions.cpp
Expand Up @@ -228,11 +228,15 @@ static cell_t sm_AddToForward(IPluginContext *pContext, const cell_t *params)
}
}

IPluginFunction *pFunction = pPlugin->GetBaseContext()->GetFunctionById(params[3]);

cell_t funcid = params[3];
if (funcid <= 0)
{
return pContext->ThrowNativeError("Invalid function id (%X)", funcid);
}
IPluginFunction *pFunction = pPlugin->GetBaseContext()->GetFunctionById(funcid);
if (!pFunction)
{
return pContext->ThrowNativeError("Invalid function id (%X)", params[3]);
return pContext->ThrowNativeError("Invalid function id (%X)", funcid);
}

return pForward->AddFunction(pFunction);
Expand Down Expand Up @@ -265,11 +269,15 @@ static cell_t sm_RemoveFromForward(IPluginContext *pContext, const cell_t *param
}
}

IPluginFunction *pFunction = pPlugin->GetBaseContext()->GetFunctionById(params[3]);

cell_t funcid = params[3];
if (funcid <= 0)
{
return pContext->ThrowNativeError("Invalid function id (%X)", funcid);
}
IPluginFunction *pFunction = pPlugin->GetBaseContext()->GetFunctionById(funcid);
if (!pFunction)
{
return pContext->ThrowNativeError("Invalid function id (%X)", params[3]);
return pContext->ThrowNativeError("Invalid function id (%X)", funcid);
}

return pForward->RemoveFunction(pFunction);
Expand Down Expand Up @@ -327,11 +335,15 @@ static cell_t sm_CallStartFunction(IPluginContext *pContext, const cell_t *param
}
}

s_pFunction = pPlugin->GetBaseContext()->GetFunctionById(params[2]);

cell_t funcid = params[2];
if (funcid <= 0)
{
return pContext->ThrowNativeError("Invalid function id (%X)", funcid);
}
s_pFunction = pPlugin->GetBaseContext()->GetFunctionById(funcid);
if (!s_pFunction)
{
return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
return pContext->ThrowNativeError("Invalid function id (%X)", funcid);
}

s_pCallable = static_cast<ICallable *>(s_pFunction);
Expand Down

0 comments on commit af93d81

Please sign in to comment.