Skip to content

Commit

Permalink
Fixed bug: 'luaD_callnoyield' called twice in a row
Browse files Browse the repository at this point in the history
In luaD_callnoyield, when there is a possible stack overflow, it
zeros the number of CallInfos to force a check when calling the
function. However, if the "function" is not a function, the code will
raise an error before checking the stack. Then, the error handling calls
luaD_callnoyield again and nCcalls is decremented again, crossing the
stack redzone without raising an error. (This loop can only happens
once, because the error handler must be a function.  But once is enough
to cross the redzone.)
  • Loading branch information
roberto-ieru committed Jul 17, 2020
1 parent a219564 commit 34affe7
Showing 1 changed file with 4 additions and 5 deletions.
9 changes: 4 additions & 5 deletions ldo.c
Original file line number Diff line number Diff line change
Expand Up @@ -515,14 +515,13 @@ void luaD_call (lua_State *L, StkId func, int nresults) {

/*
** Similar to 'luaD_call', but does not allow yields during the call.
** If there is a stack overflow, freeing all CI structures will
** force the subsequent call to invoke 'luaE_extendCI', which then
** will raise any errors.
*/
void luaD_callnoyield (lua_State *L, StkId func, int nResults) {
incXCcalls(L);
if (getCcalls(L) <= CSTACKERR) /* possible stack overflow? */
luaE_freeCI(L);
if (getCcalls(L) <= CSTACKERR) { /* possible C stack overflow? */
luaE_exitCcall(L); /* to compensate decrement in next call */
luaE_enterCcall(L); /* check properly */
}
luaD_call(L, func, nResults);
decXCcalls(L);
}
Expand Down

0 comments on commit 34affe7

Please sign in to comment.