From a97f29f15487c5f584185f646f9cfc06a04b26ca Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Tue, 29 Aug 2000 17:43:28 -0300 Subject: [PATCH] explicit stack control in the API --- lapi.c | 6 +++++- lauxlib.c | 8 +++++++- lauxlib.h | 5 +++-- ldo.c | 12 +++--------- liolib.c | 3 ++- lstrlib.c | 3 ++- lua.h | 6 +++++- 7 files changed, 27 insertions(+), 16 deletions(-) diff --git a/lapi.c b/lapi.c index 5a000b49..e3d4a906 100644 --- a/lapi.c +++ b/lapi.c @@ -1,5 +1,5 @@ /* -** $Id: lapi.c,v 1.88 2000/08/28 17:57:04 roberto Exp roberto $ +** $Id: lapi.c,v 1.89 2000/08/29 14:52:27 roberto Exp roberto $ ** Lua API ** See Copyright Notice in lua.h */ @@ -45,6 +45,10 @@ void luaA_pushobject (lua_State *L, const TObject *o) { incr_top; } +int lua_stackspace (lua_State *L) { + return (L->stack_last - L->top); +} + /* diff --git a/lauxlib.c b/lauxlib.c index 12d1d067..2c54bd02 100644 --- a/lauxlib.c +++ b/lauxlib.c @@ -1,5 +1,5 @@ /* -** $Id: lauxlib.c,v 1.31 2000/08/28 17:57:04 roberto Exp roberto $ +** $Id: lauxlib.c,v 1.32 2000/08/29 14:33:31 roberto Exp roberto $ ** Auxiliary functions for building Lua libraries ** See Copyright Notice in lua.h */ @@ -49,6 +49,12 @@ static void type_error (lua_State *L, int narg, const char *type_name) { } +void luaL_checkstack (lua_State *L, int space, const char *mes) { + if (space > lua_stackspace(L)) + luaL_verror(L, "stack overflow (%.30s)", mes); +} + + /* ** use the 3rd letter of type names for testing: ** nuMber, niL, stRing, fuNction, usErdata, taBle, anY diff --git a/lauxlib.h b/lauxlib.h index 25dbc1f9..b57164d1 100644 --- a/lauxlib.h +++ b/lauxlib.h @@ -1,5 +1,5 @@ /* -** $Id: lauxlib.h,v 1.19 2000/08/09 19:16:57 roberto Exp roberto $ +** $Id: lauxlib.h,v 1.20 2000/08/28 17:57:04 roberto Exp roberto $ ** Auxiliary functions for building Lua libraries ** See Copyright Notice in lua.h */ @@ -28,7 +28,8 @@ const char *luaL_opt_lstr (lua_State *L, int numArg, const char *def, double luaL_check_number (lua_State *L, int numArg); double luaL_opt_number (lua_State *L, int numArg, double def); -void luaL_checktype(lua_State *L, int narg, const char *tname); +void luaL_checkstack (lua_State *L, int space, const char *msg); +void luaL_checktype (lua_State *L, int narg, const char *tname); void luaL_verror (lua_State *L, const char *fmt, ...); int luaL_findstring (const char *name, const char *const list[]); diff --git a/ldo.c b/ldo.c index 907e62a6..79cf25a2 100644 --- a/ldo.c +++ b/ldo.c @@ -1,5 +1,5 @@ /* -** $Id: ldo.c,v 1.89 2000/08/29 14:57:23 roberto Exp roberto $ +** $Id: ldo.c,v 1.90 2000/08/29 19:01:34 roberto Exp roberto $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ @@ -53,14 +53,8 @@ void luaD_checkstack (lua_State *L, int n) { lua_error(L, "BAD STACK OVERFLOW! DATA CORRUPTED!"); } else { - lua_Debug dummy; L->stack_last += EXTRA_STACK; /* to be used by error message */ - if (lua_getstack(L, L->stacksize/SLOTS_PER_F, &dummy) == 0) { - /* too few funcs on stack: doesn't look like a recursion loop */ - lua_error(L, "Lua2C - C2Lua overflow"); - } - else - lua_error(L, "stack overflow; possible recursion loop"); + lua_error(L, "stack overflow"); } } } @@ -140,7 +134,7 @@ static StkId callCclosure (lua_State *L, const struct Closure *cl, StkId base) { StkId old_Cbase = L->Cbase; int n; L->Cbase = base; /* new base for C function */ - luaD_checkstack(L, nup); + luaD_checkstack(L, nup+LUA_MINSTACK); /* assures minimum stack size */ for (n=0; ntop++) = cl->upvalue[n]; n = (*cl->f.c)(L); /* do the actual call */ diff --git a/liolib.c b/liolib.c index 4c0cbf2b..0a310de0 100644 --- a/liolib.c +++ b/liolib.c @@ -1,5 +1,5 @@ /* -** $Id: liolib.c,v 1.72 2000/08/28 17:57:04 roberto Exp roberto $ +** $Id: liolib.c,v 1.73 2000/08/29 14:33:31 roberto Exp roberto $ ** Standard I/O (and system) library ** See Copyright Notice in lua.h */ @@ -372,6 +372,7 @@ static int io_read (lua_State *L) { firstarg = lastarg = 1; /* correct indices */ lua_pushstring(L, "*l"); /* push default argument */ } + luaL_checkstack(L, lastarg-firstarg+1, "too many results"); for (n = firstarg; n<=lastarg; n++) { size_t l; int success; diff --git a/lstrlib.c b/lstrlib.c index c380359b..0a0a6c13 100644 --- a/lstrlib.c +++ b/lstrlib.c @@ -1,5 +1,5 @@ /* -** $Id: lstrlib.c,v 1.46 2000/08/09 19:16:57 roberto Exp roberto $ +** $Id: lstrlib.c,v 1.47 2000/08/28 17:57:04 roberto Exp roberto $ ** Standard library for string operations and pattern-matching ** See Copyright Notice in lua.h */ @@ -400,6 +400,7 @@ static const char *lmemfind (const char *s1, size_t l1, static int push_captures (lua_State *L, struct Capture *cap) { int i; + luaL_checkstack(L, cap->level, "too many captures"); for (i=0; ilevel; i++) { int l = cap->capture[i].len; if (l == -1) lua_error(L, "unfinished capture"); diff --git a/lua.h b/lua.h index f9921a52..567f4e1a 100644 --- a/lua.h +++ b/lua.h @@ -1,5 +1,5 @@ /* -** $Id: lua.h,v 1.60 2000/08/28 17:57:04 roberto Exp roberto $ +** $Id: lua.h,v 1.61 2000/08/29 14:33:31 roberto Exp roberto $ ** Lua - An Extensible Extension Language ** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil ** e-mail: lua@tecgraf.puc-rio.br @@ -33,6 +33,9 @@ #define LUA_MULTRET (-1) +#define LUA_MINSTACK 16 + + /* error codes for lua_do* */ #define LUA_ERRFILE 2 #define LUA_ERRSYNTAX 3 @@ -58,6 +61,7 @@ void lua_close (lua_State *L); int lua_gettop (lua_State *L); void lua_settop (lua_State *L, int index); void lua_pushobject (lua_State *L, int index); +int lua_stackspace (lua_State *L); /*