diff --git a/lib/lua/README.md b/lib/lua/README.md new file mode 100644 index 000000000..b82e4a652 --- /dev/null +++ b/lib/lua/README.md @@ -0,0 +1,6 @@ +## Lua 5.1.5 source + +This copy has been patched with Minetest-specific changes (`lua_atccall`) +so it is *not* interchangeable with upstream PUC Lua. + +A patch for CVE-2014-5461 has been applied. diff --git a/lib/lua/src/lbaselib.c b/lib/lua/src/lbaselib.c index 2ab550bd4..ed293ebdc 100644 --- a/lib/lua/src/lbaselib.c +++ b/lib/lua/src/lbaselib.c @@ -340,13 +340,14 @@ static int luaB_assert (lua_State *L) { static int luaB_unpack (lua_State *L) { - int i, e, n; + int i, e; + unsigned int n; luaL_checktype(L, 1, LUA_TTABLE); i = luaL_optint(L, 2, 1); e = luaL_opt(L, luaL_checkint, 3, luaL_getn(L, 1)); if (i > e) return 0; /* empty range */ - n = e - i + 1; /* number of elements */ - if (n <= 0 || !lua_checkstack(L, n)) /* n <= 0 means arith. overflow */ + n = (unsigned int)e - (unsigned int)i; /* number of elements minus 1 */ + if (n > (INT_MAX - 10) || !lua_checkstack(L, ++n)) return luaL_error(L, "too many results to unpack"); lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */ while (i++ < e) /* push arg[i + 1...e] */ diff --git a/lib/lua/src/ldblib.c b/lib/lua/src/ldblib.c index 628a6c458..2c55edcda 100644 --- a/lib/lua/src/ldblib.c +++ b/lib/lua/src/ldblib.c @@ -101,6 +101,7 @@ static int db_getinfo (lua_State *L) { int arg; lua_State *L1 = getthread(L, &arg); const char *options = luaL_optstring(L, arg+2, "flnSu"); + luaL_argcheck(L, options[0] != '>', arg + 2, "invalid option '>'"); if (lua_isnumber(L, arg+1)) { if (!lua_getstack(L1, (int)lua_tointeger(L, arg+1), &ar)) { lua_pushnil(L); /* level out of range */ diff --git a/lib/lua/src/ldo.c b/lib/lua/src/ldo.c index 7eeea636c..37a7660fd 100644 --- a/lib/lua/src/ldo.c +++ b/lib/lua/src/ldo.c @@ -274,7 +274,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { CallInfo *ci; StkId st, base; Proto *p = cl->p; - luaD_checkstack(L, p->maxstacksize); + luaD_checkstack(L, p->maxstacksize + p->numparams); func = restorestack(L, funcr); if (!p->is_vararg) { /* no varargs? */ base = func + 1; diff --git a/lib/lua/src/llex.c b/lib/lua/src/llex.c index d1b179670..5affe7c16 100644 --- a/lib/lua/src/llex.c +++ b/lib/lua/src/llex.c @@ -133,7 +133,7 @@ static void inclinenumber (LexState *ls) { if (currIsNewline(ls) && ls->current != old) next(ls); /* skip `\n\r' or `\r\n' */ if (++ls->linenumber >= MAX_INT) - luaX_syntaxerror(ls, "chunk has too many lines"); + luaX_lexerror(ls, "chunk has too many lines", 0); } diff --git a/lib/lua/src/lvm.c b/lib/lua/src/lvm.c index a438d7805..60a715a6d 100644 --- a/lib/lua/src/lvm.c +++ b/lib/lua/src/lvm.c @@ -209,14 +209,15 @@ static int l_strcmp (const TString *ls, const TString *rs) { int temp = strcoll(l, r); if (temp != 0) return temp; else { /* strings are equal up to a `\0' */ - size_t len = strlen(l); /* index of first `\0' in both strings */ - if (len == lr) /* r is finished? */ - return (len == ll) ? 0 : 1; - else if (len == ll) /* l is finished? */ - return -1; /* l is smaller than r (because r is not finished) */ - /* both strings longer than `len'; go on comparing (after the `\0') */ - len++; - l += len; ll -= len; r += len; lr -= len; + size_t zl1 = strlen(l); /* index of first '\0' in 'l' */ + size_t zl2 = strlen(r); /* index of first '\0' in 'r' */ + if (zl2 == lr) /* 'r' is finished? */ + return (zl1 == ll) ? 0 : 1; /* check 'l' */ + else if (zl1 == ll) /* 'l' is finished? */ + return -1; /* 'l' is less than 'r' ('r' is not finished) */ + /* both strings longer than 'zl'; go on comparing after the '\0' */ + zl1++; zl2++; + l += zl1; ll -= zl1; r += zl2; lr -= zl2; } } }