- 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
parent 0a21d19723
commit cf590d73e4
4 changed files with 36 additions and 27 deletions

1
.gitignore vendored
View file

@ -56,3 +56,4 @@
/mapfiles_release/*.map
.DS_Store
/build_vc2017-32
/build2

View file

@ -119,28 +119,8 @@ void FState::SetAction(const char *name)
}
bool FState::CallAction(AActor *self, AActor *stateowner, FStateParamInfo *info, FState **stateret)
void FState::CheckCallerType(AActor *self, AActor *stateowner)
{
if (ActionFunc != nullptr)
{
ActionCycles.Clock();
VMValue params[3] = { self, stateowner, VMValue(info) };
// If the function returns a state, store it at *stateret.
// If it doesn't return a state but stateret is non-nullptr, we need
// to set *stateret to nullptr.
if (stateret != nullptr)
{
*stateret = nullptr;
if (ActionFunc->Proto == nullptr ||
ActionFunc->Proto->ReturnTypes.Size() == 0 ||
ActionFunc->Proto->ReturnTypes[0] != TypeState)
{
stateret = nullptr;
}
}
try
{
auto CheckType = [=](AActor *check, PType *requiredType)
{
// This should really never happen. Any valid action function must have actor pointers here.
@ -165,10 +145,34 @@ bool FState::CallAction(AActor *self, AActor *stateowner, FStateParamInfo *info,
{
CheckType(stateowner, argtypes[1]);
}
}
}
bool FState::CallAction(AActor *self, AActor *stateowner, FStateParamInfo *info, FState **stateret)
{
if (ActionFunc != nullptr)
{
ActionCycles.Clock();
VMValue params[3] = { self, stateowner, VMValue(info) };
// If the function returns a state, store it at *stateret.
// If it doesn't return a state but stateret is non-nullptr, we need
// to set *stateret to nullptr.
if (stateret != nullptr)
{
*stateret = nullptr;
if (ActionFunc->Proto == nullptr ||
ActionFunc->Proto->ReturnTypes.Size() == 0 ||
ActionFunc->Proto->ReturnTypes[0] != TypeState)
{
stateret = nullptr;
}
}
try
{
CheckCallerType(self, stateowner);
if (stateret == nullptr)
{
VMCall(ActionFunc, params, ActionFunc->ImplicitArgs, nullptr, 0);

View file

@ -175,10 +175,13 @@ public:
void ClearAction() { ActionFunc = NULL; }
void SetAction(const char *name);
bool CallAction(AActor *self, AActor *stateowner, FStateParamInfo *stateinfo, FState **stateret);
void CheckCallerType(AActor *self, AActor *stateowner);
static PClassActor *StaticFindStateOwner (const FState *state);
static PClassActor *StaticFindStateOwner (const FState *state, PClassActor *info);
static FString StaticGetStateName(const FState *state);
static FRandom pr_statetics;
};
struct FStateLabels;

View file

@ -169,6 +169,7 @@ bool AStateProvider::CallStateChain (AActor *actor, FState *state)
}
try
{
state->CheckCallerType(actor, this);
VMCall(state->ActionFunc, params, state->ActionFunc->ImplicitArgs, wantret, numret);
}
catch (CVMAbortException &err)