Handle INVALID_FUNCTION mismatches at plugin boundaries, redux (#2136)

This commit is contained in:
Adrian-Stefan Mares 2024-04-20 03:56:48 +02:00 committed by GitHub
parent d426d1f04f
commit af93d819c6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 68 additions and 12 deletions

View File

@ -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;
}
@ -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)

View File

@ -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))
@ -483,7 +510,7 @@ REGISTER_NATIVES(nativeNatives)
{"GetNativeArray", GetNativeArray},
{"GetNativeCell", GetNativeCell},
{"GetNativeCellRef", GetNativeCellRef},
{"GetNativeFunction", GetNativeCell},
{"GetNativeFunction", GetNativeFunction},
{"GetNativeString", GetNativeString},
{"GetNativeStringLength", GetNativeStringLength},
{"FormatNativeString", FormatNativeString},

View File

@ -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);
@ -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);
@ -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);