diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2021-11-03 15:04:18 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2021-11-03 15:04:18 -0300 |
commit | 74d99057a5146755e737c479850f87fd0e3b6868 (patch) | |
tree | db3f0b0bc146572c0e6d9508543cd79be15dd875 /ldo.c | |
parent | 1fce5bea817de50e055a84c153a975f25bfcf493 (diff) | |
download | lua-74d99057a5146755e737c479850f87fd0e3b6868.tar.gz lua-74d99057a5146755e737c479850f87fd0e3b6868.tar.bz2 lua-74d99057a5146755e737c479850f87fd0e3b6868.zip |
Bug: C stack overflow with coroutines
'coroutine.resume' did not increment counter of C calls when
continuing execution after a protected error (that is,
while running 'precover').
Diffstat (limited to 'ldo.c')
-rw-r--r-- | ldo.c | 6 |
1 files changed, 4 insertions, 2 deletions
@@ -759,11 +759,10 @@ static void resume (lua_State *L, void *ud) { | |||
759 | StkId firstArg = L->top - n; /* first argument */ | 759 | StkId firstArg = L->top - n; /* first argument */ |
760 | CallInfo *ci = L->ci; | 760 | CallInfo *ci = L->ci; |
761 | if (L->status == LUA_OK) /* starting a coroutine? */ | 761 | if (L->status == LUA_OK) /* starting a coroutine? */ |
762 | ccall(L, firstArg - 1, LUA_MULTRET, 1); /* just call its body */ | 762 | ccall(L, firstArg - 1, LUA_MULTRET, 0); /* just call its body */ |
763 | else { /* resuming from previous yield */ | 763 | else { /* resuming from previous yield */ |
764 | lua_assert(L->status == LUA_YIELD); | 764 | lua_assert(L->status == LUA_YIELD); |
765 | L->status = LUA_OK; /* mark that it is running (again) */ | 765 | L->status = LUA_OK; /* mark that it is running (again) */ |
766 | luaE_incCstack(L); /* control the C stack */ | ||
767 | if (isLua(ci)) { /* yielded inside a hook? */ | 766 | if (isLua(ci)) { /* yielded inside a hook? */ |
768 | L->top = firstArg; /* discard arguments */ | 767 | L->top = firstArg; /* discard arguments */ |
769 | luaV_execute(L, ci); /* just continue running Lua code */ | 768 | luaV_execute(L, ci); /* just continue running Lua code */ |
@@ -814,6 +813,9 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs, | |||
814 | else if (L->status != LUA_YIELD) /* ended with errors? */ | 813 | else if (L->status != LUA_YIELD) /* ended with errors? */ |
815 | return resume_error(L, "cannot resume dead coroutine", nargs); | 814 | return resume_error(L, "cannot resume dead coroutine", nargs); |
816 | L->nCcalls = (from) ? getCcalls(from) : 0; | 815 | L->nCcalls = (from) ? getCcalls(from) : 0; |
816 | if (getCcalls(L) >= LUAI_MAXCCALLS) | ||
817 | return resume_error(L, "C stack overflow", nargs); | ||
818 | L->nCcalls++; | ||
817 | luai_userstateresume(L, nargs); | 819 | luai_userstateresume(L, nargs); |
818 | api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs); | 820 | api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs); |
819 | status = luaD_rawrunprotected(L, resume, &nargs); | 821 | status = luaD_rawrunprotected(L, resume, &nargs); |