Avoid underflows in 'luaF_getlocalname'

A call like 'debug.getlocal(test, -2147483648)' could decrement
-2147483648, causing an underflow. (As this happens in a debug function,
the fix was not strictly necessary, but it has no cost in the generated
code.)
This commit is contained in:
Roberto I
2026-10-12 16:12:40 -03:00
parent 745b96db54
commit 80f3ecc44f
5 changed files with 8 additions and 7 deletions
+3 -3
View File
@@ -202,7 +202,7 @@ const char *luaG_findlocal (lua_State *L, CallInfo *ci, int n, StkId *pos) {
if (n < 0) /* access to vararg values? */
return findvararg(ci, n, pos);
else
name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci));
name = luaF_getlocalname(ci_func(ci)->p, cast_uint(n), currentpc(ci));
}
if (name == NULL) { /* no 'standard' name? */
StkId limit = (ci == L->ci) ? L->top.p : ci->next->func.p;
@@ -226,7 +226,7 @@ LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
if (!isLfunction(s2v(L->top.p - 1))) /* not a Lua function? */
name = NULL;
else /* consider live variables at function start (parameters) */
name = luaF_getlocalname(clLvalue(s2v(L->top.p - 1))->p, n, 0);
name = luaF_getlocalname(clLvalue(s2v(L->top.p - 1))->p, cast_uint(n), 0);
}
else { /* active function; get information through 'ar' */
StkId pos = NULL; /* to avoid warnings */
@@ -505,7 +505,7 @@ static const char *kname (const Proto *p, int index, const char **name) {
static const char *basicgetobjname (const Proto *p, int *ppc, int reg,
const char **name) {
int pc = *ppc;
*name = luaF_getlocalname(p, reg + 1, pc);
*name = luaF_getlocalname(p, cast_uint(reg + 1), pc);
if (*name) /* is a local? */
return strlocal;
/* else try symbolic execution */
+1 -1
View File
@@ -300,7 +300,7 @@ void luaF_freeproto (lua_State *L, Proto *f) {
** Look for n-th local variable at line 'line' in function 'func'.
** Returns NULL if not found.
*/
const char *luaF_getlocalname (const Proto *f, int local_number, int pc) {
const char *luaF_getlocalname (const Proto *f, unsigned local_number, int pc) {
int i;
for (i = 0; i<f->sizelocvars && f->locvars[i].startpc <= pc; i++) {
if (pc < f->locvars[i].endpc) { /* is variable active? */
+2 -2
View File
@@ -58,8 +58,8 @@ LUAI_FUNC StkId luaF_close (lua_State *L, StkId level, TStatus status, int yy);
LUAI_FUNC void luaF_unlinkupval (UpVal *uv);
LUAI_FUNC lu_mem luaF_protosize (Proto *p);
LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f);
LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number,
int pc);
LUAI_FUNC const char *luaF_getlocalname (const Proto *func,
unsigned local_number, int pc);
#endif
+1 -1
View File
@@ -853,7 +853,7 @@ static int listlocals (lua_State *L) {
luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
1, "Lua function expected");
p = getproto(obj_at(L, 1));
while ((name = luaF_getlocalname(p, ++i, pc)) != NULL)
while ((name = luaF_getlocalname(p, cast_uint(++i), pc)) != NULL)
lua_pushstring(L, name);
return i-1;
}
+1
View File
@@ -258,6 +258,7 @@ print'+'
-- invalid levels in [gs]etlocal
assert(not pcall(debug.getlocal, 20, 1))
assert(not pcall(debug.setlocal, -1, 1, 10))
assert(not debug.getlocal(test, -2147483648))
-- parameter names