Browse Source

BUG: too many variables in an assignment may cause a C stack overflow

Roberto Ierusalimschy 18 years ago
parent
commit
f6a81dbe97
2 changed files with 33 additions and 3 deletions
  1. 28 0
      bugs
  2. 5 3
      lparser.c

+ 28 - 0
bugs

@@ -1382,6 +1382,11 @@ patch = [[remove the '#include "lobject.h" and use
 'lua_pushfstring' instead of 'luaO_pushfstring']],
 }
 
+
+
+-----------------------------------------------------------------
+-- Lua 5.1.2
+
 Bug{
 what = [[Lua may close standard files,
 which then may be used by C]],
@@ -1492,6 +1497,29 @@ ltable.c:
 ]],
 }
 
+Bug{
+what = [[Too many variables in an assignment may cause a
+C stack overflow]],
+report = [[Mike Pall, on 07/2007]],
+since = [[5.0]],
+example = [[
+$ ulimit -s 1024       # Reduce C stack to 1MB for quicker results
+$ lua -e 'local s = "a,"; for i=1,18 do s = s..s end print(loadstring("local a "..s.."a=nil", ""))'
+]],
+patch = [[
+lparser.c:
+@@ -938,6 +938,8 @@
+     primaryexp(ls, &nv.v);
+     if (nv.v.k == VLOCAL)
+       check_conflict(ls, lh, &nv.v);
++    luaY_checklimit(ls->fs, nvars, LUAI_MAXCCALLS - ls->L->nCcalls,
++                    "variable names");
+     assignment(ls, &nv, nvars+1);
+   }
+   else {  /* assignment -> `=' explist1 */
+]],
+}
+
 Bug{
 what = [[ ]],
 report = [[ , on ]],

+ 5 - 3
lparser.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lparser.c,v 2.52 2007/03/27 14:11:38 roberto Exp roberto $
+** $Id: lparser.c,v 2.53 2007/05/11 17:28:56 roberto Exp roberto $
 ** Lua Parser
 ** See Copyright Notice in lua.h
 */
@@ -73,8 +73,8 @@ static void errorlimit (FuncState *fs, int limit, const char *what) {
   const char *where = (fs->f->linedefined == 0) ?
              "main function" :
              luaO_pushfstring(fs->L, "function at line %d", fs->f->linedefined);
-  msg = luaO_pushfstring(fs->L, "too many %s in %s (limit is %d)",
-                                what, where, limit);
+  msg = luaO_pushfstring(fs->L, "too many %s (limit is %d) in %s",
+                                what, limit, where);
   luaX_lexerror(fs->ls, msg, fs->ls->t.token);
 }
 
@@ -946,6 +946,8 @@ static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
     primaryexp(ls, &nv.v);
     if (nv.v.k == VLOCAL)
       check_conflict(ls, lh, &nv.v);
+    luaY_checklimit(ls->fs, nvars, LUAI_MAXCCALLS - G(ls->L)->nCcalls,
+                    "variable names");
     assignment(ls, &nv, nvars+1);
   }
   else {  /* assignment -> `=' explist1 */