mirror of
				https://github.com/luanti-org/luanti.git
				synced 2025-11-04 01:05:48 +01:00 
			
		
		
		
	Use numeric indices and raw table access with LUA_REGISTRYINDEX
This commit is contained in:
		@@ -34,6 +34,27 @@ extern "C" {
 | 
			
		||||
 | 
			
		||||
#include "common/c_types.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
	Define our custom indices into the Lua registry table.
 | 
			
		||||
 | 
			
		||||
	Lua 5.2 and above define the LUA_RIDX_LAST macro. Only numbers above that
 | 
			
		||||
	may be used for custom indices, anything else is reserved.
 | 
			
		||||
 | 
			
		||||
	Lua 5.1 / LuaJIT do not use any numeric indices (only string indices),
 | 
			
		||||
	so we can use numeric indices freely.
 | 
			
		||||
*/
 | 
			
		||||
#ifdef LUA_RIDX_LAST
 | 
			
		||||
#define CUSTOM_RIDX_BASE ((LUA_RIDX_LAST)+1)
 | 
			
		||||
#else
 | 
			
		||||
#define CUSTOM_RIDX_BASE 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define CUSTOM_RIDX_SCRIPTAPI           (CUSTOM_RIDX_BASE)
 | 
			
		||||
#define CUSTOM_RIDX_GLOBALS_BACKUP      (CUSTOM_RIDX_BASE + 1)
 | 
			
		||||
#define CUSTOM_RIDX_CURRENT_MOD_NAME    (CUSTOM_RIDX_BASE + 2)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define PCALL_RESL(L, RES) do {                         \
 | 
			
		||||
	int result_ = (RES);                                \
 | 
			
		||||
	if (result_ != 0) {                                 \
 | 
			
		||||
 
 | 
			
		||||
@@ -52,13 +52,13 @@ public:
 | 
			
		||||
	{
 | 
			
		||||
		// Store current mod name in registry
 | 
			
		||||
		lua_pushstring(L, mod_name.c_str());
 | 
			
		||||
		lua_setfield(L, LUA_REGISTRYINDEX, SCRIPT_MOD_NAME_FIELD);
 | 
			
		||||
		lua_rawseti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME);
 | 
			
		||||
	}
 | 
			
		||||
	~ModNameStorer()
 | 
			
		||||
	{
 | 
			
		||||
		// Clear current mod name from registry
 | 
			
		||||
		lua_pushnil(L);
 | 
			
		||||
		lua_setfield(L, LUA_REGISTRYINDEX, SCRIPT_MOD_NAME_FIELD);
 | 
			
		||||
		lua_rawseti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME);
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -84,7 +84,7 @@ ScriptApiBase::ScriptApiBase()
 | 
			
		||||
 | 
			
		||||
	// Make the ScriptApiBase* accessible to ModApiBase
 | 
			
		||||
	lua_pushlightuserdata(m_luastack, this);
 | 
			
		||||
	lua_setfield(m_luastack, LUA_REGISTRYINDEX, "scriptapi");
 | 
			
		||||
	lua_rawseti(m_luastack, LUA_REGISTRYINDEX, CUSTOM_RIDX_SCRIPTAPI);
 | 
			
		||||
 | 
			
		||||
	// If we are using LuaJIT add a C++ wrapper function to catch
 | 
			
		||||
	// exceptions thrown in Lua -> C++ calls
 | 
			
		||||
 
 | 
			
		||||
@@ -36,7 +36,6 @@ extern "C" {
 | 
			
		||||
#define SCRIPTAPI_LOCK_DEBUG
 | 
			
		||||
#define SCRIPTAPI_DEBUG
 | 
			
		||||
 | 
			
		||||
#define SCRIPT_MOD_NAME_FIELD "current_mod_name"
 | 
			
		||||
// MUST be an invalid mod name so that mods can't
 | 
			
		||||
// use that name to bypass security!
 | 
			
		||||
#define BUILTIN_MOD_NAME "*builtin*"
 | 
			
		||||
 
 | 
			
		||||
@@ -47,7 +47,7 @@ static inline void copy_safe(lua_State *L, const char *list[], unsigned len, int
 | 
			
		||||
// Pushes the original version of a library function on the stack, from the old version
 | 
			
		||||
static inline void push_original(lua_State *L, const char *lib, const char *func)
 | 
			
		||||
{
 | 
			
		||||
	lua_getfield(L, LUA_REGISTRYINDEX, "globals_backup");
 | 
			
		||||
	lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_GLOBALS_BACKUP);
 | 
			
		||||
	lua_getfield(L, -1, lib);
 | 
			
		||||
	lua_remove(L, -2);  // Remove globals_backup
 | 
			
		||||
	lua_getfield(L, -1, func);
 | 
			
		||||
@@ -143,7 +143,7 @@ void ScriptApiSecurity::initializeSecurity()
 | 
			
		||||
 | 
			
		||||
	// Backup globals to the registry
 | 
			
		||||
	lua_getglobal(L, "_G");
 | 
			
		||||
	lua_setfield(L, LUA_REGISTRYINDEX, "globals_backup");
 | 
			
		||||
	lua_rawseti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_GLOBALS_BACKUP);
 | 
			
		||||
 | 
			
		||||
	// Replace the global environment with an empty one
 | 
			
		||||
#if LUA_VERSION_NUM <= 501
 | 
			
		||||
@@ -165,7 +165,7 @@ void ScriptApiSecurity::initializeSecurity()
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	// Get old globals
 | 
			
		||||
	lua_getfield(L, LUA_REGISTRYINDEX, "globals_backup");
 | 
			
		||||
	lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_GLOBALS_BACKUP);
 | 
			
		||||
	int old_globals = lua_gettop(L);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -241,7 +241,7 @@ void ScriptApiSecurity::initializeSecurity()
 | 
			
		||||
 | 
			
		||||
bool ScriptApiSecurity::isSecure(lua_State *L)
 | 
			
		||||
{
 | 
			
		||||
	lua_getfield(L, LUA_REGISTRYINDEX, "globals_backup");
 | 
			
		||||
	lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_GLOBALS_BACKUP);
 | 
			
		||||
	bool secure = !lua_isnil(L, -1);
 | 
			
		||||
	lua_pop(L, 1);
 | 
			
		||||
	return secure;
 | 
			
		||||
@@ -356,7 +356,7 @@ bool ScriptApiSecurity::checkPath(lua_State *L, const char *path)
 | 
			
		||||
	if (!removed.empty()) abs_path += DIR_DELIM + removed;
 | 
			
		||||
 | 
			
		||||
	// Get server from registry
 | 
			
		||||
	lua_getfield(L, LUA_REGISTRYINDEX, "scriptapi");
 | 
			
		||||
	lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_SCRIPTAPI);
 | 
			
		||||
	ScriptApiBase *script = (ScriptApiBase *) lua_touserdata(L, -1);
 | 
			
		||||
	lua_pop(L, 1);
 | 
			
		||||
	const Server *server = script->getServer();
 | 
			
		||||
