aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2020-07-17 14:54:26 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2020-07-17 14:54:26 -0300
commit34affe7a63fc5d842580a9f23616d057e17dfe27 (patch)
tree62283d8c88989180e8e971efe457a8b55afa16a0
parenta2195644d89812e5b157ce7bac35543e06db05e3 (diff)
downloadlua-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.c9
1 files changed, 4 insertions, 5 deletions
diff --git a/ldo.c b/ldo.c
index 98dd9fbb..5473815a 100644
--- a/ldo.c
+++ b/ldo.c
@@ -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*/
522void luaD_callnoyield (lua_State *L, StkId func, int nResults) { 519void 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}