mirror of
https://github.com/lua/lua.git
synced 2026-10-26 10:35:26 +00:00
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:
@@ -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 */
|
||||
|
||||
@@ -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? */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user