浏览代码

Wrong error message when using "_ENV" fields

The string "_ENV" is erroneously identified as a variable _ENV,
so that results from a field is classified as a global.
Roberto Ierusalimschy 4 月之前
父节点
当前提交
94d38560c3
共有 3 个文件被更改,包括 16 次插入6 次删除
  1. 12 5
      ldebug.c
  2. 1 1
      ltests.c
  3. 3 0
      testes/errors.lua

+ 12 - 5
ldebug.c

@@ -33,6 +33,8 @@
 
 #define LuaClosure(f)		((f) != NULL && (f)->c.tt == LUA_VLCL)
 
+static const char strlocal[] = "local";
+static const char strupval[] = "upvalue";
 
 static const char *funcnamefromcall (lua_State *L, CallInfo *ci,
                                                    const char **name);
@@ -505,7 +507,7 @@ static const char *basicgetobjname (const Proto *p, int *ppc, int reg,
   int pc = *ppc;
   *name = luaF_getlocalname(p, reg + 1, pc);
   if (*name)  /* is a local? */
-    return "local";
+    return strlocal;
   /* else try symbolic execution */
   *ppc = pc = findsetreg(p, pc, reg);
   if (pc != -1) {  /* could find instruction? */
@@ -520,7 +522,7 @@ static const char *basicgetobjname (const Proto *p, int *ppc, int reg,
       }
       case OP_GETUPVAL: {
         *name = upvalname(p, GETARG_B(i));
-        return "upvalue";
+        return strupval;
       }
       case OP_LOADK: return kname(p, GETARG_Bx(i), name);
       case OP_LOADKX: return kname(p, GETARG_Ax(p->code[pc + 1]), name);
@@ -550,8 +552,13 @@ static const char *isEnv (const Proto *p, int pc, Instruction i, int isup) {
   const char *name;  /* name of indexed variable */
   if (isup)  /* is 't' an upvalue? */
     name = upvalname(p, t);
-  else  /* 't' is a register */
-    basicgetobjname(p, &pc, t, &name);
+  else {  /* 't' is a register */
+    const char *what = basicgetobjname(p, &pc, t, &name);
+    /* 'name' must be the name of a local variable (at the current
+       level or an upvalue) */
+    if (what != strlocal && what != strupval)
+      name = NULL;  /* cannot be the variable _ENV */
+  }
   return (name && strcmp(name, LUA_ENV) == 0) ? "global" : "field";
 }
 
@@ -698,7 +705,7 @@ static const char *getupvalname (CallInfo *ci, const TValue *o,
   for (i = 0; i < c->nupvalues; i++) {
     if (c->upvals[i]->v.p == o) {
       *name = upvalname(c->p, i);
-      return "upvalue";
+      return strupval;
     }
   }
   return NULL;

+ 1 - 1
ltests.c

@@ -982,7 +982,7 @@ static int gc_printobj (lua_State *L) {
 }
 
 
-static const char *statenames[] = {
+static const char *const statenames[] = {
   "propagate", "enteratomic", "atomic", "sweepallgc", "sweepfinobj",
   "sweeptobefnz", "sweepend", "callfin", "pause", ""};
 

+ 3 - 0
testes/errors.lua

@@ -162,6 +162,9 @@ checkmessage("aaa=(1)..{}", "a table value")
 -- bug in 5.4.6
 checkmessage("a = {_ENV = {}}; print(a._ENV.x + 1)", "field 'x'")
 
+-- a similar bug, since 5.4.0
+checkmessage("print(('_ENV').x + 1)", "field 'x'")
+
 _G.aaa, _G.bbbb = nil
 
 -- calls