diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2020-07-17 14:54:26 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2020-07-17 14:54:26 -0300 |
commit | 34affe7a63fc5d842580a9f23616d057e17dfe27 (patch) | |
tree | 62283d8c88989180e8e971efe457a8b55afa16a0 | |
parent | a2195644d89812e5b157ce7bac35543e06db05e3 (diff) | |
download | lua-34affe7a63fc5d842580a9f23616d057e17dfe27.tar.gz lua-34affe7a63fc5d842580a9f23616d057e17dfe27.tar.bz2 lua-34affe7a63fc5d842580a9f23616d057e17dfe27.zip |
Fixed bug: 'luaD_callnoyield' called twice in a row
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.)
-rw-r--r-- | ldo.c | 9 |
1 files changed, 4 insertions, 5 deletions
@@ -515,14 +515,13 @@ void luaD_call (lua_State *L, StkId func, int nresults) { | |||
515 | 515 | ||
516 | /* | 516 | /* |
517 | ** Similar to 'luaD_call', but does not allow yields during the call. | 517 | ** Similar to 'luaD_call', but does not allow yields during the call. |
518 | ** If there is a stack overflow, freeing all CI structures will | ||
519 | ** force the subsequent call to invoke 'luaE_extendCI', which then | ||
520 | ** will raise any errors. | ||
521 | */ | 518 | */ |
522 | void luaD_callnoyield (lua_State *L, StkId func, int nResults) { | 519 | void luaD_callnoyield (lua_State *L, StkId func, int nResults) { |
523 | incXCcalls(L); | 520 | incXCcalls(L); |
524 | if (getCcalls(L) <= CSTACKERR) /* possible stack overflow? */ | 521 | if (getCcalls(L) <= CSTACKERR) { /* possible C stack overflow? */ |
525 | luaE_freeCI(L); | 522 | luaE_exitCcall(L); /* to compensate decrement in next call */ |
523 | luaE_enterCcall(L); /* check properly */ | ||
524 | } | ||
526 | luaD_call(L, func, nResults); | 525 | luaD_call(L, func, nResults); |
527 | decXCcalls(L); | 526 | decXCcalls(L); |
528 | } | 527 | } |