Lua: fix: ReadOnlyTable, existing keys could be written
Dieser Commit ist enthalten in:
Ursprung
919e2e2787
Commit
d9b121948f
@ -54,7 +54,7 @@ void Console::push(lua_State* L)
|
|||||||
lua_pushcfunction(L, fatal);
|
lua_pushcfunction(L, fatal);
|
||||||
lua_setfield(L, -2, "fatal");
|
lua_setfield(L, -2, "fatal");
|
||||||
|
|
||||||
ReadOnlyTable::setMetatable(L, -1);
|
ReadOnlyTable::wrap(L, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Console::log(lua_State* L, ::Console::Level level, const std::string& message)
|
void Console::log(lua_State* L, ::Console::Level level, const std::string& message)
|
||||||
|
|||||||
@ -98,7 +98,7 @@ struct Enum
|
|||||||
push(L, it.first);
|
push(L, it.first);
|
||||||
lua_setfield(L, -2, toUpper(it.second).c_str());
|
lua_setfield(L, -2, toUpper(it.second).c_str());
|
||||||
}
|
}
|
||||||
ReadOnlyTable::setMetatable(L, -1);
|
ReadOnlyTable::wrap(L, -1);
|
||||||
lua_setfield(L, -2, EnumName<T>::value);
|
lua_setfield(L, -2, EnumName<T>::value);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* This file is part of the traintastic source code.
|
* This file is part of the traintastic source code.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2019-2020 Reinder Feenstra
|
* Copyright (C) 2019-2021 Reinder Feenstra
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@ -29,29 +29,33 @@
|
|||||||
|
|
||||||
namespace Lua {
|
namespace Lua {
|
||||||
|
|
||||||
struct ReadOnlyTable
|
class ReadOnlyTable
|
||||||
{
|
{
|
||||||
static constexpr const char* metatableName = "read_only_table";
|
private:
|
||||||
|
static int __newindex(lua_State* L)
|
||||||
|
{
|
||||||
|
errorTableIsReadOnly(L);
|
||||||
|
}
|
||||||
|
|
||||||
static void setMetatable(lua_State* L, int index)
|
public:
|
||||||
{
|
static void wrap(lua_State* L, int index)
|
||||||
luaL_getmetatable(L, metatableName);
|
{
|
||||||
assert(lua_istable(L, -1)); // is type registered?
|
assert(lua_istable(L, index));
|
||||||
lua_setmetatable(L, index < 0 ? index - 1 : index);
|
lua_newtable(L); // create wrapper table
|
||||||
}
|
lua_newtable(L); // metatable for wrapper table
|
||||||
|
if(index < 0)
|
||||||
static int __newindex(lua_State* L)
|
index -= 2; // correct index if relative
|
||||||
{
|
lua_pushvalue(L, index); // copy source table (ref)
|
||||||
errorTableIsReadOnly(L);
|
lua_setfield(L, -2, "__index");
|
||||||
}
|
lua_pushcfunction(L, __newindex);
|
||||||
|
lua_setfield(L, -2, "__newindex");
|
||||||
static void registerType(lua_State* L)
|
lua_pushboolean(L, 0);
|
||||||
{
|
lua_setfield(L, -2, "__metatable");
|
||||||
luaL_newmetatable(L, metatableName);
|
lua_setmetatable(L, -2); // set metatable @ wrapper table
|
||||||
lua_pushcfunction(L, __newindex);
|
if(index < 0)
|
||||||
lua_setfield(L, -2, "__newindex");
|
index++; // correct index if relative
|
||||||
lua_pop(L, 1);
|
lua_replace(L, index); // replace source table by wrapper table
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -98,13 +98,13 @@ SandboxPtr Sandbox::create(Script& script)
|
|||||||
Enum<DecoderProtocol>::registerValues(L);
|
Enum<DecoderProtocol>::registerValues(L);
|
||||||
Enum<Direction>::registerValues(L);
|
Enum<Direction>::registerValues(L);
|
||||||
Enum<WorldEvent>::registerValues(L);
|
Enum<WorldEvent>::registerValues(L);
|
||||||
ReadOnlyTable::setMetatable(L, -1);
|
ReadOnlyTable::wrap(L, -1);
|
||||||
lua_setfield(L, -2, "enum");
|
lua_setfield(L, -2, "enum");
|
||||||
|
|
||||||
// add set values:
|
// add set values:
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
Set<WorldState>::registerValues(L);
|
Set<WorldState>::registerValues(L);
|
||||||
ReadOnlyTable::setMetatable(L, -1);
|
ReadOnlyTable::wrap(L, -1);
|
||||||
lua_setfield(L, -2, "set");
|
lua_setfield(L, -2, "set");
|
||||||
|
|
||||||
// let global _G point to itself:
|
// let global _G point to itself:
|
||||||
|
|||||||
@ -174,7 +174,7 @@ struct Set
|
|||||||
push(L, it.first);
|
push(L, it.first);
|
||||||
lua_setfield(L, -2, it.second);
|
lua_setfield(L, -2, it.second);
|
||||||
}
|
}
|
||||||
ReadOnlyTable::setMetatable(L, -1);
|
ReadOnlyTable::wrap(L, -1);
|
||||||
lua_setfield(L, -2, set_name_v<T>);
|
lua_setfield(L, -2, set_name_v<T>);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -37,7 +37,6 @@ static lua_State* createState()
|
|||||||
{
|
{
|
||||||
lua_State* L = newStateWithProtect();
|
lua_State* L = newStateWithProtect();
|
||||||
|
|
||||||
Lua::ReadOnlyTable::registerType(L);
|
|
||||||
Lua::Enum<T>::registerType(L);
|
Lua::Enum<T>::registerType(L);
|
||||||
|
|
||||||
lua_createtable(L, 0, 1);
|
lua_createtable(L, 0, 1);
|
||||||
|
|||||||
@ -35,7 +35,6 @@ static lua_State* createState()
|
|||||||
{
|
{
|
||||||
lua_State* L = newStateWithProtect();
|
lua_State* L = newStateWithProtect();
|
||||||
|
|
||||||
Lua::ReadOnlyTable::registerType(L);
|
|
||||||
Lua::Set<T>::registerType(L);
|
Lua::Set<T>::registerType(L);
|
||||||
|
|
||||||
lua_createtable(L, 0, 1);
|
lua_createtable(L, 0, 1);
|
||||||
|
|||||||
Laden…
x
In neuem Issue referenzieren
Einen Benutzer sperren