Lua: fix: ReadOnlyTable, existing keys could be written

Dieser Commit ist enthalten in:
Reinder Feenstra 2021-04-22 23:28:41 +02:00
Ursprung 919e2e2787
Commit d9b121948f
7 geänderte Dateien mit 31 neuen und 29 gelöschten Zeilen

Datei anzeigen

@ -54,7 +54,7 @@ void Console::push(lua_State* L)
lua_pushcfunction(L, 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)

Datei anzeigen

@ -98,7 +98,7 @@ struct Enum
push(L, it.first);
lua_setfield(L, -2, toUpper(it.second).c_str());
}
ReadOnlyTable::setMetatable(L, -1);
ReadOnlyTable::wrap(L, -1);
lua_setfield(L, -2, EnumName<T>::value);
}
};

Datei anzeigen

@ -3,7 +3,7 @@
*
* 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
* modify it under the terms of the GNU General Public License
@ -29,29 +29,33 @@
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)
{
luaL_getmetatable(L, metatableName);
assert(lua_istable(L, -1)); // is type registered?
lua_setmetatable(L, index < 0 ? index - 1 : index);
}
static int __newindex(lua_State* L)
{
errorTableIsReadOnly(L);
}
static void registerType(lua_State* L)
{
luaL_newmetatable(L, metatableName);
lua_pushcfunction(L, __newindex);
lua_setfield(L, -2, "__newindex");
lua_pop(L, 1);
}
public:
static void wrap(lua_State* L, int index)
{
assert(lua_istable(L, index));
lua_newtable(L); // create wrapper table
lua_newtable(L); // metatable for wrapper table
if(index < 0)
index -= 2; // correct index if relative
lua_pushvalue(L, index); // copy source table (ref)
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, __newindex);
lua_setfield(L, -2, "__newindex");
lua_pushboolean(L, 0);
lua_setfield(L, -2, "__metatable");
lua_setmetatable(L, -2); // set metatable @ wrapper table
if(index < 0)
index++; // correct index if relative
lua_replace(L, index); // replace source table by wrapper table
}
};
}

Datei anzeigen

@ -98,13 +98,13 @@ SandboxPtr Sandbox::create(Script& script)
Enum<DecoderProtocol>::registerValues(L);
Enum<Direction>::registerValues(L);
Enum<WorldEvent>::registerValues(L);
ReadOnlyTable::setMetatable(L, -1);
ReadOnlyTable::wrap(L, -1);
lua_setfield(L, -2, "enum");
// add set values:
lua_newtable(L);
Set<WorldState>::registerValues(L);
ReadOnlyTable::setMetatable(L, -1);
ReadOnlyTable::wrap(L, -1);
lua_setfield(L, -2, "set");
// let global _G point to itself:

Datei anzeigen

@ -174,7 +174,7 @@ struct Set
push(L, it.first);
lua_setfield(L, -2, it.second);
}
ReadOnlyTable::setMetatable(L, -1);
ReadOnlyTable::wrap(L, -1);
lua_setfield(L, -2, set_name_v<T>);
}
};

Datei anzeigen

@ -37,7 +37,6 @@ static lua_State* createState()
{
lua_State* L = newStateWithProtect();
Lua::ReadOnlyTable::registerType(L);
Lua::Enum<T>::registerType(L);
lua_createtable(L, 0, 1);

Datei anzeigen

@ -35,7 +35,6 @@ static lua_State* createState()
{
lua_State* L = newStateWithProtect();
Lua::ReadOnlyTable::registerType(L);
Lua::Set<T>::registerType(L);
lua_createtable(L, 0, 1);