diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2015-02-13 14:01:17 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2015-02-13 14:01:17 -0200 |
commit | 4bdf9962bfd413077d979af4ddc406e7fcd4bbd6 (patch) | |
tree | 49308264448bd40f47c1af1cfd722045dbe4508d /ldebug.c | |
parent | e0306e386fdaa1b1f18f0c293a4b14de8b8a8536 (diff) | |
download | lua-4bdf9962bfd413077d979af4ddc406e7fcd4bbd6.tar.gz lua-4bdf9962bfd413077d979af4ddc406e7fcd4bbd6.tar.bz2 lua-4bdf9962bfd413077d979af4ddc406e7fcd4bbd6.zip |
bug: suspended function can have its 'func' field not pointing to
its function, crashing debug functions
Diffstat (limited to 'ldebug.c')
-rw-r--r-- | ldebug.c | 27 |
1 files changed, 25 insertions, 2 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldebug.c,v 2.109 2014/12/10 11:30:09 roberto Exp roberto $ | 2 | ** $Id: ldebug.c,v 2.110 2015/01/02 12:52:22 roberto Exp roberto $ |
3 | ** Debug Interface | 3 | ** Debug Interface |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -49,6 +49,22 @@ static int currentline (CallInfo *ci) { | |||
49 | 49 | ||
50 | 50 | ||
51 | /* | 51 | /* |
52 | ** If function yielded, its 'func' can be in the 'extra' field. The | ||
53 | ** next function restores 'func' to its correct value for debugging | ||
54 | ** purposes. (It exchanges 'func' and 'extra'; so, when called again, | ||
55 | ** after debugging, it also "re-restores" ** 'func' to its altered value. | ||
56 | */ | ||
57 | static void swapextra (lua_State *L) { | ||
58 | if (L->status == LUA_YIELD) { | ||
59 | CallInfo *ci = L->ci; /* get function that yielded */ | ||
60 | StkId temp = ci->func; /* exchange its 'func' and 'extra' values */ | ||
61 | ci->func = restorestack(L, ci->extra); | ||
62 | ci->extra = savestack(L, temp); | ||
63 | } | ||
64 | } | ||
65 | |||
66 | |||
67 | /* | ||
52 | ** this function can be called asynchronous (e.g. during a signal) | 68 | ** this function can be called asynchronous (e.g. during a signal) |
53 | */ | 69 | */ |
54 | LUA_API void lua_sethook (lua_State *L, lua_Hook func, int mask, int count) { | 70 | LUA_API void lua_sethook (lua_State *L, lua_Hook func, int mask, int count) { |
@@ -144,6 +160,7 @@ static const char *findlocal (lua_State *L, CallInfo *ci, int n, | |||
144 | LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { | 160 | LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { |
145 | const char *name; | 161 | const char *name; |
146 | lua_lock(L); | 162 | lua_lock(L); |
163 | swapextra(L); | ||
147 | if (ar == NULL) { /* information about non-active function? */ | 164 | if (ar == NULL) { /* information about non-active function? */ |
148 | if (!isLfunction(L->top - 1)) /* not a Lua function? */ | 165 | if (!isLfunction(L->top - 1)) /* not a Lua function? */ |
149 | name = NULL; | 166 | name = NULL; |
@@ -158,6 +175,7 @@ LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { | |||
158 | api_incr_top(L); | 175 | api_incr_top(L); |
159 | } | 176 | } |
160 | } | 177 | } |
178 | swapextra(L); | ||
161 | lua_unlock(L); | 179 | lua_unlock(L); |
162 | return name; | 180 | return name; |
163 | } | 181 | } |
@@ -165,12 +183,15 @@ LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { | |||
165 | 183 | ||
166 | LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { | 184 | LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { |
167 | StkId pos = 0; /* to avoid warnings */ | 185 | StkId pos = 0; /* to avoid warnings */ |
168 | const char *name = findlocal(L, ar->i_ci, n, &pos); | 186 | const char *name; |
169 | lua_lock(L); | 187 | lua_lock(L); |
188 | swapextra(L); | ||
189 | name = findlocal(L, ar->i_ci, n, &pos); | ||
170 | if (name) { | 190 | if (name) { |
171 | setobjs2s(L, pos, L->top - 1); | 191 | setobjs2s(L, pos, L->top - 1); |
172 | L->top--; /* pop value */ | 192 | L->top--; /* pop value */ |
173 | } | 193 | } |
194 | swapextra(L); | ||
174 | lua_unlock(L); | 195 | lua_unlock(L); |
175 | return name; | 196 | return name; |
176 | } | 197 | } |
@@ -270,6 +291,7 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { | |||
270 | CallInfo *ci; | 291 | CallInfo *ci; |
271 | StkId func; | 292 | StkId func; |
272 | lua_lock(L); | 293 | lua_lock(L); |
294 | swapextra(L); | ||
273 | if (*what == '>') { | 295 | if (*what == '>') { |
274 | ci = NULL; | 296 | ci = NULL; |
275 | func = L->top - 1; | 297 | func = L->top - 1; |
@@ -288,6 +310,7 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { | |||
288 | setobjs2s(L, L->top, func); | 310 | setobjs2s(L, L->top, func); |
289 | api_incr_top(L); | 311 | api_incr_top(L); |
290 | } | 312 | } |
313 | swapextra(L); /* correct before option 'L', which can raise a mem. error */ | ||
291 | if (strchr(what, 'L')) | 314 | if (strchr(what, 'L')) |
292 | collectvalidlines(L, cl); | 315 | collectvalidlines(L, cl); |
293 | lua_unlock(L); | 316 | lua_unlock(L); |