aboutsummaryrefslogtreecommitdiff
path: root/lparser.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-07-26 13:27:43 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-07-26 13:27:43 -0300
commite70f275f32a5339a86be6f8b9d08c20cb874b205 (patch)
tree4ef2a00ab5ac8dffa8a6ee5e8af33a0c0380f1b0 /lparser.c
parent9a37dc0ce64c51fd57f5e658a5af8f3671a26b0a (diff)
downloadlua-e70f275f32a5339a86be6f8b9d08c20cb874b205.tar.gz
lua-e70f275f32a5339a86be6f8b9d08c20cb874b205.tar.bz2
lua-e70f275f32a5339a86be6f8b9d08c20cb874b205.zip
Bug: 'Vardesc' array can be reallocated in 'localstat'
A reference to a 'Vardesc*' (as done by 'localstat') can be invalidated by the creation of any new variable.
Diffstat (limited to 'lparser.c')
-rw-r--r--lparser.c27
1 files changed, 15 insertions, 12 deletions
diff --git a/lparser.c b/lparser.c
index 7447222b..f1d2ce85 100644
--- a/lparser.c
+++ b/lparser.c
@@ -187,9 +187,10 @@ static int registerlocalvar (LexState *ls, FuncState *fs, TString *varname) {
187 187
188 188
189/* 189/*
190** Create a new local variable with the given 'name'. 190** Create a new local variable with the given 'name'. Return its index
191** in the function.
191*/ 192*/
192static Vardesc *new_localvar (LexState *ls, TString *name) { 193static int new_localvar (LexState *ls, TString *name, int kind) {
193 lua_State *L = ls->L; 194 lua_State *L = ls->L;
194 FuncState *fs = ls->fs; 195 FuncState *fs = ls->fs;
195 Dyndata *dyd = ls->dyd; 196 Dyndata *dyd = ls->dyd;
@@ -199,13 +200,14 @@ static Vardesc *new_localvar (LexState *ls, TString *name) {
199 luaM_growvector(L, dyd->actvar.arr, dyd->actvar.n + 1, 200 luaM_growvector(L, dyd->actvar.arr, dyd->actvar.n + 1,
200 dyd->actvar.size, Vardesc, USHRT_MAX, "local variables"); 201 dyd->actvar.size, Vardesc, USHRT_MAX, "local variables");
201 var = &dyd->actvar.arr[dyd->actvar.n++]; 202 var = &dyd->actvar.arr[dyd->actvar.n++];
202 var->vd.kind = VDKREG; /* default is a regular variable */ 203 var->vd.kind = kind;
203 var->vd.name = name; 204 var->vd.name = name;
204 return var; 205 return dyd->actvar.n - 1 - fs->firstlocal;
205} 206}
206 207
207#define new_localvarliteral(ls,v) \ 208#define new_localvarliteral(ls,v) \
208 new_localvar(ls, luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char)) - 1)); 209 new_localvar(ls, \
210 luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char)) - 1), VDKREG);
209 211
210 212
211 213
@@ -945,7 +947,7 @@ static void parlist (LexState *ls) {
945 do { 947 do {
946 switch (ls->t.token) { 948 switch (ls->t.token) {
947 case TK_NAME: { /* param -> NAME */ 949 case TK_NAME: { /* param -> NAME */
948 new_localvar(ls, str_checkname(ls)); 950 new_localvar(ls, str_checkname(ls), VDKREG);
949 nparams++; 951 nparams++;
950 break; 952 break;
951 } 953 }
@@ -1551,7 +1553,7 @@ static void fornum (LexState *ls, TString *varname, int line) {
1551 new_localvarliteral(ls, "(for state)"); 1553 new_localvarliteral(ls, "(for state)");
1552 new_localvarliteral(ls, "(for state)"); 1554 new_localvarliteral(ls, "(for state)");
1553 new_localvarliteral(ls, "(for state)"); 1555 new_localvarliteral(ls, "(for state)");
1554 new_localvar(ls, varname); 1556 new_localvar(ls, varname, VDKREG);
1555 checknext(ls, '='); 1557 checknext(ls, '=');
1556 exp1(ls); /* initial value */ 1558 exp1(ls); /* initial value */
1557 checknext(ls, ','); 1559 checknext(ls, ',');
@@ -1580,9 +1582,9 @@ static void forlist (LexState *ls, TString *indexname) {
1580 new_localvarliteral(ls, "(for state)"); 1582 new_localvarliteral(ls, "(for state)");
1581 new_localvarliteral(ls, "(for state)"); 1583 new_localvarliteral(ls, "(for state)");
1582 /* create declared variables */ 1584 /* create declared variables */
1583 new_localvar(ls, indexname); 1585 new_localvar(ls, indexname, VDKREG);
1584 while (testnext(ls, ',')) { 1586 while (testnext(ls, ',')) {
1585 new_localvar(ls, str_checkname(ls)); 1587 new_localvar(ls, str_checkname(ls), VDKREG);
1586 nvars++; 1588 nvars++;
1587 } 1589 }
1588 checknext(ls, TK_IN); 1590 checknext(ls, TK_IN);
@@ -1706,7 +1708,7 @@ static void localfunc (LexState *ls) {
1706 expdesc b; 1708 expdesc b;
1707 FuncState *fs = ls->fs; 1709 FuncState *fs = ls->fs;
1708 int fvar = fs->nactvar; /* function's variable index */ 1710 int fvar = fs->nactvar; /* function's variable index */
1709 new_localvar(ls, str_checkname(ls)); /* new local variable */ 1711 new_localvar(ls, str_checkname(ls), VDKREG); /* new local variable */
1710 adjustlocalvars(ls, 1); /* enter its scope */ 1712 adjustlocalvars(ls, 1); /* enter its scope */
1711 body(ls, &b, 0, ls->linenumber); /* function created in next register */ 1713 body(ls, &b, 0, ls->linenumber); /* function created in next register */
1712 /* debug information will only see the variable after this point! */ 1714 /* debug information will only see the variable after this point! */
@@ -1746,13 +1748,13 @@ static void localstat (LexState *ls) {
1746 FuncState *fs = ls->fs; 1748 FuncState *fs = ls->fs;
1747 int toclose = -1; /* index of to-be-closed variable (if any) */ 1749 int toclose = -1; /* index of to-be-closed variable (if any) */
1748 Vardesc *var; /* last variable */ 1750 Vardesc *var; /* last variable */
1751 int ivar; /* index of last variable */
1749 int nvars = 0; 1752 int nvars = 0;
1750 int nexps; 1753 int nexps;
1751 expdesc e; 1754 expdesc e;
1752 do { 1755 do {
1753 int kind = getlocalattribute(ls); 1756 int kind = getlocalattribute(ls);
1754 var = new_localvar(ls, str_checkname(ls)); 1757 ivar = new_localvar(ls, str_checkname(ls), kind);
1755 var->vd.kind = kind;
1756 if (kind == RDKTOCLOSE) { /* to-be-closed? */ 1758 if (kind == RDKTOCLOSE) { /* to-be-closed? */
1757 if (toclose != -1) /* one already present? */ 1759 if (toclose != -1) /* one already present? */
1758 luaK_semerror(ls, "multiple to-be-closed variables in local list"); 1760 luaK_semerror(ls, "multiple to-be-closed variables in local list");
@@ -1766,6 +1768,7 @@ static void localstat (LexState *ls) {
1766 e.k = VVOID; 1768 e.k = VVOID;
1767 nexps = 0; 1769 nexps = 0;
1768 } 1770 }
1771 var = getlocalvardesc(fs, ivar); /* get last variable */
1769 if (nvars == nexps && /* no adjustments? */ 1772 if (nvars == nexps && /* no adjustments? */
1770 var->vd.kind == RDKCONST && /* last variable is const? */ 1773 var->vd.kind == RDKCONST && /* last variable is const? */
1771 luaK_exp2const(fs, &e, &var->k)) { /* compile-time constant? */ 1774 luaK_exp2const(fs, &e, &var->k)) { /* compile-time constant? */