|
Jim Whitehead II wrote:
On Tue, Nov 3, 2009 at 3:53 PM, Peter Cawley <lua@corsix.org> wrote:On Tue, Nov 3, 2009 at 3:46 PM, Christian Tellefsen <christian.tellefsen@funcom.com> wrote:I'm investigating using Lua as a scripting language for content designers. If I want to make sure that none of the designer-supplied scripts can loop forever and freeze the host application, how would I do that? Sample problem code: f = coroutine.create(function() while true do print('x') end end) -- No yield() coroutine.resume(f) -- Oh noI would use lua_sethook, with LUA_MASKCOUNT and some value between 50 and 500. This will call your hook function at a regular interval, and then you can abort if things are taking too long. You'll have to do this for each thread though, so you'll have to export slightly tweaked versions of the coroutine.xyz functions to your scripts to add automatic hooking.
Thanks, this worked great! void CoroutineTimeoutHook(lua_State * L, lua_Debug * ar) { luaL_error(L, "Script took too long to execute."); } int CoroutineCreate(lua_State * L) { lua_State * L1 = lua_newthread(L); // L: f, thread lua_pushvalue(L, 1); // L: f, thread, f lua_xmove(L, L1, 1); // L: f, thread L1: f lua_sethook(L1, &CoroutineTimeoutHook, LUA_MASKCOUNT, 10000); return 1; }
OK, thanks, I'll keep that in mind, or maybe I'll just remove access to that function.Keep in mind that for certain C functions (like string.find) won't call your debug hook in them, so a user script can still tie up the system in what appears to be an infinite loop, but really is just code that takes a long time to run (all without your hook being called). - Jim
Cheers, Christian.