[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Protect global table from any changes
- From: Patrick Kurth <p.kurth@...>
- Date: Wed, 19 Jan 2022 15:22:43 +0000
On Wed, 2022-01-19 at 16:10 +0200, Meir Shpilraien wrote:
> Thanks for your reply, I was thinking of doing it but wouldn't a user
> can still use rawset to forcely set 'A1' to the global table and then
> my metatable '__index' function will not even be called when fetching
> 'A1'?
>
No, and please ignore some other things that were said on this thread.
rawset and rawget operate on the actual table, not the metatable. So if
you are using __index with the global environment as the metatable, the
user can't set the global values with rawset. But you have to also
protect the metatable by setting __metatable (this prevents
setmetatable and only returns this value when using getmetatable)
Here is an example:
----------------------
local env = {
foo = function() print("foo") end,
print = print,
rawset = rawset
}
env.__index = env
local proxy = {}
setmetatable(proxy, env)
--proxy = env
local source = "rawset(_ENV, 'foo', function() print('bar') end);
foo()"
local chunk = load(source, "@a_chunk", "t", proxy)
chunk() -- prints 'bar'
env.foo() -- prints 'foo' if proxy ~= env, 'bar' if proxy == env
---------------------
I used a local table here for the environment, this can of course also
just be the global environment, but I tend to avoid global stuff.
Kind regards,
Patrick