lua-users home
lua-l archive

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


On Aug 8, 2010, at 3:26 PM, Roberto Ierusalimschy wrote:

>> Why not the following function instead:
>> 
>> function newproxy2( meta, env ) -- returns a userdata with the given metatable and environment (user value in 5.2)
> 
> Then you can write the following:
> 
>  falsefile = newproxy2(getmetatable(io.stdin), {})
>  io.read(falsefile)
> 
> and crash the io library.

Interesting. Though I might argue that the problem there is really that Lua code shouldn't be able to get the metatable on userdata any more than it can set the metatable.

How about:

function newproxy3( proxy or true or false [ , env ] )

-- If the first parameter is a proxy, it uses the metatable from that proxy.
-- If the first parameter is true, it generates a new metatable and returns that as a second result (thereby eliminating the need to call getmetatable)
-- If the first parameter is false, the proxy has no metatable
-- If an environment is supplied, it is set as the environment for the new proxy
-- If an environment is not supplied and the first parameter is a proxy, the environment from the proxy is used
-- Otherwise, the environment is whatever the default environment is

Obviously, this is implementable using the debug library, but the debug library is generally to be avoided for either performance or security reasons.

Then there's this construct:

function makeFactoryAndMetatable()

	local proxy = newproxy( true )

	local function factory( env )
		local result = newproxy( proxy )
		if env ~= nil then
			debug.setfenv( result, env )
		end
		return result
	end

	return factory, getmetatable( proxy )

end

This hides the proxy that gets used only for generating new proxies and provides access to the metatable so that it can be filled in.

Mark