- extended state caller check to work on CustomInventory items as well

Since CallStateChain is a public member in CustomInventory we cannot really be sure that the given state is valid so it needs checking as well.
This commit is contained in:
Christoph Oelckers 2018-11-15 09:24:17 +01:00
commit cf590d73e4
4 changed files with 36 additions and 27 deletions

View file

@ -119,6 +119,36 @@ void FState::SetAction(const char *name)
}
void FState::CheckCallerType(AActor *self, AActor *stateowner)
{
auto CheckType = [=](AActor *check, PType *requiredType)
{
// This should really never happen. Any valid action function must have actor pointers here.
if (!requiredType->isObjectPointer())
{
ThrowAbortException(X_OTHER, "Bad function prototype in function call to %s", ActionFunc->PrintableName.GetChars());
}
auto cls = static_cast<PObjectPointer*>(requiredType)->PointedClass();
if (!check->IsKindOf(cls))
{
ThrowAbortException(X_OTHER, "Invalid class %s in function call to %s. %s expected", check->GetClass()->TypeName.GetChars(), ActionFunc->PrintableName.GetChars(), cls->TypeName.GetChars());
}
};
if (ActionFunc->ImplicitArgs >= 1)
{
auto argtypes = ActionFunc->Proto->ArgumentTypes;
CheckType(self, argtypes[0]);
if (ActionFunc->ImplicitArgs >= 2)
{
CheckType(stateowner, argtypes[1]);
}
}
}
bool FState::CallAction(AActor *self, AActor *stateowner, FStateParamInfo *info, FState **stateret)
{
if (ActionFunc != nullptr)
@ -141,33 +171,7 @@ bool FState::CallAction(AActor *self, AActor *stateowner, FStateParamInfo *info,
}
try
{
auto CheckType = [=](AActor *check, PType *requiredType)
{
// This should really never happen. Any valid action function must have actor pointers here.
if (!requiredType->isObjectPointer())
{
ThrowAbortException(X_OTHER, "Bad function prototype in function call to %s", ActionFunc->PrintableName.GetChars());
}
auto cls = static_cast<PObjectPointer*>(requiredType)->PointedClass();
if (!check->IsKindOf(cls))
{
ThrowAbortException(X_OTHER, "Invalid class %s in function call to %s. %s expected", check->GetClass()->TypeName.GetChars(), ActionFunc->PrintableName.GetChars(), cls->TypeName.GetChars());
}
};
if (ActionFunc->ImplicitArgs >= 1)
{
auto argtypes = ActionFunc->Proto->ArgumentTypes;
CheckType(self, argtypes[0]);
if (ActionFunc->ImplicitArgs >= 2)
{
CheckType(stateowner, argtypes[1]);
}
}
CheckCallerType(self, stateowner);
if (stateret == nullptr)
{