]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-lua: Add function for restricting global variable definition
authorSiavash Tavakoli <siavash.tavakoli@open-xchange.com>
Sun, 5 Sep 2021 23:49:06 +0000 (00:49 +0100)
committertimo.sirainen <timo.sirainen@open-xchange.com>
Fri, 17 Sep 2021 11:47:15 +0000 (11:47 +0000)
Add "dovecot.restrict_global_variables()" with a boolean argument to mitigate
unintended variable assignments and to prevent unnecessarily populating
global namespace.

If enabled, variables can only be defined local to the script but global
functions are still allowed.

src/lib-lua/dlua-dovecot.c

index 991ce259757087c9f1b985aa4e442e17f1fb75b6..f011315ce115002f189f55bf993946c66c6335a9 100644 (file)
@@ -572,6 +572,52 @@ static int dlua_clear_flag(lua_State *L)
        return 1;
 }
 
+static int dlua_script_strict_index(lua_State *L)
+{
+       DLUA_REQUIRE_ARGS(L, 2);
+       const char *name = luaL_checkstring(L, 2);
+       return luaL_error(L, "attempt to write to read undeclared global variable %s",
+                         name);
+}
+
+static int dlua_script_strict_newindex(lua_State *L)
+{
+       DLUA_REQUIRE_ARGS(L, 3);
+       if (lua_type(L, 3) == LUA_TFUNCTION) {
+               /* allow defining global functions */
+               lua_rawset(L, 1);
+       } else {
+               const char *name = luaL_checkstring(L, 2);
+               return luaL_error(L, "attempt to write to undeclared global variable %s",
+                                 name);
+       }
+       return 0;
+}
+
+static luaL_Reg env_strict_metamethods[] = {
+       { "__index", dlua_script_strict_index },
+       { "__newindex", dlua_script_strict_newindex },
+       { NULL, NULL }
+};
+
+static int dlua_restrict_global_variables(lua_State *L)
+{
+       DLUA_REQUIRE_ARGS(L, 1);
+
+       if (lua_toboolean(L, 1)) {
+               /* disable defining global variables */
+               lua_getglobal(L, "_G");
+               lua_newtable(L);
+               luaL_setfuncs(L, env_strict_metamethods, 0);
+       } else {
+               /* revert restrictions */
+               lua_getglobal(L, "_G");
+               lua_newtable(L);
+       }
+       lua_setmetatable(L, -2);
+       lua_pop(L, 1);
+       return 0;
+}
 
 static luaL_Reg lua_dovecot_methods[] = {
        { "i_debug", dlua_i_debug },
@@ -582,6 +628,7 @@ static luaL_Reg lua_dovecot_methods[] = {
        { "has_flag", dlua_has_flag },
        { "set_flag", dlua_set_flag },
        { "clear_flag", dlua_clear_flag },
+       { "restrict_global_variables", dlua_restrict_global_variables },
        { NULL, NULL }
 };