commit 1797341f9cefd83fb1ea2d01c8447023ed1a6e1c
Author: Simon Howard <fraggle@soulsphere.org>
AuthorDate: Fri Jan 5 01:09:08 2018 +0100
Commit: Simon Howard <fraggle@soulsphere.org>
CommitDate: Fri Jan 5 01:09:08 2018 +0100
hexen: Add assertion checking for ACS stack.
The vanilla ACS VM does not do any kind of bounds checking on the
stack, which has a limited size. If an attempt is made to exceed the
vanilla limits, exit with an error.
---
src/hexen/p_acs.c | 34 +++++++++++++++++++++++++++++++---
1 file changed, 31 insertions(+), 3 deletions(-)
diff --git a/src/hexen/p_acs.c b/src/hexen/p_acs.c
index 8a7bb313..6e549402 100644
--- a/src/hexen/p_acs.c
+++ b/src/hexen/p_acs.c
@@ -39,9 +39,6 @@
#define TEXTURE_TOP 0
#define TEXTURE_MIDDLE 1
#define TEXTURE_BOTTOM 2
-#define S_DROP ACScript->stackPtr--
-#define S_POP ACScript->stack[--ACScript->stackPtr]
-#define S_PUSH(x) ACScript->stack[ACScript->stackPtr++] = x
// TYPES -------------------------------------------------------------------
@@ -302,6 +299,31 @@ static int (*PCodeCmds[]) (void) =
// CODE --------------------------------------------------------------------
+//==========================================================================
+//
+// ACSAssert
+//
+// Check that the given condition evaluates to true. If it does not, exit
+// with an I_Error() printing the given message.
+//
+//==========================================================================
+
+static void ACSAssert(int condition, char *fmt, ...)
+{
+ char buf[128];
+ va_list args;
+
+ if (condition)
+ {
+ return;
+ }
+
+ va_start(args, fmt);
+ M_vsnprintf(buf, sizeof(buf), fmt, args);
+ va_end(args);
+ I_Error("ACS assertation failure: %s", buf);
+}
+
//==========================================================================
//
// P_LoadACScripts
@@ -810,6 +832,9 @@ void CheckACSPresent(int number)
static void Push(int value)
{
+ ACSAssert(ACScript->stackPtr < ACS_STACK_DEPTH,
+ "maximum stack depth exceeded: %d >= %d",
+ ACScript->stackPtr, ACS_STACK_DEPTH);
ACScript->stack[ACScript->stackPtr++] = value;
}
@@ -821,6 +846,7 @@ static void Push(int value)
static int Pop(void)
{
+ ACSAssert(ACScript->stackPtr > 0, "pop of empty stack");
return ACScript->stack[--ACScript->stackPtr];
}
@@ -832,6 +858,7 @@ static int Pop(void)
static int Top(void)
{
+ ACSAssert(ACScript->stackPtr > 0, "read from top of empty stack");
return ACScript->stack[ACScript->stackPtr - 1];
}
@@ -843,6 +870,7 @@ static int Top(void)
static void Drop(void)
{
+ ACSAssert(ACScript->stackPtr > 0, "drop on empty stack");
ACScript->stackPtr--;
}