commit f9e35627ed26dff4114a1d01ff113d8b4cc91ab5
parent ceac82f78be8baeddfa8536472d8b08df2eb7d49
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Wed, 26 Feb 2025 11:30:43 -0300
'lua_State.nci' must be an integer
Lua can easily overflow an unsigned short counting nested calls.
(The limit to this value is the maximum stack size, LUAI_MAXSTACK,
which is currently 1e6.)
Diffstat:
3 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/lstate.h b/lstate.h
@@ -290,7 +290,6 @@ struct lua_State {
CommonHeader;
lu_byte allowhook;
TStatus status;
- unsigned short nci; /* number of items in 'ci' list */
StkIdRel top; /* first free slot in the stack */
struct global_State *l_G;
CallInfo *ci; /* call info for current function */
@@ -306,6 +305,7 @@ struct lua_State {
ptrdiff_t errfunc; /* current error handling function (stack index) */
l_uint32 nCcalls; /* number of nested non-yieldable or C calls */
int oldpc; /* last pc traced */
+ int nci; /* number of items in 'ci' list */
int basehookcount;
int hookcount;
volatile l_signalT hookmask;
diff --git a/ltests.h b/ltests.h
@@ -152,9 +152,12 @@ LUA_API void *debug_realloc (void *ud, void *block,
*/
-/* make stack-overflow tests run faster */
+/*
+** Reduce maximum stack size to make stack-overflow tests run faster.
+** (But value is still large enough to overflow smaller integers.)
+*/
#undef LUAI_MAXSTACK
-#define LUAI_MAXSTACK 50000
+#define LUAI_MAXSTACK 68000
/* test mode uses more stack space */
diff --git a/testes/coroutine.lua b/testes/coroutine.lua
@@ -127,6 +127,18 @@ assert(#a == 22 and a[#a] == 79)
x, a = nil
+do -- "bug" in 5.4.2
+ local function foo () foo () end -- just create a stack overflow
+ local co = coroutine.create(foo)
+ -- running this coroutine would overflow the unsigned short 'nci', the
+ -- counter of CallInfo structures available to the thread.
+ -- (The issue only manifests in an 'assert'.)
+ local st, msg = coroutine.resume(co)
+ assert(string.find(msg, "stack overflow"))
+ assert(coroutine.status(co) == "dead")
+end
+
+
print("to-be-closed variables in coroutines")
local function func2close (f)