瀏覽代碼

'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.)
Roberto Ierusalimschy 5 月之前
父節點
當前提交
f9e35627ed
共有 3 個文件被更改,包括 18 次插入3 次删除
  1. 1 1
      lstate.h
  2. 5 2
      ltests.h
  3. 12 0
      testes/coroutine.lua

+ 1 - 1
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;

+ 5 - 2
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 */

+ 12 - 0
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)