diff --git a/apps/openmw_test_suite/lua/test_lua.cpp b/apps/openmw_test_suite/lua/test_lua.cpp index 90c987522d..a669a3c670 100644 --- a/apps/openmw_test_suite/lua/test_lua.cpp +++ b/apps/openmw_test_suite/lua/test_lua.cpp @@ -51,6 +51,9 @@ return { } )X"); + TestingOpenMW::VFSTestFile metaIndexErrorFile( + "return setmetatable({}, { __index = function(t, key) error('meta index error') end })"); + std::string genBigScript() { std::stringstream buf; @@ -70,7 +73,7 @@ return { { std::unique_ptr mVFS = TestingOpenMW::createTestVFS({ { "aaa/counter.lua", &counterFile }, { "bbb/tests.lua", &testsFile }, { "invalid.lua", &invalidScriptFile }, { "big.lua", &bigScriptFile }, - { "requireBig.lua", &requireBigScriptFile } }); + { "requireBig.lua", &requireBigScriptFile }, { "metaIndexError.lua", &metaIndexErrorFile } }); LuaUtil::ScriptsConfiguration mCfg; LuaUtil::LuaState mLua{ mVFS.get(), &mCfg }; @@ -223,4 +226,11 @@ return { // At this moment all instances of the script should be garbage-collected. EXPECT_LT(memWithoutScript, memWithScript); } + + TEST_F(LuaStateTest, SafeIndexMetamethod) + { + sol::table t = mLua.runInNewSandbox("metaIndexError.lua"); + // without safe get we crash here + EXPECT_ERROR(LuaUtil::safeGet(t, "any key"), "meta index error"); + } } diff --git a/components/lua/luastate.hpp b/components/lua/luastate.hpp index f14fc44867..509b5e16e1 100644 --- a/components/lua/luastate.hpp +++ b/components/lua/luastate.hpp @@ -235,7 +235,7 @@ namespace LuaUtil // work around for a (likely) sol3 bug // when the index meta method throws, simply calling table.get crashes instead of re-throwing the error template - sol::object safe_get(const sol::table& table, const Key& key) + sol::object safeGet(const sol::table& table, const Key& key) { auto index = table.traverse_raw_get>( sol::metatable_key, sol::meta_function::index); @@ -257,7 +257,7 @@ namespace LuaUtil { if (!table.is()) return sol::nil; - sol::object value = safe_get(table.as(), first); + sol::object value = safeGet(table.as(), first); if constexpr (sizeof...(str) == 0) return value; else