Unverified Commit 10e37839 authored by Yiheng Cao's avatar Yiheng Cao Committed by GitHub
Browse files

Fix potential integer overflow in getnum and fix the negation overflow in lua (#3634)

parent 6798f027
...@@ -132,10 +132,11 @@ static const char *upvalname (Proto *p, int uv) { ...@@ -132,10 +132,11 @@ static const char *upvalname (Proto *p, int uv) {
static const char *findvararg (CallInfo *ci, int n, StkId *pos) { static const char *findvararg (CallInfo *ci, int n, StkId *pos) {
int nparams = getnumparams(clLvalue(ci->func)->p); int nparams = getnumparams(clLvalue(ci->func)->p);
if (n >= cast_int(ci->u.l.base - ci->func) - nparams) int nvararg = cast_int(ci->u.l.base - ci->func) - nparams;
if (n <= -nvararg)
return NULL; /* no such vararg */ return NULL; /* no such vararg */
else { else {
*pos = ci->func + nparams + n; *pos = ci->func + nparams - n;
return "(*vararg)"; /* generic name for any vararg */ return "(*vararg)"; /* generic name for any vararg */
} }
} }
...@@ -147,7 +148,7 @@ static const char *findlocal (lua_State *L, CallInfo *ci, int n, ...@@ -147,7 +148,7 @@ static const char *findlocal (lua_State *L, CallInfo *ci, int n,
StkId base; StkId base;
if (isLua(ci)) { if (isLua(ci)) {
if (n < 0) /* access to vararg values? */ if (n < 0) /* access to vararg values? */
return findvararg(ci, -n, pos); return findvararg(ci, n, pos);
else { else {
base = ci->u.l.base; base = ci->u.l.base;
name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci)); name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci));
......
...@@ -93,12 +93,14 @@ typedef struct Header { ...@@ -93,12 +93,14 @@ typedef struct Header {
} Header; } Header;
static int getnum (const char **fmt, int df) { static int getnum (lua_State *L, const char **fmt, int df) {
if (!isdigit((unsigned char)**fmt)) /* no number? */ if (!isdigit((unsigned char)**fmt)) /* no number? */
return df; /* return default value */ return df; /* return default value */
else { else {
int a = 0; int a = 0;
do { do {
if (a > (INT_MAX / 10) || a * 10 > (INT_MAX - (**fmt - '0')))
luaL_error(L, "integral size overflow");
a = a*10 + *((*fmt)++) - '0'; a = a*10 + *((*fmt)++) - '0';
} while (isdigit((unsigned char)**fmt)); } while (isdigit((unsigned char)**fmt));
return a; return a;
...@@ -121,9 +123,9 @@ static size_t optsize (lua_State *L, char opt, const char **fmt) { ...@@ -121,9 +123,9 @@ static size_t optsize (lua_State *L, char opt, const char **fmt) {
case 'd': return sizeof(double); case 'd': return sizeof(double);
#endif #endif
case 'x': return 1; case 'x': return 1;
case 'c': return getnum(fmt, 1); case 'c': return getnum(L, fmt, 1);
case 'i': case 'I': { case 'i': case 'I': {
int sz = getnum(fmt, sizeof(int)); int sz = getnum(L, fmt, sizeof(int));
if (sz > MAXINTSIZE) if (sz > MAXINTSIZE)
luaL_error(L, "integral size %d is larger than limit of %d", luaL_error(L, "integral size %d is larger than limit of %d",
sz, MAXINTSIZE); sz, MAXINTSIZE);
...@@ -156,7 +158,7 @@ static void controloptions (lua_State *L, int opt, const char **fmt, ...@@ -156,7 +158,7 @@ static void controloptions (lua_State *L, int opt, const char **fmt,
case '>': h->endian = BIG; return; case '>': h->endian = BIG; return;
case '<': h->endian = LITTLE; return; case '<': h->endian = LITTLE; return;
case '!': { case '!': {
int a = getnum(fmt, MAXALIGN); int a = getnum(L, fmt, MAXALIGN);
if (!isp2(a)) if (!isp2(a))
luaL_error(L, "alignment %d is not a power of 2", a); luaL_error(L, "alignment %d is not a power of 2", a);
h->align = a; h->align = a;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment