mirror of https://github.com/rusefi/lua.git
avoid C stack overflow during parsing
This commit is contained in:
parent
007f229568
commit
04b143ddf9
3
llex.h
3
llex.h
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: llex.h,v 1.44 2002/09/03 11:57:38 roberto Exp roberto $
|
** $Id: llex.h,v 1.45 2002/10/08 18:46:08 roberto Exp roberto $
|
||||||
** Lexical Analyzer
|
** Lexical Analyzer
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -59,6 +59,7 @@ typedef struct LexState {
|
||||||
ZIO *z; /* input stream */
|
ZIO *z; /* input stream */
|
||||||
Mbuffer *buff; /* buffer for tokens */
|
Mbuffer *buff; /* buffer for tokens */
|
||||||
TString *source; /* current source name */
|
TString *source; /* current source name */
|
||||||
|
int nestlevel; /* level of nested non-terminals */
|
||||||
} LexState;
|
} LexState;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: llimits.h,v 1.46 2002/10/08 18:46:08 roberto Exp roberto $
|
** $Id: llimits.h,v 1.47 2002/10/22 17:18:28 roberto Exp roberto $
|
||||||
** Limits, basic types, and some other `installation-dependent' definitions
|
** Limits, basic types, and some other `installation-dependent' definitions
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -165,4 +165,10 @@ typedef unsigned long Instruction;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* maximum number of syntactical nested non-terminals */
|
||||||
|
#ifndef LUA_MAXPARSERLEVEL
|
||||||
|
#define LUA_MAXPARSERLEVEL 200
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
15
lparser.c
15
lparser.c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: lparser.c,v 1.196 2002/10/16 20:40:58 roberto Exp roberto $
|
** $Id: lparser.c,v 1.197 2002/11/22 13:59:04 roberto Exp roberto $
|
||||||
** Lua Parser
|
** Lua Parser
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -26,6 +26,10 @@
|
||||||
#define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]])
|
#define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]])
|
||||||
|
|
||||||
|
|
||||||
|
#define enterlevel(ls) if (++(ls)->nestlevel > LUA_MAXPARSERLEVEL) \
|
||||||
|
luaX_syntaxerror(ls, "too many syntax levels");
|
||||||
|
#define leavelevel(ls) ((ls)->nestlevel--)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** nodes for block list (list of active blocks)
|
** nodes for block list (list of active blocks)
|
||||||
|
@ -356,6 +360,7 @@ Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff) {
|
||||||
struct LexState lexstate;
|
struct LexState lexstate;
|
||||||
struct FuncState funcstate;
|
struct FuncState funcstate;
|
||||||
lexstate.buff = buff;
|
lexstate.buff = buff;
|
||||||
|
lexstate.nestlevel = 0;
|
||||||
luaX_setinput(L, &lexstate, z, luaS_new(L, zname(z)));
|
luaX_setinput(L, &lexstate, z, luaS_new(L, zname(z)));
|
||||||
open_func(&lexstate, &funcstate);
|
open_func(&lexstate, &funcstate);
|
||||||
next(&lexstate); /* read first token */
|
next(&lexstate); /* read first token */
|
||||||
|
@ -364,6 +369,7 @@ Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff) {
|
||||||
close_func(&lexstate);
|
close_func(&lexstate);
|
||||||
lua_assert(funcstate.prev == NULL);
|
lua_assert(funcstate.prev == NULL);
|
||||||
lua_assert(funcstate.f->nupvalues == 0);
|
lua_assert(funcstate.f->nupvalues == 0);
|
||||||
|
lua_assert(lexstate.nestlevel == 0);
|
||||||
return funcstate.f;
|
return funcstate.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -749,7 +755,9 @@ static const struct {
|
||||||
*/
|
*/
|
||||||
static BinOpr subexpr (LexState *ls, expdesc *v, int limit) {
|
static BinOpr subexpr (LexState *ls, expdesc *v, int limit) {
|
||||||
BinOpr op;
|
BinOpr op;
|
||||||
UnOpr uop = getunopr(ls->t.token);
|
UnOpr uop;
|
||||||
|
enterlevel(ls);
|
||||||
|
uop = getunopr(ls->t.token);
|
||||||
if (uop != OPR_NOUNOPR) {
|
if (uop != OPR_NOUNOPR) {
|
||||||
next(ls);
|
next(ls);
|
||||||
subexpr(ls, v, UNARY_PRIORITY);
|
subexpr(ls, v, UNARY_PRIORITY);
|
||||||
|
@ -768,6 +776,7 @@ static BinOpr subexpr (LexState *ls, expdesc *v, int limit) {
|
||||||
luaK_posfix(ls->fs, op, v, &v2);
|
luaK_posfix(ls->fs, op, v, &v2);
|
||||||
op = nextop;
|
op = nextop;
|
||||||
}
|
}
|
||||||
|
leavelevel(ls);
|
||||||
return op; /* return first untreated operator */
|
return op; /* return first untreated operator */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1299,11 +1308,13 @@ static void body (LexState *ls, expdesc *e, int needself, int line) {
|
||||||
static void chunk (LexState *ls) {
|
static void chunk (LexState *ls) {
|
||||||
/* chunk -> { stat [`;'] } */
|
/* chunk -> { stat [`;'] } */
|
||||||
int islast = 0;
|
int islast = 0;
|
||||||
|
enterlevel(ls);
|
||||||
while (!islast && !block_follow(ls->t.token)) {
|
while (!islast && !block_follow(ls->t.token)) {
|
||||||
islast = statement(ls);
|
islast = statement(ls);
|
||||||
testnext(ls, ';');
|
testnext(ls, ';');
|
||||||
lua_assert(ls->fs->freereg >= ls->fs->nactvar);
|
lua_assert(ls->fs->freereg >= ls->fs->nactvar);
|
||||||
ls->fs->freereg = ls->fs->nactvar; /* free registers */
|
ls->fs->freereg = ls->fs->nactvar; /* free registers */
|
||||||
}
|
}
|
||||||
|
leavelevel(ls);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue