1029 posts
Location
Missouri, United States, America, Earth, Solar System, Milky Way, Universe 42B, Life Street, Multiverse, 4th Dimension
Posted 17 July 2015 - 10:37 PM
With the 1.7.4 update, setfenv is sort of depreciated now, and lua 5.2 functions have been added, or at least some of them. Is there a way I can apply an environment to a coroutine, spawned from a pre-specified function? I'm not loading the function as a string, I'm receiving it from an untrusted source, and I want to set its environment. Once again, I am
NOT loading it from a string.
~~Nobump: Thanks for the replies.
R.I.P. in peace setfenv. You will be dearly missed.
//offtopic Rest In Peace in peace makes no sense. Ugh… (sorry :P/>)
I know, that's why it's funny. It's making fun of people who do that.
Edited on 19 July 2015 - 04:46 PM
570 posts
Posted 17 July 2015 - 11:20 PM
There's no real way to do it anymore, I'm afraid. Your best bet would be to avoid the situation in the first place. However, you could try to use string.dump on the function to get its code and then load a new function from that code with the desired environment. This won't work if the function has upvalues, though! It's a very hacky and slow way to do it but, if it works, it's the best there is.
EDIT: I've just given it a try, and I was stopped by the error "Binary chunk loading prohibited". I suppose this is because the compatibility layer doesn't support them? If so, it should work when Lua 5.2 is actually implemented. Until then you could use the code at the end of
this thread to allow loadstring to load chunks.
Edited on 17 July 2015 - 09:32 PM
1029 posts
Location
Missouri, United States, America, Earth, Solar System, Milky Way, Universe 42B, Life Street, Multiverse, 4th Dimension
Posted 18 July 2015 - 02:32 AM
There's no real way to do it anymore, I'm afraid. Your best bet would be to avoid the situation in the first place. However, you could try to use string.dump on the function to get its code and then load a new function from that code with the desired environment. This won't work if the function has upvalues, though! It's a very hacky and slow way to do it but, if it works, it's the best there is.
EDIT: I've just given it a try, and I was stopped by the error "Binary chunk loading prohibited". I suppose this is because the compatibility layer doesn't support them? If so, it should work when Lua 5.2 is actually implemented. Until then you could use the code at the end of
this thread to allow loadstring to load chunks.
Sigh….
R.I.P. in peace setfenv. You will be dearly missed.
Re-looking at my code, I probably don't need to set the environment of coroutines, it just makes it a little bit harder for me since I have to do it manually every time I call the task creation function. Routines created from an outside source can't get into the protected environment I don't want foreign code running in anyway, so there's that.
3057 posts
Location
United States of America
Posted 18 July 2015 - 03:13 AM
R.I.P. in peace setfenv. You will be dearly missed.
//offtopic Rest In Peace in peace makes no sense. Ugh… (sorry :P/>)
797 posts
Posted 18 July 2015 - 11:27 AM
Well, I'm not sure about this, you seemed pretty clear about the fact that the code/function was not being loaded from a file, but whether or not that's just because the code that loads the file is different to the sandbox, and therefore can't load the code in a sandboxed environment, was unclear. If so, you can use some fancy metatable magic to dynamically change the function's (and coroutine's) environment:
local environments = {}
function loadfile( file )
local content = readfile( file ) -- I'm assuming you can do this part yourself (' to fix forum syntax highlighting)
local f, err
local env = setmetatable( {}, { __index = function( t, k ) return environments[f][k] end, __newindex( t, k, v ) environments[f][k] = v end } )
f, err = load( content, fs.getName( file ), nil, env )
if not f then return false, err end
environments[f] = getfenv( 2 ) -- the caller's environment, because that's generally what you want?
return f
end
function setfenv( f, env )
environments[f] = env
end
function getfenv( f )
return environments[f]
end
Edited on 18 July 2015 - 09:29 AM
7083 posts
Location
Tasmania (AU)
Posted 19 July 2015 - 03:28 AM
There was a bit of discussion about this in the beta thread,
starting here.
There's no real way to do it anymore, I'm afraid.
Or at least, there presumably won't be. But setfenv isn't gone
yet! ;)/>