- ACS stack checking (proxy commit by Rachael)

This commit is contained in:
alexey.lysiuk 2018-01-03 23:28:48 -05:00 committed by Rachael Alexanderson
parent 6aa724a9b4
commit 4b044e30d7

View file

@ -851,9 +851,25 @@ FWorldGlobalArray ACS_GlobalArrays[NUM_GLOBALVARS];
// //
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
struct FACSStackMemory
{
int32_t& operator[](const size_t index)
{
if (index >= STACK_SIZE)
{
I_Error("Corrupted stack pointer in ACS VM");
}
return buffer[index];
}
private:
int32_t buffer[STACK_SIZE];
};
struct FACSStack struct FACSStack
{ {
int32_t buffer[STACK_SIZE]; FACSStackMemory buffer;
int sp; int sp;
FACSStack *next; FACSStack *next;
FACSStack *prev; FACSStack *prev;
@ -1488,7 +1504,20 @@ void P_CollectACSGlobalStrings()
{ {
for (FACSStack *stack = FACSStack::head; stack != NULL; stack = stack->next) for (FACSStack *stack = FACSStack::head; stack != NULL; stack = stack->next)
{ {
GlobalACSStrings.MarkStringArray(stack->buffer, stack->sp); const int32_t sp = stack->sp;
if (0 == sp)
{
continue;
}
else if (sp < 0 && sp >= STACK_SIZE)
{
I_Error("Corrupted stack pointer in ACS VM");
}
else
{
GlobalACSStrings.MarkStringArray(&stack->buffer[0], sp);
}
} }
FBehavior::StaticMarkLevelVarStrings(); FBehavior::StaticMarkLevelVarStrings();
P_MarkWorldVarStrings(); P_MarkWorldVarStrings();
@ -6889,7 +6918,7 @@ inline int getshort (int *&pc)
return res; return res;
} }
static bool CharArrayParms(int &capacity, int &offset, int &a, int *Stack, int &sp, bool ranged) static bool CharArrayParms(int &capacity, int &offset, int &a, FACSStackMemory& Stack, int &sp, bool ranged)
{ {
if (ranged) if (ranged)
{ {
@ -7012,7 +7041,7 @@ int DLevelScript::RunScript ()
} }
FACSStack stackobj; FACSStack stackobj;
int32_t *Stack = stackobj.buffer; FACSStackMemory& Stack = stackobj.buffer;
int &sp = stackobj.sp; int &sp = stackobj.sp;
int *pc = this->pc; int *pc = this->pc;
@ -7376,7 +7405,7 @@ int DLevelScript::RunScript ()
sp -= sizeof(CallReturn)/sizeof(int); sp -= sizeof(CallReturn)/sizeof(int);
retsp = &Stack[sp]; retsp = &Stack[sp];
activeBehavior->GetFunctionProfileData(activeFunction)->AddRun(runaway - ret->EntryInstrCount); activeBehavior->GetFunctionProfileData(activeFunction)->AddRun(runaway - ret->EntryInstrCount);
sp = int(locals - Stack); sp = int(locals - &Stack[0]);
pc = ret->ReturnModule->Ofs2PC(ret->ReturnAddress); pc = ret->ReturnModule->Ofs2PC(ret->ReturnAddress);
activeFunction = ret->ReturnFunction; activeFunction = ret->ReturnFunction;
activeBehavior = ret->ReturnModule; activeBehavior = ret->ReturnModule;