From d0477515f30f0b2612f5de10f4531026dab2798e Mon Sep 17 00:00:00 2001
From: gumi <git@gumi.ca>
Date: Mon, 6 Jul 2020 18:07:56 +0000
Subject: ensure that returning builtins always return, else abort

---
 src/map/script-call.cpp | 22 ++++++++++++++++++++++
 src/map/script-fun.cpp  | 12 ++++++------
 2 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/src/map/script-call.cpp b/src/map/script-call.cpp
index 5541043..4de94d7 100644
--- a/src/map/script-call.cpp
+++ b/src/map/script-call.cpp
@@ -706,6 +706,28 @@ void run_func(ScriptState *st)
     }
     builtin_functions[func].func(st);
 
+    if (builtin_functions[func].ret != '\0') {
+        // this builtin is expected to return a value
+        script_data &back = st->stack->stack_datav.back();
+
+        if (builtin_functions[func].ret == 'i' && !back.is<ScriptDataInt>()) {
+            PRINTF("script-call:run_func: expected %s to push an integer but none was found. aborting script execution.\n"_fmt, builtin_functions[func].name);
+            st->state = ScriptEndState::END;
+        } else if (builtin_functions[func].ret == 's' && !back.is<ScriptDataStr>()) {
+            PRINTF("script-call:run_func: expected %s to push a string but none was found. aborting script execution.\n"_fmt, builtin_functions[func].name);
+            st->state = ScriptEndState::END;
+        } else if (builtin_functions[func].ret == 'v' && !back.is<ScriptDataStr>() && !back.is<ScriptDataInt>() && !back.is<ScriptDataParam>() && !back.is<ScriptDataVariable>()) {
+            PRINTF("script-call:run_func: expected %s to push a value but none was found. aborting script execution.\n"_fmt, builtin_functions[func].name);
+            st->state = ScriptEndState::END;
+        } else if (builtin_functions[func].ret == 'r' && !back.is<ScriptDataVariable>()) {
+            PRINTF("script-call:run_func: expected %s to push a variable reference but none was found. aborting script execution.\n"_fmt, builtin_functions[func].name);
+            st->state = ScriptEndState::END;
+        } else if (builtin_functions[func].ret == 'l' && !back.is<ScriptDataPos>()) {
+            PRINTF("script-call:run_func: expected %s to push a label pos but none was found. aborting script execution.\n"_fmt, builtin_functions[func].name);
+            st->state = ScriptEndState::END;
+        }
+    }
+
     pop_stack(st->stack, start_sp, end_sp);
 
     if (st->state == ScriptEndState::RETFUNC)
diff --git a/src/map/script-fun.cpp b/src/map/script-fun.cpp
index 610220d..b72be56 100644
--- a/src/map/script-fun.cpp
+++ b/src/map/script-fun.cpp
@@ -4757,7 +4757,7 @@ BuiltinFunction builtin_functions[] =
     BUILTIN(callfunc, "F"_s, '\0'),
     BUILTIN(call, "F?*"_s, '.'),
     BUILTIN(callsub, "L"_s, '\0'),
-    BUILTIN(getarg, "i?"_s, '.'),
+    BUILTIN(getarg, "i?"_s, 'v'),
     BUILTIN(return, "?"_s, '\0'),
     BUILTIN(void, "?*"_s, '\0'),
     BUILTIN(next, ""_s, '\0'),
@@ -4777,11 +4777,11 @@ BuiltinFunction builtin_functions[] =
     BUILTIN(elif, "iF*"_s, '\0'),
     BUILTIN(else, "F*"_s, '\0'),
     BUILTIN(set, "Ne?"_s, '\0'),
-    BUILTIN(get, "Ne"_s, '.'),
+    BUILTIN(get, "Ne"_s, 'v'),
     BUILTIN(setarray, "Ne*"_s, '\0'),
     BUILTIN(cleararray, "Nei"_s, '\0'),
     BUILTIN(getarraysize, "N"_s, 'i'),
-    BUILTIN(getelementofarray, "Ni"_s, '.'),
+    BUILTIN(getelementofarray, "Ni"_s, 'v'),
     BUILTIN(array_search, "eN"_s, 'i'),
     BUILTIN(setlook, "ii"_s, '\0'),
     BUILTIN(countitem, "I"_s, 'i'),
@@ -4880,7 +4880,7 @@ BuiltinFunction builtin_functions[] =
     BUILTIN(mapmask, "i?"_s, '\0'),
     BUILTIN(getmask, ""_s, 'i'),
     BUILTIN(getlook, "i"_s, 'i'),
-    BUILTIN(getsavepoint, "i"_s, '.'),
+    BUILTIN(getsavepoint, "i"_s, 'v'),
     BUILTIN(areatimer, "MxyxytEi"_s, '\0'),
     BUILTIN(foreach, "iMxyxyE?"_s, '\0'),
     BUILTIN(isin, "Mxyxy"_s, 'i'),
@@ -4900,7 +4900,7 @@ BuiltinFunction builtin_functions[] =
     BUILTIN(getmap, "?"_s, 's'),
     BUILTIN(mapexit, ""_s, '\0'),
     BUILTIN(freeloop, "i"_s, '\0'),
-    BUILTIN(if_then_else, "iii"_s, '.'),
+    BUILTIN(if_then_else, "iii"_s, 'v'),
     BUILTIN(max, "e?*"_s, 'i'),
     BUILTIN(min, "e?*"_s, 'i'),
     BUILTIN(average, "ii*"_s, 'i'),
@@ -4909,7 +4909,7 @@ BuiltinFunction builtin_functions[] =
     BUILTIN(pow, "ii"_s, 'i'),
     BUILTIN(target, "iii"_s, 'i'),
     BUILTIN(distance, "ii?"_s, 'i'),
-    BUILTIN(chr, "i"_s, 'i'),
+    BUILTIN(chr, "i"_s, 's'),
     BUILTIN(ord, "s"_s, 'i'),
     {nullptr, ""_s, ""_s, '\0'},
 };
-- 
cgit v1.2.3-70-g09d2