Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Why exactly are metatables locked for Strings in RbxLua?

I'm wondering if anyone can explain why this is

1 answer

✓ Accepted answer

It's a "security" thing, involving scripts (from freemodels or friends) interfering with each other.

All strings share the same metatable. This would be true even for separate scripts on the same client / on the server. That means if I did something like

-- Evil script:
local meta = getmetatable("cat")

meta.__index = function()
	return error;
end
-- By default, `meta.__index` would be the `string` library,
-- which is how you can do `:sub` and the like.

-----------

-- Other Script, minding it's own business:
local message = "Hello"
for i = 1, 5 do
	print( message:sub(1, i) )
end

The second script could get an error, because the first one invisibly changed the way strings behave.

In general you could be much more malicious with well designed metatable modifications. So ROBLOX doesn't allow this.


Locking the metatable is an easier (and much more reasonable) solution that modifying the core of Lua's code in order to make it generate new metatables for each thread, especially since Lua essentially allows that to be done very easily.



EDIT: A related thing: This is the same reason that the math, string, table, etc libraries are locked. It's also the same reason _G is no longer the default environment --

print( _G.print == print ) and you'll get true. In standard Lua,

_G.cat = 1;
print(cat);
-- 1

print, pcall, string, etc all come from _G in standard Lua, implicitly (i.e., _G is the global environment).

ROBLOX's solution to that problem is to make _G not the default environment, which again, Lua makes relatively easy, and doesn't require modifying the way Lua works.

1 comment

1

Perfect Explanation. Thanks, Blue [Nice use of 'Evil Script' label :P]

This discussion is preserved as it was. New answers, comments, and votes are closed.