diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2025-03-14 15:16:09 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2025-03-14 15:16:09 -0300 |
| commit | 94d38560c3095190fa2c868cbf7bcf39ca444568 (patch) | |
| tree | b68480036d7d92dc38f68953e53757f52fdc06a8 | |
| parent | c2dc6e8e947ed0c7b18d452592f722f56ee1f96a (diff) | |
| download | lua-94d38560c3095190fa2c868cbf7bcf39ca444568.tar.gz lua-94d38560c3095190fa2c868cbf7bcf39ca444568.tar.bz2 lua-94d38560c3095190fa2c868cbf7bcf39ca444568.zip | |
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.
| -rw-r--r-- | ldebug.c | 17 | ||||
| -rw-r--r-- | ltests.c | 2 | ||||
| -rw-r--r-- | testes/errors.lua | 3 |
3 files changed, 16 insertions, 6 deletions
| @@ -33,6 +33,8 @@ | |||
| 33 | 33 | ||
| 34 | #define LuaClosure(f) ((f) != NULL && (f)->c.tt == LUA_VLCL) | 34 | #define LuaClosure(f) ((f) != NULL && (f)->c.tt == LUA_VLCL) |
| 35 | 35 | ||
| 36 | static const char strlocal[] = "local"; | ||
| 37 | static const char strupval[] = "upvalue"; | ||
| 36 | 38 | ||
| 37 | static const char *funcnamefromcall (lua_State *L, CallInfo *ci, | 39 | static const char *funcnamefromcall (lua_State *L, CallInfo *ci, |
| 38 | const char **name); | 40 | const char **name); |
| @@ -505,7 +507,7 @@ static const char *basicgetobjname (const Proto *p, int *ppc, int reg, | |||
| 505 | int pc = *ppc; | 507 | int pc = *ppc; |
| 506 | *name = luaF_getlocalname(p, reg + 1, pc); | 508 | *name = luaF_getlocalname(p, reg + 1, pc); |
| 507 | if (*name) /* is a local? */ | 509 | if (*name) /* is a local? */ |
| 508 | return "local"; | 510 | return strlocal; |
| 509 | /* else try symbolic execution */ | 511 | /* else try symbolic execution */ |
| 510 | *ppc = pc = findsetreg(p, pc, reg); | 512 | *ppc = pc = findsetreg(p, pc, reg); |
| 511 | if (pc != -1) { /* could find instruction? */ | 513 | if (pc != -1) { /* could find instruction? */ |
| @@ -520,7 +522,7 @@ static const char *basicgetobjname (const Proto *p, int *ppc, int reg, | |||
| 520 | } | 522 | } |
| 521 | case OP_GETUPVAL: { | 523 | case OP_GETUPVAL: { |
| 522 | *name = upvalname(p, GETARG_B(i)); | 524 | *name = upvalname(p, GETARG_B(i)); |
| 523 | return "upvalue"; | 525 | return strupval; |
| 524 | } | 526 | } |
| 525 | case OP_LOADK: return kname(p, GETARG_Bx(i), name); | 527 | case OP_LOADK: return kname(p, GETARG_Bx(i), name); |
| 526 | case OP_LOADKX: return kname(p, GETARG_Ax(p->code[pc + 1]), name); | 528 | 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) { | |||
| 550 | const char *name; /* name of indexed variable */ | 552 | const char *name; /* name of indexed variable */ |
| 551 | if (isup) /* is 't' an upvalue? */ | 553 | if (isup) /* is 't' an upvalue? */ |
| 552 | name = upvalname(p, t); | 554 | name = upvalname(p, t); |
| 553 | else /* 't' is a register */ | 555 | else { /* 't' is a register */ |
| 554 | basicgetobjname(p, &pc, t, &name); | 556 | const char *what = basicgetobjname(p, &pc, t, &name); |
| 557 | /* 'name' must be the name of a local variable (at the current | ||
| 558 | level or an upvalue) */ | ||
| 559 | if (what != strlocal && what != strupval) | ||
| 560 | name = NULL; /* cannot be the variable _ENV */ | ||
| 561 | } | ||
| 555 | return (name && strcmp(name, LUA_ENV) == 0) ? "global" : "field"; | 562 | return (name && strcmp(name, LUA_ENV) == 0) ? "global" : "field"; |
| 556 | } | 563 | } |
| 557 | 564 | ||
| @@ -698,7 +705,7 @@ static const char *getupvalname (CallInfo *ci, const TValue *o, | |||
| 698 | for (i = 0; i < c->nupvalues; i++) { | 705 | for (i = 0; i < c->nupvalues; i++) { |
| 699 | if (c->upvals[i]->v.p == o) { | 706 | if (c->upvals[i]->v.p == o) { |
| 700 | *name = upvalname(c->p, i); | 707 | *name = upvalname(c->p, i); |
| 701 | return "upvalue"; | 708 | return strupval; |
| 702 | } | 709 | } |
| 703 | } | 710 | } |
| 704 | return NULL; | 711 | return NULL; |
| @@ -982,7 +982,7 @@ static int gc_printobj (lua_State *L) { | |||
| 982 | } | 982 | } |
| 983 | 983 | ||
| 984 | 984 | ||
| 985 | static const char *statenames[] = { | 985 | static const char *const statenames[] = { |
| 986 | "propagate", "enteratomic", "atomic", "sweepallgc", "sweepfinobj", | 986 | "propagate", "enteratomic", "atomic", "sweepallgc", "sweepfinobj", |
| 987 | "sweeptobefnz", "sweepend", "callfin", "pause", ""}; | 987 | "sweeptobefnz", "sweepend", "callfin", "pause", ""}; |
| 988 | 988 | ||
diff --git a/testes/errors.lua b/testes/errors.lua index d83e6023..c1c40fec 100644 --- a/testes/errors.lua +++ b/testes/errors.lua | |||
| @@ -162,6 +162,9 @@ checkmessage("aaa=(1)..{}", "a table value") | |||
| 162 | -- bug in 5.4.6 | 162 | -- bug in 5.4.6 |
| 163 | checkmessage("a = {_ENV = {}}; print(a._ENV.x + 1)", "field 'x'") | 163 | checkmessage("a = {_ENV = {}}; print(a._ENV.x + 1)", "field 'x'") |
| 164 | 164 | ||
| 165 | -- a similar bug, since 5.4.0 | ||
| 166 | checkmessage("print(('_ENV').x + 1)", "field 'x'") | ||
| 167 | |||
| 165 | _G.aaa, _G.bbbb = nil | 168 | _G.aaa, _G.bbbb = nil |
| 166 | 169 | ||
| 167 | -- calls | 170 | -- calls |
