diff --git a/Scripts/Tests/metatable.lua b/Scripts/Tests/metatable.lua new file mode 100644 index 0000000..1d24c13 --- /dev/null +++ b/Scripts/Tests/metatable.lua @@ -0,0 +1,25 @@ +-- Should succeed +-- User created tables can have their metatables changed +setmetatable({},{}) + +-- Should fail +protectedTables = { + string, + math, + string, + table, + math, + coroutine, + os, +} + +function modifyProtectedTable(t) + setmetatable(t, {}) +end + +for _, t in ipairs(protectedTables) do + local code, msg = pcall(modifyProtectedTable, t) + if(code ~= false or msg:match("cannot change a protected metatable$") == nil) then + print("ERROR: Protected table was modified!") + end +end \ No newline at end of file diff --git a/Scripts/sandbox.lua b/Scripts/sandbox.lua index 44b1219..ddf8bef 100644 --- a/Scripts/sandbox.lua +++ b/Scripts/sandbox.lua @@ -256,7 +256,27 @@ function sandbox.createNew(aiID, scriptName) end sb.require = sb.dofile + + sb.setmetatable = setmetatable + sb.getmetatable = getmetatable + + protectMetatables(sb) + return sb end +function protectMetatables(t) + if type(t) ~= "table" then + return + end + + local metatable = getmetatable(t) or {} + metatable.__metatable=false -- Protect metatable, cannot be modified anymore + setmetatable(t, metatable) + + for _, v in pairs(t) do + protectMetatables(v) + end +end + return sandbox