Jump to content




[Lua 5."2"] [1.7.4] Applying an environment to a coroutine


  • You cannot reply to this topic
5 replies to this topic

#1 Geforce Fan

  • Members
  • 846 posts
  • LocationMissouri, United States, America, Earth, Solar System, Milky Way, Universe 42B, Life Street, Multiverse, 4th Dimension

Posted 17 July 2015 - 09: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.

View PostKingofGamesYami, on 18 July 2015 - 02:13 AM, said:

View PostGeforce Fan, on 18 July 2015 - 01:32 AM, said:

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 by Geforce Fan, 19 July 2015 - 05:46 PM.


#2 Lignum

  • Members
  • 558 posts

Posted 17 July 2015 - 10: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 by Lignum, 17 July 2015 - 10:32 PM.


#3 Geforce Fan

  • Members
  • 846 posts
  • LocationMissouri, United States, America, Earth, Solar System, Milky Way, Universe 42B, Life Street, Multiverse, 4th Dimension

Posted 18 July 2015 - 01:32 AM

View PostLignum, on 17 July 2015 - 10:20 PM, said:

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.

#4 KingofGamesYami

  • Members
  • 3,002 posts
  • LocationUnited States of America

Posted 18 July 2015 - 02:13 AM

View PostGeforce Fan, on 18 July 2015 - 01:32 AM, said:

R.I.P. in peace setfenv. You will be dearly missed.

//offtopic Rest In Peace in peace makes no sense. Ugh... (sorry :P)

#5 Exerro

  • Members
  • 801 posts

Posted 18 July 2015 - 10: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 by awsumben13, 18 July 2015 - 10:29 AM.


#6 Bomb Bloke

    Hobbyist Coder

  • Moderators
  • 7,099 posts
  • LocationTasmania (AU)

Posted 19 July 2015 - 02:28 AM

There was a bit of discussion about this in the beta thread, starting here.

View PostLignum, on 17 July 2015 - 10:20 PM, said:

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! ;)







1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users