diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-11-22 14:35:20 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-11-22 14:35:20 -0200 |
| commit | 04b143ddf931f5312209ddfc1d8d14ede6997afd (patch) | |
| tree | 3a06772a43d0b966e62e0e96a1ff729f8db4f921 | |
| parent | 007f229568ec47a2b6659ef3049b9ed03ccac72d (diff) | |
| download | lua-04b143ddf931f5312209ddfc1d8d14ede6997afd.tar.gz lua-04b143ddf931f5312209ddfc1d8d14ede6997afd.tar.bz2 lua-04b143ddf931f5312209ddfc1d8d14ede6997afd.zip | |
avoid C stack overflow during parsing
| -rw-r--r-- | llex.h | 3 | ||||
| -rw-r--r-- | llimits.h | 8 | ||||
| -rw-r--r-- | lparser.c | 15 |
3 files changed, 22 insertions, 4 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: llex.h,v 1.44 2002/09/03 11:57:38 roberto Exp roberto $ | 2 | ** $Id: llex.h,v 1.45 2002/10/08 18:46:08 roberto Exp roberto $ |
| 3 | ** Lexical Analyzer | 3 | ** Lexical Analyzer |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -59,6 +59,7 @@ typedef struct LexState { | |||
| 59 | ZIO *z; /* input stream */ | 59 | ZIO *z; /* input stream */ |
| 60 | Mbuffer *buff; /* buffer for tokens */ | 60 | Mbuffer *buff; /* buffer for tokens */ |
| 61 | TString *source; /* current source name */ | 61 | TString *source; /* current source name */ |
| 62 | int nestlevel; /* level of nested non-terminals */ | ||
| 62 | } LexState; | 63 | } LexState; |
| 63 | 64 | ||
| 64 | 65 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: llimits.h,v 1.46 2002/10/08 18:46:08 roberto Exp roberto $ | 2 | ** $Id: llimits.h,v 1.47 2002/10/22 17:18:28 roberto Exp roberto $ |
| 3 | ** Limits, basic types, and some other `installation-dependent' definitions | 3 | ** Limits, basic types, and some other `installation-dependent' definitions |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -165,4 +165,10 @@ typedef unsigned long Instruction; | |||
| 165 | #endif | 165 | #endif |
| 166 | 166 | ||
| 167 | 167 | ||
| 168 | /* maximum number of syntactical nested non-terminals */ | ||
| 169 | #ifndef LUA_MAXPARSERLEVEL | ||
| 170 | #define LUA_MAXPARSERLEVEL 200 | ||
| 171 | #endif | ||
| 172 | |||
| 173 | |||
| 168 | #endif | 174 | #endif |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lparser.c,v 1.196 2002/10/16 20:40:58 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 1.197 2002/11/22 13:59:04 roberto Exp roberto $ |
| 3 | ** Lua Parser | 3 | ** Lua Parser |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -26,6 +26,10 @@ | |||
| 26 | #define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]]) | 26 | #define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]]) |
| 27 | 27 | ||
| 28 | 28 | ||
| 29 | #define enterlevel(ls) if (++(ls)->nestlevel > LUA_MAXPARSERLEVEL) \ | ||
| 30 | luaX_syntaxerror(ls, "too many syntax levels"); | ||
| 31 | #define leavelevel(ls) ((ls)->nestlevel--) | ||
| 32 | |||
| 29 | 33 | ||
| 30 | /* | 34 | /* |
| 31 | ** nodes for block list (list of active blocks) | 35 | ** nodes for block list (list of active blocks) |
| @@ -356,6 +360,7 @@ Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff) { | |||
| 356 | struct LexState lexstate; | 360 | struct LexState lexstate; |
| 357 | struct FuncState funcstate; | 361 | struct FuncState funcstate; |
| 358 | lexstate.buff = buff; | 362 | lexstate.buff = buff; |
| 363 | lexstate.nestlevel = 0; | ||
| 359 | luaX_setinput(L, &lexstate, z, luaS_new(L, zname(z))); | 364 | luaX_setinput(L, &lexstate, z, luaS_new(L, zname(z))); |
| 360 | open_func(&lexstate, &funcstate); | 365 | open_func(&lexstate, &funcstate); |
| 361 | next(&lexstate); /* read first token */ | 366 | next(&lexstate); /* read first token */ |
| @@ -364,6 +369,7 @@ Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff) { | |||
| 364 | close_func(&lexstate); | 369 | close_func(&lexstate); |
| 365 | lua_assert(funcstate.prev == NULL); | 370 | lua_assert(funcstate.prev == NULL); |
| 366 | lua_assert(funcstate.f->nupvalues == 0); | 371 | lua_assert(funcstate.f->nupvalues == 0); |
| 372 | lua_assert(lexstate.nestlevel == 0); | ||
| 367 | return funcstate.f; | 373 | return funcstate.f; |
| 368 | } | 374 | } |
| 369 | 375 | ||
| @@ -749,7 +755,9 @@ static const struct { | |||
| 749 | */ | 755 | */ |
| 750 | static BinOpr subexpr (LexState *ls, expdesc *v, int limit) { | 756 | static BinOpr subexpr (LexState *ls, expdesc *v, int limit) { |
| 751 | BinOpr op; | 757 | BinOpr op; |
| 752 | UnOpr uop = getunopr(ls->t.token); | 758 | UnOpr uop; |
| 759 | enterlevel(ls); | ||
| 760 | uop = getunopr(ls->t.token); | ||
| 753 | if (uop != OPR_NOUNOPR) { | 761 | if (uop != OPR_NOUNOPR) { |
| 754 | next(ls); | 762 | next(ls); |
| 755 | subexpr(ls, v, UNARY_PRIORITY); | 763 | subexpr(ls, v, UNARY_PRIORITY); |
| @@ -768,6 +776,7 @@ static BinOpr subexpr (LexState *ls, expdesc *v, int limit) { | |||
| 768 | luaK_posfix(ls->fs, op, v, &v2); | 776 | luaK_posfix(ls->fs, op, v, &v2); |
| 769 | op = nextop; | 777 | op = nextop; |
| 770 | } | 778 | } |
| 779 | leavelevel(ls); | ||
| 771 | return op; /* return first untreated operator */ | 780 | return op; /* return first untreated operator */ |
| 772 | } | 781 | } |
| 773 | 782 | ||
| @@ -1299,11 +1308,13 @@ static void body (LexState *ls, expdesc *e, int needself, int line) { | |||
| 1299 | static void chunk (LexState *ls) { | 1308 | static void chunk (LexState *ls) { |
| 1300 | /* chunk -> { stat [`;'] } */ | 1309 | /* chunk -> { stat [`;'] } */ |
| 1301 | int islast = 0; | 1310 | int islast = 0; |
| 1311 | enterlevel(ls); | ||
| 1302 | while (!islast && !block_follow(ls->t.token)) { | 1312 | while (!islast && !block_follow(ls->t.token)) { |
| 1303 | islast = statement(ls); | 1313 | islast = statement(ls); |
| 1304 | testnext(ls, ';'); | 1314 | testnext(ls, ';'); |
| 1305 | lua_assert(ls->fs->freereg >= ls->fs->nactvar); | 1315 | lua_assert(ls->fs->freereg >= ls->fs->nactvar); |
| 1306 | ls->fs->freereg = ls->fs->nactvar; /* free registers */ | 1316 | ls->fs->freereg = ls->fs->nactvar; /* free registers */ |
| 1307 | } | 1317 | } |
| 1318 | leavelevel(ls); | ||
| 1308 | } | 1319 | } |
| 1309 | 1320 | ||