@@ -364,7 +364,7 @@ bool ScriptApiSecurity::checkPath(lua_State *L, const char *path)
 | 
			
		||||
	if (!server) return false;
 | 
			
		||||
 | 
			
		||||
	// Get mod name
 | 
			
		||||
	lua_getfield(L, LUA_REGISTRYINDEX, SCRIPT_MOD_NAME_FIELD);
 | 
			
		||||
	lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME);
 | 
			
		||||
	if (lua_isstring(L, -1)) {
 | 
			
		||||
		std::string mod_name = lua_tostring(L, -1);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -26,7 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
ScriptApiBase *ModApiBase::getScriptApiBase(lua_State *L)
 | 
			
		||||
{
 | 
			
		||||
	// Get server from registry
 | 
			
		||||
	lua_getfield(L, LUA_REGISTRYINDEX, "scriptapi");
 | 
			
		||||
	lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_SCRIPTAPI);
 | 
			
		||||
	ScriptApiBase *sapi_ptr = (ScriptApiBase*) lua_touserdata(L, -1);
 | 
			
		||||
	lua_pop(L, 1);
 | 
			
		||||
	return sapi_ptr;
 | 
			
		||||
@@ -49,7 +49,7 @@ GUIEngine *ModApiBase::getGuiEngine(lua_State *L)
 | 
			
		||||
 | 
			
		||||
std::string ModApiBase::getCurrentModPath(lua_State *L)
 | 
			
		||||
{
 | 
			
		||||
	lua_getfield(L, LUA_REGISTRYINDEX, SCRIPT_MOD_NAME_FIELD);
 | 
			
		||||
	lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME);
 | 
			
		||||
	const char *current_mod_name = lua_tostring(L, -1);
 | 
			
		||||
	if (!current_mod_name)
 | 
			
		||||
		return ".";
 | 
			
		||||
 
 | 
			
		||||
@@ -345,7 +345,7 @@ int ModApiServer::l_show_formspec(lua_State *L)
 | 
			
		||||
int ModApiServer::l_get_current_modname(lua_State *L)
 | 
			
		||||
{
 | 
			
		||||
	NO_MAP_LOCK_REQUIRED;
 | 
			
		||||
	lua_getfield(L, LUA_REGISTRYINDEX, SCRIPT_MOD_NAME_FIELD);
 | 
			
		||||
	lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME);
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -442,7 +442,7 @@ int ModApiServer::l_notify_authentication_modified(lua_State *L)
 | 
			
		||||
int ModApiServer::l_get_last_run_mod(lua_State *L)
 | 
			
		||||
{
 | 
			
		||||
	NO_MAP_LOCK_REQUIRED;
 | 
			
		||||
	lua_getfield(L, LUA_REGISTRYINDEX, SCRIPT_MOD_NAME_FIELD);
 | 
			
		||||
	lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME);
 | 
			
		||||
	const char *current_mod = lua_tostring(L, -1);
 | 
			
		||||
	if (current_mod == NULL || current_mod[0] == '\0') {
 | 
			
		||||
		lua_pop(L, 1);
 | 
			
		||||
 
 | 
			
		||||
@@ -371,7 +371,7 @@ int ModApiUtil::l_request_insecure_environment(lua_State *L)
 | 
			
		||||
		lua_getglobal(L, "_G");
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
	lua_getfield(L, LUA_REGISTRYINDEX, SCRIPT_MOD_NAME_FIELD);
 | 
			
		||||
	lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME);
 | 
			
		||||
	if (!lua_isstring(L, -1)) {
 | 
			
		||||
		lua_pushnil(L);
 | 
			
		||||
		return 1;
 | 
			
		||||
@@ -383,7 +383,7 @@ int ModApiUtil::l_request_insecure_environment(lua_State *L)
 | 
			
		||||
		lua_pushnil(L);
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
	lua_getfield(L, LUA_REGISTRYINDEX, "globals_backup");
 | 
			
		||||
	lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_GLOBALS_BACKUP);
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user