aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-11-22 14:35:20 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-11-22 14:35:20 -0200
commit04b143ddf931f5312209ddfc1d8d14ede6997afd (patch)
tree3a06772a43d0b966e62e0e96a1ff729f8db4f921
parent007f229568ec47a2b6659ef3049b9ed03ccac72d (diff)
downloadlua-04b143ddf931f5312209ddfc1d8d14ede6997afd.tar.gz
lua-04b143ddf931f5312209ddfc1d8d14ede6997afd.tar.bz2
lua-04b143ddf931f5312209ddfc1d8d14ede6997afd.zip
avoid C stack overflow during parsing
-rw-r--r--llex.h3
-rw-r--r--llimits.h8
-rw-r--r--lparser.c15
3 files changed, 22 insertions, 4 deletions
diff --git a/llex.h b/llex.h
index d0e4216c..2df59d0b 100644
--- a/llex.h
+++ b/llex.h
@@ -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
diff --git a/llimits.h b/llimits.h
index ae24db35..c14e0203 100644
--- a/llimits.h
+++ b/llimits.h
@@ -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
diff --git a/lparser.c b/lparser.c
index 0c1997ea..3fbe451c 100644
--- a/lparser.c
+++ b/lparser.c
@@ -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*/
750static BinOpr subexpr (LexState *ls, expdesc *v, int limit) { 756static 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) {
1299static void chunk (LexState *ls) { 1308static 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