aboutsummaryrefslogtreecommitdiff
path: root/ldblib.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2015-02-19 15:06:21 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2015-02-19 15:06:21 -0200
commit97f2aa5a443b75f2528a27e6e78fe18f66cb4f87 (patch)
tree1cd2494cc684dd41769f3be66cb1b4040e1da231 /ldblib.c
parent419e2cb01d3527928cc4035f8b9b9589946e0e1a (diff)
downloadlua-97f2aa5a443b75f2528a27e6e78fe18f66cb4f87.tar.gz
lua-97f2aa5a443b75f2528a27e6e78fe18f66cb4f87.tar.bz2
lua-97f2aa5a443b75f2528a27e6e78fe18f66cb4f87.zip
bug: when manipulating other threads, there is no garanties about
their stack space
Diffstat (limited to 'ldblib.c')
-rw-r--r--ldblib.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/ldblib.c b/ldblib.c
index b8164d51..afec1ebc 100644
--- a/ldblib.c
+++ b/ldblib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldblib.c,v 1.147 2014/12/08 15:47:25 roberto Exp roberto $ 2** $Id: ldblib.c,v 1.148 2015/01/02 12:52:22 roberto Exp roberto $
3** Interface from Lua to its debug API 3** Interface from Lua to its debug API
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -27,6 +27,17 @@
27static const int HOOKKEY = 0; 27static const int HOOKKEY = 0;
28 28
29 29
30/*
31** If L1 != L, L1 can be in any state, and therefore there is no
32** garanties about its stack space; any push in L1 must be
33** checked.
34*/
35static void checkstack (lua_State *L, lua_State *L1, int n) {
36 if (L != L1 && !lua_checkstack(L1, n))
37 luaL_error(L, "stack overflow");
38}
39
40
30static int db_getregistry (lua_State *L) { 41static int db_getregistry (lua_State *L) {
31 lua_pushvalue(L, LUA_REGISTRYINDEX); 42 lua_pushvalue(L, LUA_REGISTRYINDEX);
32 return 1; 43 return 1;
@@ -127,12 +138,16 @@ static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) {
127 138
128/* 139/*
129** Calls 'lua_getinfo' and collects all results in a new table. 140** Calls 'lua_getinfo' and collects all results in a new table.
141** L1 needs stack space for an optional input (function) plus
142** two optional outputs (function and line table) from function
143** 'lua_getinfo'.
130*/ 144*/
131static int db_getinfo (lua_State *L) { 145static int db_getinfo (lua_State *L) {
132 lua_Debug ar; 146 lua_Debug ar;
133 int arg; 147 int arg;
134 lua_State *L1 = getthread(L, &arg); 148 lua_State *L1 = getthread(L, &arg);
135 const char *options = luaL_optstring(L, arg+2, "flnStu"); 149 const char *options = luaL_optstring(L, arg+2, "flnStu");
150 checkstack(L, L1, 3);
136 if (lua_isfunction(L, arg + 1)) { /* info about a function? */ 151 if (lua_isfunction(L, arg + 1)) { /* info about a function? */
137 options = lua_pushfstring(L, ">%s", options); /* add '>' to 'options' */ 152 options = lua_pushfstring(L, ">%s", options); /* add '>' to 'options' */
138 lua_pushvalue(L, arg + 1); /* move function to 'L1' stack */ 153 lua_pushvalue(L, arg + 1); /* move function to 'L1' stack */
@@ -190,6 +205,7 @@ static int db_getlocal (lua_State *L) {
190 int level = (int)luaL_checkinteger(L, arg + 1); 205 int level = (int)luaL_checkinteger(L, arg + 1);
191 if (!lua_getstack(L1, level, &ar)) /* out of range? */ 206 if (!lua_getstack(L1, level, &ar)) /* out of range? */
192 return luaL_argerror(L, arg+1, "level out of range"); 207 return luaL_argerror(L, arg+1, "level out of range");
208 checkstack(L, L1, 1);
193 name = lua_getlocal(L1, &ar, nvar); 209 name = lua_getlocal(L1, &ar, nvar);
194 if (name) { 210 if (name) {
195 lua_xmove(L1, L, 1); /* move local value */ 211 lua_xmove(L1, L, 1); /* move local value */
@@ -216,6 +232,7 @@ static int db_setlocal (lua_State *L) {
216 return luaL_argerror(L, arg+1, "level out of range"); 232 return luaL_argerror(L, arg+1, "level out of range");
217 luaL_checkany(L, arg+3); 233 luaL_checkany(L, arg+3);
218 lua_settop(L, arg+3); 234 lua_settop(L, arg+3);
235 checkstack(L, L1, 1);
219 lua_xmove(L, L1, 1); 236 lua_xmove(L, L1, 1);
220 name = lua_setlocal(L1, &ar, nvar); 237 name = lua_setlocal(L1, &ar, nvar);
221 if (name == NULL) 238 if (name == NULL)
@@ -350,6 +367,7 @@ static int db_sethook (lua_State *L) {
350 lua_pushvalue(L, -1); 367 lua_pushvalue(L, -1);
351 lua_setmetatable(L, -2); /* setmetatable(hooktable) = hooktable */ 368 lua_setmetatable(L, -2); /* setmetatable(hooktable) = hooktable */
352 } 369 }
370 checkstack(L, L1, 1);
353 lua_pushthread(L1); lua_xmove(L1, L, 1); /* key (thread) */ 371 lua_pushthread(L1); lua_xmove(L1, L, 1); /* key (thread) */
354 lua_pushvalue(L, arg + 1); /* value (hook function) */ 372 lua_pushvalue(L, arg + 1); /* value (hook function) */
355 lua_rawset(L, -3); /* hooktable[L1] = new Lua hook */ 373 lua_rawset(L, -3); /* hooktable[L1] = new Lua hook */
@@ -370,6 +388,7 @@ static int db_gethook (lua_State *L) {
370 lua_pushliteral(L, "external hook"); 388 lua_pushliteral(L, "external hook");
371 else { /* hook table must exist */ 389 else { /* hook table must exist */
372 lua_rawgetp(L, LUA_REGISTRYINDEX, &HOOKKEY); 390 lua_rawgetp(L, LUA_REGISTRYINDEX, &HOOKKEY);
391 checkstack(L, L1, 1);
373 lua_pushthread(L1); lua_xmove(L1, L, 1); 392 lua_pushthread(L1); lua_xmove(L1, L, 1);
374 lua_rawget(L, -2); /* 1st result = hooktable[L1] */ 393 lua_rawget(L, -2); /* 1st result = hooktable[L1] */
375 lua_remove(L, -2); /* remove hook table */ 394 lua_remove(L, -2); /* remove hook table */