lua-users home
lua-l archive

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



On 23-Feb-07, at 3:12 AM, Eric Raible wrote:

Rici Lake <lua <at> ricilake.net> writes:

Can a Lua program get at metatables (and environments)? A simple test
would demonstrate:

 ...

setmetatable("", {})
stdin:1: bad argument #1 to 'setmetatable' (table expected, got string)

But setmetatable("", {}) always gives an error, even when
getmetatable("").__metatable is nil!

Yes, sorry, I was writing too fast.


-- now, let's get rid of the string table
string = nil

While there are many approaches, it would be nice to leave as much of the standard functionality in place as possible. This example does just that;

I agree, and I normally suggest mechanisms like that; my example was
just for illustration.

In fact, I'd prefer not to make the table read-only, in case
the sandbox wants to add it's own string methods (and why not?)
However, that requires giving each sandbox its own instance
of the string table (and other library tables), each one created
with lazy copy ( setmetatable({}, {__index = original}) ).

If you had only one sandbox, this would work fine, but if you
have multiple sandboxes, you end up having to swap package.loaded
and the string metatable every time you switch between them, which
can be awkward.

This could be made simpler if the package.loaded cache were actually
stored in the thread environment, rather than the registry, and if
the vector of type metatables was specific to a thread, rather than
global.

Since they're not, it can still be accomplished by trapping all
thread context switches, and shuffling accordingly. That has
acceptable performance in cases where sandboxes are called to
do significant work, but it's a bit much in the case where
sandboxes are called to do trivial computations.

The only remaining way to get to the string table is via
debug.getmetatable("").  But a sandbox shouldn't allow access
to the debug table anyway...

Absolutely. Access to the debug library cannot be given to
untrusted code.