aboutsummaryrefslogtreecommitdiff
path: root/lapi.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-07-16 14:13:22 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-07-16 14:13:22 -0300
commit298f383ffcc30d0799fbca0293175f647fe6bccf (patch)
treeb96f7572dd4e185007d20436db45c505976c3122 /lapi.c
parent758c1ef445ab27d89bace746111add04083a8e20 (diff)
downloadlua-298f383ffcc30d0799fbca0293175f647fe6bccf.tar.gz
lua-298f383ffcc30d0799fbca0293175f647fe6bccf.tar.bz2
lua-298f383ffcc30d0799fbca0293175f647fe6bccf.zip
Avoid setting the stack top below upvalues to be closed
When leaving a scope, the new stack top should be set only after closing any upvalue, to avoid manipulating values in an "invalid" part of the stack.
Diffstat (limited to 'lapi.c')
-rw-r--r--lapi.c15
1 files changed, 8 insertions, 7 deletions
diff --git a/lapi.c b/lapi.c
index 661fdb14..0f81107f 100644
--- a/lapi.c
+++ b/lapi.c
@@ -171,19 +171,20 @@ LUA_API int lua_gettop (lua_State *L) {
171 171
172LUA_API void lua_settop (lua_State *L, int idx) { 172LUA_API void lua_settop (lua_State *L, int idx) {
173 StkId func = L->ci->func; 173 StkId func = L->ci->func;
174 int diff; /* difference for new top */
174 lua_lock(L); 175 lua_lock(L);
175 if (idx >= 0) { 176 if (idx >= 0) {
176 StkId newtop = (func + 1) + idx; 177 api_check(L, idx <= L->ci->top - (func + 1), "new top too large");
177 api_check(L, idx <= L->stack_last - (func + 1), "new top too large"); 178 diff = (func + 1) + idx - L->top;
178 while (L->top < newtop) 179 for (; diff > 0; diff--)
179 setnilvalue(s2v(L->top++)); 180 setnilvalue(s2v(L->top++)); /* clear new slots */
180 L->top = newtop;
181 } 181 }
182 else { 182 else {
183 api_check(L, -(idx+1) <= (L->top - (func + 1)), "invalid new top"); 183 api_check(L, -(idx+1) <= (L->top - (func + 1)), "invalid new top");
184 L->top += idx+1; /* 'subtract' index (index is negative) */ 184 diff = idx + 1; /* will "subtract" index (as it is negative) */
185 } 185 }
186 luaF_close(L, L->top, LUA_OK); 186 luaF_close(L, L->top + diff, LUA_OK);
187 L->top += diff; /* correct top only after closing any upvalue */
187 lua_unlock(L); 188 lua_unlock(L);
188} 189}
189 190