lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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