aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2004-09-08 11:23:09 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2004-09-08 11:23:09 -0300
commit0de2065f4e7cbbbe301b07835b9dd0b1bd1a4bbb (patch)
tree6f578771ff27c6a352b52ba721fbcf163c610945
parentee165043ef917688d6e9151fc1a98d1e0f3e6ab1 (diff)
downloadlua-0de2065f4e7cbbbe301b07835b9dd0b1bd1a4bbb.tar.gz
lua-0de2065f4e7cbbbe301b07835b9dd0b1bd1a4bbb.tar.bz2
lua-0de2065f4e7cbbbe301b07835b9dd0b1bd1a4bbb.zip
tighter tests for stack overflow
-rw-r--r--ldo.c34
-rw-r--r--ldo.h6
-rw-r--r--lgc.c17
-rw-r--r--lstate.c4
4 files changed, 37 insertions, 24 deletions
diff --git a/ldo.c b/ldo.c
index 5aa6b5c0..19c57153 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 2.7 2004/06/02 19:07:55 roberto Exp roberto $ 2** $Id: ldo.c,v 2.8 2004/09/03 15:48:56 roberto Exp roberto $
3** Stack and Call structure of Lua 3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -93,7 +93,7 @@ int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
93 93
94 94
95static void restore_stack_limit (lua_State *L) { 95static void restore_stack_limit (lua_State *L) {
96 L->stack_last = L->stack+L->stacksize-1; 96 lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1);
97 if (L->size_ci > LUA_MAXCALLS) { /* there was an overflow? */ 97 if (L->size_ci > LUA_MAXCALLS) { /* there was an overflow? */
98 int inuse = (L->ci - L->base_ci); 98 int inuse = (L->ci - L->base_ci);
99 if (inuse + 1 < LUA_MAXCALLS) /* can `undo' overflow? */ 99 if (inuse + 1 < LUA_MAXCALLS) /* can `undo' overflow? */
@@ -121,9 +121,11 @@ static void correctstack (lua_State *L, TValue *oldstack) {
121 121
122void luaD_reallocstack (lua_State *L, int newsize) { 122void luaD_reallocstack (lua_State *L, int newsize) {
123 TValue *oldstack = L->stack; 123 TValue *oldstack = L->stack;
124 luaM_reallocvector(L, L->stack, L->stacksize, newsize, TValue); 124 int realsize = newsize + 1 + EXTRA_STACK;
125 L->stacksize = newsize; 125 lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1);
126 L->stack_last = L->stack+newsize-1-EXTRA_STACK; 126 luaM_reallocvector(L, L->stack, L->stacksize, realsize, TValue);
127 L->stacksize = realsize;
128 L->stack_last = L->stack+newsize;
127 correctstack(L, oldstack); 129 correctstack(L, oldstack);
128} 130}
129 131
@@ -133,7 +135,7 @@ void luaD_reallocCI (lua_State *L, int newsize) {
133 luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo); 135 luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo);
134 L->size_ci = cast(unsigned short, newsize); 136 L->size_ci = cast(unsigned short, newsize);
135 L->ci = (L->ci - oldci) + L->base_ci; 137 L->ci = (L->ci - oldci) + L->base_ci;
136 L->end_ci = L->base_ci + L->size_ci; 138 L->end_ci = L->base_ci + L->size_ci - 1;
137} 139}
138 140
139 141
@@ -141,11 +143,11 @@ void luaD_growstack (lua_State *L, int n) {
141 if (n <= L->stacksize) /* double size is enough? */ 143 if (n <= L->stacksize) /* double size is enough? */
142 luaD_reallocstack(L, 2*L->stacksize); 144 luaD_reallocstack(L, 2*L->stacksize);
143 else 145 else
144 luaD_reallocstack(L, L->stacksize + n + EXTRA_STACK); 146 luaD_reallocstack(L, L->stacksize + n);
145} 147}
146 148
147 149
148static void luaD_growCI (lua_State *L) { 150static CallInfo *luaD_growCI (lua_State *L) {
149 if (L->size_ci > LUA_MAXCALLS) /* overflow while handling overflow? */ 151 if (L->size_ci > LUA_MAXCALLS) /* overflow while handling overflow? */
150 luaD_throw(L, LUA_ERRERR); 152 luaD_throw(L, LUA_ERRERR);
151 else { 153 else {
@@ -153,6 +155,7 @@ static void luaD_growCI (lua_State *L) {
153 if (L->size_ci > LUA_MAXCALLS) 155 if (L->size_ci > LUA_MAXCALLS)
154 luaG_runerror(L, "stack overflow"); 156 luaG_runerror(L, "stack overflow");
155 } 157 }
158 return ++L->ci;
156} 159}
157 160
158 161
@@ -170,6 +173,7 @@ void luaD_callhook (lua_State *L, int event, int line) {
170 ar.i_ci = L->ci - L->base_ci; 173 ar.i_ci = L->ci - L->base_ci;
171 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ 174 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
172 L->ci->top = L->top + LUA_MINSTACK; 175 L->ci->top = L->top + LUA_MINSTACK;
176 lua_assert(L->ci->top <= L->stack_last);
173 L->allowhook = 0; /* cannot call hooks inside a hook */ 177 L->allowhook = 0; /* cannot call hooks inside a hook */
174 lua_unlock(L); 178 lua_unlock(L);
175 (*hook)(L, &ar); 179 (*hook)(L, &ar);
@@ -232,14 +236,18 @@ static StkId tryfuncTM (lua_State *L, StkId func) {
232} 236}
233 237
234 238
239
240#define inc_ci(L) \
241 ((L->ci == L->end_ci) ? luaD_growCI(L) : \
242 (condhardstacktests(luaD_reallocCI(L, L->size_ci)), ++L->ci))
243
244
235int luaD_precall (lua_State *L, StkId func, int nresults) { 245int luaD_precall (lua_State *L, StkId func, int nresults) {
236 LClosure *cl; 246 LClosure *cl;
237 ptrdiff_t funcr; 247 ptrdiff_t funcr;
238 if (!ttisfunction(func)) /* `func' is not a function? */ 248 if (!ttisfunction(func)) /* `func' is not a function? */
239 func = tryfuncTM(L, func); /* check the `function' tag method */ 249 func = tryfuncTM(L, func); /* check the `function' tag method */
240 funcr = savestack(L, func); 250 funcr = savestack(L, func);
241 if (L->ci + 1 == L->end_ci) luaD_growCI(L);
242 else condhardstacktests(luaD_reallocCI(L, L->size_ci));
243 cl = &clvalue(func)->l; 251 cl = &clvalue(func)->l;
244 if (!cl->isC) { /* Lua function? prepare its call */ 252 if (!cl->isC) { /* Lua function? prepare its call */
245 CallInfo *ci; 253 CallInfo *ci;
@@ -256,10 +264,11 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
256 func = restorestack(L, funcr); 264 func = restorestack(L, funcr);
257 base = func + 1; 265 base = func + 1;
258 } 266 }
259 ci = ++L->ci; /* now `enter' new function */ 267 ci = inc_ci(L); /* now `enter' new function */
260 ci->func = func; 268 ci->func = func;
261 L->base = ci->base = base; 269 L->base = ci->base = base;
262 ci->top = L->base + p->maxstacksize; 270 ci->top = L->base + p->maxstacksize;
271 lua_assert(ci->top <= L->stack_last);
263 ci->savedpc = p->code; /* starting point */ 272 ci->savedpc = p->code; /* starting point */
264 ci->tailcalls = 0; 273 ci->tailcalls = 0;
265 ci->nresults = nresults; 274 ci->nresults = nresults;
@@ -272,10 +281,11 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
272 CallInfo *ci; 281 CallInfo *ci;
273 int n; 282 int n;
274 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ 283 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
275 ci = ++L->ci; /* now `enter' new function */ 284 ci = inc_ci(L); /* now `enter' new function */
276 ci->func = restorestack(L, funcr); 285 ci->func = restorestack(L, funcr);
277 L->base = ci->base = ci->func + 1; 286 L->base = ci->base = ci->func + 1;
278 ci->top = L->top + LUA_MINSTACK; 287 ci->top = L->top + LUA_MINSTACK;
288 lua_assert(ci->top <= L->stack_last);
279 if (L->hookmask & LUA_MASKCALL) 289 if (L->hookmask & LUA_MASKCALL)
280 luaD_callhook(L, LUA_HOOKCALL, -1); 290 luaD_callhook(L, LUA_HOOKCALL, -1);
281 lua_unlock(L); 291 lua_unlock(L);
diff --git a/ldo.h b/ldo.h
index 8e2e026b..665934bd 100644
--- a/ldo.h
+++ b/ldo.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.h,v 2.1 2003/12/10 12:13:36 roberto Exp roberto $ 2** $Id: ldo.h,v 2.2 2004/05/14 19:25:09 roberto Exp roberto $
3** Stack and Call structure of Lua 3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -17,7 +17,7 @@
17** macro to control inclusion of some hard tests on stack reallocation 17** macro to control inclusion of some hard tests on stack reallocation
18*/ 18*/
19#ifndef HARDSTACKTESTS 19#ifndef HARDSTACKTESTS
20#define condhardstacktests(x) { /* empty */ } 20#define condhardstacktests(x) ((void)0)
21#else 21#else
22#define condhardstacktests(x) x 22#define condhardstacktests(x) x
23#endif 23#endif
@@ -26,7 +26,7 @@
26#define luaD_checkstack(L,n) \ 26#define luaD_checkstack(L,n) \
27 if ((char *)L->stack_last - (char *)L->top <= (n)*(int)sizeof(TValue)) \ 27 if ((char *)L->stack_last - (char *)L->top <= (n)*(int)sizeof(TValue)) \
28 luaD_growstack(L, n); \ 28 luaD_growstack(L, n); \
29 else condhardstacktests(luaD_reallocstack(L, L->stacksize)); 29 else condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1));
30 30
31 31
32#define incr_top(L) {luaD_checkstack(L,1); L->top++;} 32#define incr_top(L) {luaD_checkstack(L,1); L->top++;}
diff --git a/lgc.c b/lgc.c
index 94d801ab..6beaa55b 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 2.9 2004/08/24 20:12:06 roberto Exp roberto $ 2** $Id: lgc.c,v 2.10 2004/08/30 13:44:44 roberto Exp roberto $
3** Garbage Collector 3** Garbage Collector
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -239,14 +239,17 @@ static void traverseclosure (global_State *g, Closure *cl) {
239 239
240 240
241static void checkstacksizes (lua_State *L, StkId max) { 241static void checkstacksizes (lua_State *L, StkId max) {
242 int used = L->ci - L->base_ci; /* number of `ci' in use */ 242 int ci_used = L->ci - L->base_ci; /* number of `ci' in use */
243 if (4*used < L->size_ci && 2*BASIC_CI_SIZE < L->size_ci) 243 int s_used = max - L->stack; /* part of stack in use */
244 if (L->size_ci > LUA_MAXCALLS) /* handling overflow? */
245 return; /* do not touch the stacks */
246 if (4*ci_used < L->size_ci && 2*BASIC_CI_SIZE < L->size_ci)
244 luaD_reallocCI(L, L->size_ci/2); /* still big enough... */ 247 luaD_reallocCI(L, L->size_ci/2); /* still big enough... */
245 else condhardstacktests(luaD_reallocCI(L, L->size_ci)); 248 condhardstacktests(luaD_reallocCI(L, ci_used + 1));
246 used = max - L->stack; /* part of stack in use */ 249 if (4*s_used < L->stacksize &&
247 if (4*used < L->stacksize && 2*(BASIC_STACK_SIZE+EXTRA_STACK) < L->stacksize) 250 2*(BASIC_STACK_SIZE+EXTRA_STACK) < L->stacksize)
248 luaD_reallocstack(L, L->stacksize/2); /* still big enough... */ 251 luaD_reallocstack(L, L->stacksize/2); /* still big enough... */
249 else condhardstacktests(luaD_reallocstack(L, L->stacksize)); 252 condhardstacktests(luaD_reallocstack(L, s_used));
250} 253}
251 254
252 255
diff --git a/lstate.c b/lstate.c
index 568d8e72..0a2eaefb 100644
--- a/lstate.c
+++ b/lstate.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.c,v 2.11 2004/08/24 20:12:06 roberto Exp roberto $ 2** $Id: lstate.c,v 2.12 2004/08/30 13:44:44 roberto Exp $
3** Global State 3** Global State
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -62,7 +62,7 @@ static void stack_init (lua_State *L1, lua_State *L) {
62 L1->base = L1->ci->base = L1->top; 62 L1->base = L1->ci->base = L1->top;
63 L1->ci->top = L1->top + LUA_MINSTACK; 63 L1->ci->top = L1->top + LUA_MINSTACK;
64 L1->size_ci = BASIC_CI_SIZE; 64 L1->size_ci = BASIC_CI_SIZE;
65 L1->end_ci = L1->base_ci + L1->size_ci; 65 L1->end_ci = L1->base_ci + L1->size_ci - 1;
66} 66}
67 67
68 68