aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2022-05-23 10:38:03 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2022-05-23 10:38:03 -0300
commit4a00f61276a9a38b0427fbae3dbbd86dfb5a0749 (patch)
tree16ed717a2f4b79bad0743c2a8888ba55e013a309
parent42d40581dd919fb134c07027ca1ce0844c670daf (diff)
downloadlua-4a00f61276a9a38b0427fbae3dbbd86dfb5a0749.tar.gz
lua-4a00f61276a9a38b0427fbae3dbbd86dfb5a0749.tar.bz2
lua-4a00f61276a9a38b0427fbae3dbbd86dfb5a0749.zip
'lua_checkstack' doesn't need to check stack overflow
'luaD_growstack' already checks that. This commit also fixes an internal bug in 'luaD_growstack': a large 'n' could cause an arithmetic overflow when computing 'needed'.
-rwxr-xr-xall2
-rw-r--r--lapi.c9
-rw-r--r--ldo.c15
-rw-r--r--luaconf.h2
-rw-r--r--testes/coroutine.lua15
5 files changed, 17 insertions, 26 deletions
diff --git a/all b/all
index 039f6095..86f38ac1 100755
--- a/all
+++ b/all
@@ -1,7 +1,7 @@
1make -s -j 1make -s -j
2cd testes/libs; make -s 2cd testes/libs; make -s
3cd .. # back to directory 'testes' 3cd .. # back to directory 'testes'
4ulimit -S -s 1000 4ulimit -S -s 1100
5if { ../lua -W all.lua; } then 5if { ../lua -W all.lua; } then
6 echo -e "\n\n final OK!!!!\n\n" 6 echo -e "\n\n final OK!!!!\n\n"
7else 7else
diff --git a/lapi.c b/lapi.c
index 5ee65792..352a385a 100644
--- a/lapi.c
+++ b/lapi.c
@@ -114,13 +114,8 @@ LUA_API int lua_checkstack (lua_State *L, int n) {
114 api_check(L, n >= 0, "negative 'n'"); 114 api_check(L, n >= 0, "negative 'n'");
115 if (L->stack_last - L->top > n) /* stack large enough? */ 115 if (L->stack_last - L->top > n) /* stack large enough? */
116 res = 1; /* yes; check is OK */ 116 res = 1; /* yes; check is OK */
117 else { /* no; need to grow stack */ 117 else /* need to grow stack */
118 int inuse = cast_int(L->top - L->stack) + EXTRA_STACK; 118 res = luaD_growstack(L, n, 0);
119 if (inuse > LUAI_MAXSTACK - n) /* can grow without overflow? */
120 res = 0; /* no */
121 else /* try to grow stack */
122 res = luaD_growstack(L, n, 0);
123 }
124 if (res && ci->top < L->top + n) 119 if (res && ci->top < L->top + n)
125 ci->top = L->top + n; /* adjust frame top */ 120 ci->top = L->top + n; /* adjust frame top */
126 lua_unlock(L); 121 lua_unlock(L);
diff --git a/ldo.c b/ldo.c
index 8e4faf02..5aa6d59d 100644
--- a/ldo.c
+++ b/ldo.c
@@ -227,7 +227,7 @@ int luaD_growstack (lua_State *L, int n, int raiseerror) {
227 luaD_throw(L, LUA_ERRERR); /* error inside message handler */ 227 luaD_throw(L, LUA_ERRERR); /* error inside message handler */
228 return 0; /* if not 'raiseerror', just signal it */ 228 return 0; /* if not 'raiseerror', just signal it */
229 } 229 }
230 else { 230 else if (n < LUAI_MAXSTACK) { /* avoids arithmetic overflows */
231 int newsize = 2 * size; /* tentative new size */ 231 int newsize = 2 * size; /* tentative new size */
232 int needed = cast_int(L->top - L->stack) + n; 232 int needed = cast_int(L->top - L->stack) + n;
233 if (newsize > LUAI_MAXSTACK) /* cannot cross the limit */ 233 if (newsize > LUAI_MAXSTACK) /* cannot cross the limit */
@@ -236,14 +236,13 @@ int luaD_growstack (lua_State *L, int n, int raiseerror) {
236 newsize = needed; 236 newsize = needed;
237 if (l_likely(newsize <= LUAI_MAXSTACK)) 237 if (l_likely(newsize <= LUAI_MAXSTACK))
238 return luaD_reallocstack(L, newsize, raiseerror); 238 return luaD_reallocstack(L, newsize, raiseerror);
239 else { /* stack overflow */
240 /* add extra size to be able to handle the error message */
241 luaD_reallocstack(L, ERRORSTACKSIZE, raiseerror);
242 if (raiseerror)
243 luaG_runerror(L, "stack overflow");
244 return 0;
245 }
246 } 239 }
240 /* else stack overflow */
241 /* add extra size to be able to handle the error message */
242 luaD_reallocstack(L, ERRORSTACKSIZE, raiseerror);
243 if (raiseerror)
244 luaG_runerror(L, "stack overflow");
245 return 0;
247} 246}
248 247
249 248
diff --git a/luaconf.h b/luaconf.h
index d42d14b7..fcc0018b 100644
--- a/luaconf.h
+++ b/luaconf.h
@@ -728,7 +728,7 @@
728** CHANGE it if you need a different limit. This limit is arbitrary; 728** CHANGE it if you need a different limit. This limit is arbitrary;
729** its only purpose is to stop Lua from consuming unlimited stack 729** its only purpose is to stop Lua from consuming unlimited stack
730** space (and to reserve some numbers for pseudo-indices). 730** space (and to reserve some numbers for pseudo-indices).
731** (It must fit into max(size_t)/32.) 731** (It must fit into max(size_t)/32 and max(int)/2.)
732*/ 732*/
733#if LUAI_IS32INT 733#if LUAI_IS32INT
734#define LUAI_MAXSTACK 1000000 734#define LUAI_MAXSTACK 1000000
diff --git a/testes/coroutine.lua b/testes/coroutine.lua
index 76c9d6e6..15fccc30 100644
--- a/testes/coroutine.lua
+++ b/testes/coroutine.lua
@@ -741,20 +741,17 @@ _X()
741 741
742if not _soft then 742if not _soft then
743 -- bug (stack overflow) 743 -- bug (stack overflow)
744 local j = 2^9 744 local lim = 1000000 -- stack limit; assume 32-bit machine
745 local lim = 1000000 -- (C stack limit; assume 32-bit machine) 745 local t = {lim - 10, lim - 5, lim - 1, lim, lim + 1, lim + 5}
746 local t = {lim - 10, lim - 5, lim - 1, lim, lim + 1}
747 for i = 1, #t do 746 for i = 1, #t do
748 local j = t[i] 747 local j = t[i]
749 co = coroutine.create(function() 748 local co = coroutine.create(function()
750 local t = {} 749 return table.unpack({}, 1, j)
751 for i = 1, j do t[i] = i end
752 return table.unpack(t)
753 end) 750 end)
754 local r, msg = coroutine.resume(co) 751 local r, msg = coroutine.resume(co)
755 assert(not r) 752 -- must fail for unpacking larger than stack limit
753 assert(j < lim or not r)
756 end 754 end
757 co = nil
758end 755end
759 756
760 757