From 3046a7dd814fe623721e9e7b1b80798c48e3badc Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 15 Sep 2018 12:30:05 +0200 Subject: [PATCH] - be more thorough with 'in menu' checks for certain protected functions. They would also pass the test if a menu just was open but not the actual invoker. Also error out if this happens so that modders can see that they are doing unsupported things. Silent failure is not a good idea here. --- src/c_bind.cpp | 16 ++++++++++++++++ src/c_cvars.cpp | 28 ++++++++++++++++++++++++---- src/menu/menu.cpp | 7 +++++++ src/menu/menu.h | 1 + 4 files changed, 48 insertions(+), 4 deletions(-) diff --git a/src/c_bind.cpp b/src/c_bind.cpp index 1e4f7355d..1ed96dafb 100644 --- a/src/c_bind.cpp +++ b/src/c_bind.cpp @@ -45,6 +45,7 @@ #include "dobject.h" #include "vm.h" #include "i_time.h" +#include "menu/menu.h" const char *KeyNames[NUM_KEYS] = { @@ -267,6 +268,14 @@ DEFINE_ACTION_FUNCTION(FKeyBindings, SetBind) PARAM_SELF_STRUCT_PROLOGUE(FKeyBindings); PARAM_INT(k); PARAM_STRING(cmd); + + // Only menus are allowed to change bindings. + if (DMenu::InMenu == 0) + { + I_FatalError("Attempt to change key bindings outside of menu code to '%s'", cmd.GetChars()); + } + + self->SetBind(k, cmd); return 0; } @@ -506,6 +515,13 @@ DEFINE_ACTION_FUNCTION(FKeyBindings, UnbindACommand) { PARAM_SELF_STRUCT_PROLOGUE(FKeyBindings); PARAM_STRING(cmd); + + // Only menus are allowed to change bindings. + if (DMenu::InMenu == 0) + { + I_FatalError("Attempt to unbind key bindings for '%s' outside of menu code", cmd.GetChars()); + } + self->UnbindACommand(cmd); return 0; } diff --git a/src/c_cvars.cpp b/src/c_cvars.cpp index 605338b01..5be8a28a7 100644 --- a/src/c_cvars.cpp +++ b/src/c_cvars.cpp @@ -220,7 +220,14 @@ DEFINE_ACTION_FUNCTION(_CVar, SetInt) { // Only menus are allowed to change CVARs. PARAM_SELF_STRUCT_PROLOGUE(FBaseCVar); - if (!(self->GetFlags() & CVAR_MOD) && CurrentMenu == nullptr) return 0; + if (!(self->GetFlags() & CVAR_MOD)) + { + // Only menus are allowed to change non-mod CVARs. + if (DMenu::InMenu == 0) + { + I_FatalError("Attempt to change CVAR '%s' outside of menu code", self->GetName()); + } + } PARAM_INT(val); UCVarValue v; v.Int = val; @@ -230,9 +237,15 @@ DEFINE_ACTION_FUNCTION(_CVar, SetInt) DEFINE_ACTION_FUNCTION(_CVar, SetFloat) { - // Only menus are allowed to change CVARs. PARAM_SELF_STRUCT_PROLOGUE(FBaseCVar); - if (!(self->GetFlags() & CVAR_MOD) && CurrentMenu == nullptr) return 0; + if (!(self->GetFlags() & CVAR_MOD)) + { + // Only menus are allowed to change non-mod CVARs. + if (DMenu::InMenu == 0) + { + I_FatalError("Attempt to change CVAR '%s' outside of menu code", self->GetName()); + } + } PARAM_FLOAT(val); UCVarValue v; v.Float = (float)val; @@ -244,7 +257,14 @@ DEFINE_ACTION_FUNCTION(_CVar, SetString) { // Only menus are allowed to change CVARs. PARAM_SELF_STRUCT_PROLOGUE(FBaseCVar); - if (!(self->GetFlags() & CVAR_MOD) && CurrentMenu == nullptr) return 0; + if (!(self->GetFlags() & CVAR_MOD)) + { + // Only menus are allowed to change non-mod CVARs. + if (DMenu::InMenu == 0) + { + I_FatalError("Attempt to change CVAR '%s' outside of menu code", self->GetName()); + } + } PARAM_STRING(val); UCVarValue v; v.String = val.GetChars(); diff --git a/src/menu/menu.cpp b/src/menu/menu.cpp index 0613ec255..bcba95930 100644 --- a/src/menu/menu.cpp +++ b/src/menu/menu.cpp @@ -53,6 +53,7 @@ #include "events.h" #include "scripting/types.h" +int DMenu::InMenu; // // Todo: Move these elsewhere // @@ -190,7 +191,9 @@ bool DMenu::CallResponder(event_t *ev) VMValue params[] = { (DObject*)this, &e }; int retval; VMReturn ret(&retval); + InMenu++; VMCall(func, params, 2, &ret, 1); + InMenu--; return !!retval; } } @@ -202,7 +205,9 @@ bool DMenu::CallResponder(event_t *ev) VMValue params[] = { (DObject*)this, &e }; int retval; VMReturn ret(&retval); + InMenu++; VMCall(func, params, 2, &ret, 1); + InMenu--; return !!retval; } } @@ -222,7 +227,9 @@ bool DMenu::CallMenuEvent(int mkey, bool fromcontroller) VMValue params[] = { (DObject*)this, mkey, fromcontroller }; int retval; VMReturn ret(&retval); + InMenu++; VMCall(func, params, 3, &ret, 1); + InMenu--; return !!retval; } else return false; diff --git a/src/menu/menu.h b/src/menu/menu.h index 904ea0080..b374d29e1 100644 --- a/src/menu/menu.h +++ b/src/menu/menu.h @@ -265,6 +265,7 @@ public: bool mMouseCapture; bool mBackbuttonSelected; bool DontDim; + static int InMenu; DMenu(DMenu *parent = NULL); bool TranslateKeyboardEvents();