summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2015-02-19 15:05:13 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2015-02-19 15:05:13 -0200
commitabd8f8433dc6628add06b1aa3568d40c1fdd9c46 (patch)
treeab803d7df4d59d90224b666662e5a9749b8a4754
parentce74637ace147d147578a95c435cf7cafec590b8 (diff)
downloadlua-github-abd8f8433dc6628add06b1aa3568d40c1fdd9c46.tar.gz
bug: suspended function can have its 'func' field not pointing to
its function, crashing debug functions
-rw-r--r--ldebug.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/ldebug.c b/ldebug.c
index a585075c..d9962b98 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldebug.c,v 2.90.1.2 2013/05/06 17:20:22 roberto Exp roberto $
+** $Id: ldebug.c,v 2.90.1.3 2013/05/16 16:04:15 roberto Exp roberto $
** Debug Interface
** See Copyright Notice in lua.h
*/
@@ -47,6 +47,16 @@ static int currentline (CallInfo *ci) {
}
+static void swapextra (lua_State *L) {
+ if (L->status == LUA_YIELD) {
+ CallInfo *ci = L->ci; /* get function that yielded */
+ StkId temp = ci->func; /* exchange its 'func' and 'extra' values */
+ ci->func = restorestack(L, ci->extra);
+ ci->extra = savestack(L, temp);
+ }
+}
+
+
/*
** this function can be called asynchronous (e.g. during a signal)
*/
@@ -144,6 +154,7 @@ static const char *findlocal (lua_State *L, CallInfo *ci, int n,
LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
const char *name;
lua_lock(L);
+ swapextra(L);
if (ar == NULL) { /* information about non-active function? */
if (!isLfunction(L->top - 1)) /* not a Lua function? */
name = NULL;
@@ -158,6 +169,7 @@ LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
api_incr_top(L);
}
}
+ swapextra(L);
lua_unlock(L);
return name;
}
@@ -165,11 +177,14 @@ LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
StkId pos = 0; /* to avoid warnings */
- const char *name = findlocal(L, ar->i_ci, n, &pos);
+ const char *name;
lua_lock(L);
+ swapextra(L);
+ name = findlocal(L, ar->i_ci, n, &pos);
if (name)
setobjs2s(L, pos, L->top - 1);
L->top--; /* pop value */
+ swapextra(L);
lua_unlock(L);
return name;
}
@@ -269,6 +284,7 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
CallInfo *ci;
StkId func;
lua_lock(L);
+ swapextra(L);
if (*what == '>') {
ci = NULL;
func = L->top - 1;
@@ -287,6 +303,7 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
setobjs2s(L, L->top, func);
api_incr_top(L);
}
+ swapextra(L);
if (strchr(what, 'L'))
collectvalidlines(L, cl);
lua_unlock(L);