diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2013-04-19 18:03:23 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2013-04-19 18:03:23 -0300 |
| commit | c2ea18726a466fd3c84446eb002e060c04815521 (patch) | |
| tree | f495c4ec0961deb02fb29782e0764c4922a999fd | |
| parent | 2ca518141350667e38941eac35b76980095d2fdc (diff) | |
| download | lua-c2ea18726a466fd3c84446eb002e060c04815521.tar.gz lua-c2ea18726a466fd3c84446eb002e060c04815521.tar.bz2 lua-c2ea18726a466fd3c84446eb002e060c04815521.zip | |
BUG: stack overflow in vararg functions with many fixed
parameters called with few arguments
| -rw-r--r-- | ldo.c | 15 |
1 files changed, 11 insertions, 4 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldo.c,v 2.108 2012/10/01 14:05:04 roberto Exp $ | 2 | ** $Id: ldo.c,v 2.108.1.1 2013/04/12 18:48:47 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 | */ |
| @@ -260,6 +260,7 @@ static StkId adjust_varargs (lua_State *L, Proto *p, int actual) { | |||
| 260 | StkId base, fixed; | 260 | StkId base, fixed; |
| 261 | lua_assert(actual >= nfixargs); | 261 | lua_assert(actual >= nfixargs); |
| 262 | /* move fixed parameters to final position */ | 262 | /* move fixed parameters to final position */ |
| 263 | luaD_checkstack(L, p->maxstacksize); /* check again for new 'base' */ | ||
| 263 | fixed = L->top - actual; /* first fixed argument */ | 264 | fixed = L->top - actual; /* first fixed argument */ |
| 264 | base = L->top; /* final position of first argument */ | 265 | base = L->top; /* final position of first argument */ |
| 265 | for (i=0; i<nfixargs; i++) { | 266 | for (i=0; i<nfixargs; i++) { |
| @@ -324,12 +325,18 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { | |||
| 324 | case LUA_TLCL: { /* Lua function: prepare its call */ | 325 | case LUA_TLCL: { /* Lua function: prepare its call */ |
| 325 | StkId base; | 326 | StkId base; |
| 326 | Proto *p = clLvalue(func)->p; | 327 | Proto *p = clLvalue(func)->p; |
| 327 | luaD_checkstack(L, p->maxstacksize); | ||
| 328 | func = restorestack(L, funcr); | ||
| 329 | n = cast_int(L->top - func) - 1; /* number of real arguments */ | 328 | n = cast_int(L->top - func) - 1; /* number of real arguments */ |
| 329 | luaD_checkstack(L, p->maxstacksize); | ||
| 330 | for (; n < p->numparams; n++) | 330 | for (; n < p->numparams; n++) |
| 331 | setnilvalue(L->top++); /* complete missing arguments */ | 331 | setnilvalue(L->top++); /* complete missing arguments */ |
| 332 | base = (!p->is_vararg) ? func + 1 : adjust_varargs(L, p, n); | 332 | if (!p->is_vararg) { |
| 333 | func = restorestack(L, funcr); | ||
| 334 | base = func + 1; | ||
| 335 | } | ||
| 336 | else { | ||
| 337 | base = adjust_varargs(L, p, n); | ||
| 338 | func = restorestack(L, funcr); /* previous call can change stack */ | ||
| 339 | } | ||
| 333 | ci = next_ci(L); /* now 'enter' new function */ | 340 | ci = next_ci(L); /* now 'enter' new function */ |
| 334 | ci->nresults = nresults; | 341 | ci->nresults = nresults; |
| 335 | ci->func = func; | 342 | ci->func = func; |
