lua-users home
lua-l archive

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


Hi,

I've recently been toying with Lua for use in a system where 3rd
parties can submit scripts to be executed. I need to be able to catch
scripts that accidentally run away. CPU usage can be monitored through
HOOKCOUNT (which works for my purposes), however there doesn't appear
to be any way to limit memory usage easily under the interpreter.

I've attached a simple patch which creates the function
"lua_setmemlimit()".

Perhaps this patch or something like it could be integrated into the
main Lua distro?

While I'm here I'd also like to thank the authors for creating Lua :).
Its been a long time since I've been this impressed by some software.

Now I just need to find more time to work with it ;).

Regards,
Mark
diff -urN lua-5.0/include/lua.h lua-5.0-mem/include/lua.h
--- lua-5.0/include/lua.h	Tue Mar 18 23:01:39 2003
+++ lua-5.0-mem/include/lua.h	Mon Oct  6 19:09:35 2003
@@ -104,6 +104,7 @@
 LUA_API lua_State *lua_newthread (lua_State *L);
 
 LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf);
+LUA_API unsigned long lua_setmemlimit (lua_State *L, unsigned long limit);
 
 
 /*
diff -urN lua-5.0/src/lapi.c lua-5.0-mem/src/lapi.c
--- lua-5.0/src/lapi.c	Tue Apr  8 00:06:08 2003
+++ lua-5.0-mem/src/lapi.c	Mon Oct  6 19:13:19 2003
@@ -135,6 +135,16 @@
 }
 
 
+LUA_API unsigned long lua_setmemlimit(lua_State *L, unsigned long limit) {
+  unsigned long old;
+  lua_lock(L);
+  old = G(L)->maxblocks;
+  G(L)->maxblocks = limit;
+  lua_unlock(L);
+  return old;
+}
+
+
 LUA_API lua_State *lua_newthread (lua_State *L) {
   lua_State *L1;
   lua_lock(L);
diff -urN lua-5.0/src/lmem.c lua-5.0-mem/src/lmem.c
--- lua-5.0/src/lmem.c	Thu Dec  5 04:08:31 2002
+++ lua-5.0-mem/src/lmem.c	Wed Oct  8 00:03:45 2003
@@ -73,6 +73,8 @@
   }
   else if (size >= MAX_SIZET)
     luaG_runerror(L, "memory allocation error: block too big");
+  else if (L && G(L)->nblocks - oldsize + size > G(L)->maxblocks)
+    luaD_throw(L, LUA_ERRMEM);
   else {
     block = l_realloc(block, oldsize, size);
     if (block == NULL) {
diff -urN lua-5.0/src/lstate.c lua-5.0-mem/src/lstate.c
--- lua-5.0/src/lstate.c	Thu Apr  3 23:05:34 2003
+++ lua-5.0-mem/src/lstate.c	Mon Oct  6 19:12:57 2003
@@ -108,6 +108,7 @@
   setnilvalue(gval(g->dummynode));
   g->dummynode->next = NULL;
   g->nblocks = sizeof(lua_State) + sizeof(global_State);
+  g->maxblocks = MAX_SIZET;
   stack_init(L, L);  /* init stack */
   /* create default meta table with a dummy table, and then close the loop */
   defaultmeta(L)->tt = LUA_TTABLE;
diff -urN lua-5.0/src/lstate.h lua-5.0-mem/src/lstate.h
--- lua-5.0/src/lstate.h	Thu Feb 27 22:22:30 2003
+++ lua-5.0-mem/src/lstate.h	Mon Oct  6 18:43:50 2003
@@ -116,6 +116,7 @@
   Mbuffer buff;  /* temporary buffer for string concatentation */
   lu_mem GCthreshold;
   lu_mem nblocks;  /* number of `bytes' currently allocated */
+  lu_mem maxblocks;  /* maximum `bytes' that can be allocated */
   lua_CFunction panic;  /* to be called in unprotected errors */
   TObject _registry;
   TObject _defaultmeta;