From d1ee2a4deb06a335b9ff99530917b828a7ebe3e5 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Thu, 15 May 2025 15:14:56 -0300 Subject: Bug: Bad error message with fields of string _ENV Errors with fields of the string _ENV (e.g., ("_ENV").u + 1) report the error as comming from a global. --- ldebug.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'ldebug.c') diff --git a/ldebug.c b/ldebug.c index 591b3528..7264fce8 100644 --- a/ldebug.c +++ b/ldebug.c @@ -37,6 +37,9 @@ static const char *funcnamefromcall (lua_State *L, CallInfo *ci, const char **name); +static const char strlocal[] = "local"; +static const char strupval[] = "upvalue"; + static int currentpc (CallInfo *ci) { lua_assert(isLua(ci)); @@ -497,7 +500,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? */ @@ -512,7 +515,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); @@ -547,15 +550,21 @@ static void rkname (const Proto *p, int pc, Instruction i, const char **name) { /* ** Check whether table being indexed by instruction 'i' is the -** environment '_ENV' +** environment '_ENV'. If the table is an upvalue, get its name; +** otherwise, find some "name" for the table and check whether +** that name is the name of a local variable (and not, for instance, +** a string). Then check that, if there is a name, it is '_ENV'. */ static const char *isEnv (const Proto *p, int pc, Instruction i, int isup) { int t = GETARG_B(i); /* table index */ 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); + if (what != strlocal && what != strupval) + name = NULL; /* cannot be the variable _ENV */ + } return (name && strcmp(name, LUA_ENV) == 0) ? "global" : "field"; } @@ -701,7 +710,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; -- cgit v1.2.3-55-g6feb