lua-users home
lua-l archive

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


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 no
I 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;
}

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

OK, thanks, I'll keep that in mind, or maybe I'll just remove access to that function.

Cheers,
Christian.