From 96f39b3280eeecb91b8c88116ed1100d630b4f3c6627347b24792024e60f0b71 Mon Sep 17 00:00:00 2001 From: Callum Farmer Date: Sat, 4 Jun 2022 13:52:56 +0000 Subject: [PATCH] Accepting request 980768 from home:gmbr3:Active - Added more numbered patches from upstream: * luabugs3.patch * luabugs4.patch * luabugs5.patch OBS-URL: https://build.opensuse.org/request/show/980768 OBS-URL: https://build.opensuse.org/package/show/devel:languages:lua/lua54?expand=0&rev=54 --- lua54.changes | 8 +++ lua54.spec | 3 ++ luabugs3.patch | 123 +++++++++++++++++++++++++++++++++++++++++++ luabugs4.patch | 59 +++++++++++++++++++++ luabugs5.patch | 140 +++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 333 insertions(+) create mode 100644 luabugs3.patch create mode 100644 luabugs4.patch create mode 100644 luabugs5.patch diff --git a/lua54.changes b/lua54.changes index fcd476d..9398a1a 100644 --- a/lua54.changes +++ b/lua54.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Sat Jun 4 13:49:42 UTC 2022 - Callum Farmer + +- Added more numbered patches from upstream: + * luabugs3.patch + * luabugs4.patch + * luabugs5.patch + ------------------------------------------------------------------- Wed Mar 9 10:12:55 UTC 2022 - Callum Farmer diff --git a/lua54.spec b/lua54.spec index 58b0b22..a289f22 100644 --- a/lua54.spec +++ b/lua54.spec @@ -46,6 +46,9 @@ Patch6: shared_link.patch # PATCH-FIX-UPSTREAM luabugsX.patch https://www.lua.org/bugs.html#5.4.4-X Patch7: luabugs1.patch Patch8: luabugs2.patch +Patch9: luabugs3.patch +Patch10: luabugs4.patch +Patch11: luabugs5.patch # %if "%{flavor}" == "test" BuildRequires: lua54 diff --git a/luabugs3.patch b/luabugs3.patch new file mode 100644 index 0000000..7a72db4 --- /dev/null +++ b/luabugs3.patch @@ -0,0 +1,123 @@ +From c764ca71a639f5585b5f466bea25dc42b855a4b0 Mon Sep 17 00:00:00 2001 +From: Roberto Ierusalimschy +Date: Mon, 25 Apr 2022 14:42:51 -0300 +Subject: [PATCH] Bug: Wrong code generation in bitwise operations + +--- + lcode.c | 16 ++++++++++------ + ltests.h | 7 +++++++ + testes/constructs.lua | 25 +++++++++++++++++++++++++ + 3 files changed, 42 insertions(+), 6 deletions(-) + +diff --git a/lcode.c b/lcode.c +index 06425a1db..cb724a090 100644 +--- a/src/lcode.c ++++ b/src/lcode.c +@@ -1391,7 +1391,10 @@ static void finishbinexpval (FuncState *fs, expdesc *e1, expdesc *e2, + */ + static void codebinexpval (FuncState *fs, OpCode op, + expdesc *e1, expdesc *e2, int line) { +- int v2 = luaK_exp2anyreg(fs, e2); /* both operands are in registers */ ++ int v2 = luaK_exp2anyreg(fs, e2); /* make sure 'e2' is in a register */ ++ /* 'e1' must be already in a register or it is a constant */ ++ lua_assert((VNIL <= e1->k && e1->k <= VKSTR) || ++ e1->k == VNONRELOC || e1->k == VRELOC); + lua_assert(OP_ADD <= op && op <= OP_SHR); + finishbinexpval(fs, e1, e2, op, v2, 0, line, OP_MMBIN, + cast(TMS, (op - OP_ADD) + TM_ADD)); +@@ -1478,7 +1481,7 @@ static void codecommutative (FuncState *fs, BinOpr op, + + + /* +-** Code bitwise operations; they are all associative, so the function ++** Code bitwise operations; they are all commutative, so the function + ** tries to put an integer constant as the 2nd operand (a K operand). + */ + static void codebitwise (FuncState *fs, BinOpr opr, +@@ -1486,11 +1489,11 @@ static void codebitwise (FuncState *fs, BinOpr opr, + int flip = 0; + int v2; + OpCode op; +- if (e1->k == VKINT && luaK_exp2RK(fs, e1)) { ++ if (e1->k == VKINT && luaK_exp2K(fs, e1)) { + swapexps(e1, e2); /* 'e2' will be the constant operand */ + flip = 1; + } +- else if (!(e2->k == VKINT && luaK_exp2RK(fs, e2))) { /* no constants? */ ++ else if (!(e2->k == VKINT && luaK_exp2K(fs, e2))) { /* no constants? */ + op = cast(OpCode, opr + OP_ADD); + codebinexpval(fs, op, e1, e2, line); /* all-register opcodes */ + return; +@@ -1551,7 +1554,7 @@ static void codeeq (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) { + op = OP_EQI; + r2 = im; /* immediate operand */ + } +- else if (luaK_exp2RK(fs, e2)) { /* 1st expression is constant? */ ++ else if (luaK_exp2RK(fs, e2)) { /* 2nd expression is constant? */ + op = OP_EQK; + r2 = e2->u.info; /* constant index */ + } +@@ -1611,7 +1614,8 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { + case OPR_SHL: case OPR_SHR: { + if (!tonumeral(v, NULL)) + luaK_exp2anyreg(fs, v); +- /* else keep numeral, which may be folded with 2nd operand */ ++ /* else keep numeral, which may be folded or used as an immediate ++ operand */ + break; + } + case OPR_EQ: case OPR_NE: { +diff --git a/ltests.h b/ltests.h +index cb3a0b480..ec520498b 100644 +--- a/testes/ltests/ltests.h ++++ b/testes/ltests/ltests.h +@@ -125,6 +125,13 @@ LUA_API void *debug_realloc (void *ud, void *block, + #define LUAI_USER_ALIGNMENT_T union { char b[sizeof(void*) * 8]; } + + ++/* ++** This one is not compatible with tests for opcode optimizations, ++** as it blocks some optimizations ++#define MAXINDEXRK 0 ++*/ ++ ++ + /* make stack-overflow tests run faster */ + #undef LUAI_MAXSTACK + #define LUAI_MAXSTACK 50000 +diff --git a/testes/constructs.lua b/testes/constructs.lua +index a74a8c041..0d9ec92d7 100644 +--- a/testes/constructs.lua ++++ b/testes/constructs.lua +@@ -103,6 +103,31 @@ do -- test old bug (first name could not be an `upvalue') + local a; function f(x) x={a=1}; x={x=1}; x={G=1} end + end + ++ ++do -- bug since 5.4.0 ++ -- create code with a table using more than 256 constants ++ local code = {"local x = {"} ++ for i = 1, 257 do ++ code[#code + 1] = i .. ".1," ++ end ++ code[#code + 1] = "};" ++ code = table.concat(code) ++ ++ -- add "ret" to the end of that code and checks that ++ -- it produces the expected value "val" ++ local function check (ret, val) ++ local code = code .. ret ++ code = load(code) ++ assert(code() == val) ++ end ++ ++ check("return (1 ~ (2 or 3))", 1 ~ 2) ++ check("return (1 | (2 or 3))", 1 | 2) ++ check("return (1 + (2 or 3))", 1 + 2) ++ check("return (1 << (2 or 3))", 1 << 2) ++end ++ ++ + function f (i) + if type(i) ~= 'number' then return i,'jojo'; end; + if i > 0 then return i, f(i-1); end; diff --git a/luabugs4.patch b/luabugs4.patch new file mode 100644 index 0000000..68f0053 --- /dev/null +++ b/luabugs4.patch @@ -0,0 +1,59 @@ +From 42d40581dd919fb134c07027ca1ce0844c670daf Mon Sep 17 00:00:00 2001 +From: Roberto Ierusalimschy +Date: Fri, 20 May 2022 13:14:33 -0300 +Subject: [PATCH] Save stack space while handling errors + +Because error handling (luaG_errormsg) uses slots from EXTRA_STACK, +and some errors can recur (e.g., string overflow while creating an +error message in 'luaG_runerror', or a C-stack overflow before calling +the message handler), the code should use stack slots with parsimony. + +This commit fixes the bug "Lua-stack overflow when C stack overflows +while handling an error". +--- + ldebug.c | 5 ++++- + lvm.c | 6 ++++-- + 2 files changed, 8 insertions(+), 3 deletions(-) + +diff --git a/ldebug.c b/ldebug.c +index a716d95e2..fa15eaf68 100644 +--- a/src/ldebug.c ++++ b/src/ldebug.c +@@ -824,8 +824,11 @@ l_noret luaG_runerror (lua_State *L, const char *fmt, ...) { + va_start(argp, fmt); + msg = luaO_pushvfstring(L, fmt, argp); /* format message */ + va_end(argp); +- if (isLua(ci)) /* if Lua function, add source:line information */ ++ if (isLua(ci)) { /* if Lua function, add source:line information */ + luaG_addinfo(L, msg, ci_func(ci)->p->source, getcurrentline(ci)); ++ setobjs2s(L, L->top - 2, L->top - 1); /* remove 'msg' from the stack */ ++ L->top--; ++ } + luaG_errormsg(L); + } + +diff --git a/lvm.c b/lvm.c +index e8c2e9627..cd992aada 100644 +--- a/src/lvm.c ++++ b/src/lvm.c +@@ -656,8 +656,10 @@ void luaV_concat (lua_State *L, int total) { + /* collect total length and number of strings */ + for (n = 1; n < total && tostring(L, s2v(top - n - 1)); n++) { + size_t l = vslen(s2v(top - n - 1)); +- if (l_unlikely(l >= (MAX_SIZE/sizeof(char)) - tl)) ++ if (l_unlikely(l >= (MAX_SIZE/sizeof(char)) - tl)) { ++ L->top = top - total; /* pop strings to avoid wasting stack */ + luaG_runerror(L, "string length overflow"); ++ } + tl += l; + } + if (tl <= LUAI_MAXSHORTLEN) { /* is result a short string? */ +@@ -672,7 +674,7 @@ void luaV_concat (lua_State *L, int total) { + setsvalue2s(L, top - n, ts); /* create result */ + } + total -= n-1; /* got 'n' strings to create 1 new */ +- L->top -= n-1; /* popped 'n' strings and pushed one */ ++ L->top = top - (n - 1); /* popped 'n' strings and pushed one */ + } while (total > 1); /* repeat until only 1 result left */ + } + diff --git a/luabugs5.patch b/luabugs5.patch new file mode 100644 index 0000000..3bf9ca0 --- /dev/null +++ b/luabugs5.patch @@ -0,0 +1,140 @@ +From 196bb94d66e727e0aec053a0276c3ad701500762 Mon Sep 17 00:00:00 2001 +From: Roberto Ierusalimschy +Date: Wed, 25 May 2022 17:41:39 -0300 +Subject: [PATCH] Bug: 'lua_settop' may use an invalid pointer to stack + +--- + lapi.c | 5 ++--- + ldo.c | 12 ++++++------ + lfunc.c | 5 +++-- + lfunc.h | 2 +- + testes/locals.lua | 22 ++++++++++++++++++++++ + 5 files changed, 34 insertions(+), 12 deletions(-) + +diff --git a/lapi.c b/lapi.c +index 352a385a3..5833c7b0a 100644 +--- a/src/lapi.c ++++ b/src/lapi.c +@@ -197,7 +197,7 @@ LUA_API void lua_settop (lua_State *L, int idx) { + newtop = L->top + diff; + if (diff < 0 && L->tbclist >= newtop) { + lua_assert(hastocloseCfunc(ci->nresults)); +- luaF_close(L, newtop, CLOSEKTOP, 0); ++ newtop = luaF_close(L, newtop, CLOSEKTOP, 0); + } + L->top = newtop; /* correct top only after closing any upvalue */ + lua_unlock(L); +@@ -210,8 +210,7 @@ LUA_API void lua_closeslot (lua_State *L, int idx) { + level = index2stack(L, idx); + api_check(L, hastocloseCfunc(L->ci->nresults) && L->tbclist == level, + "no variable to close at given level"); +- luaF_close(L, level, CLOSEKTOP, 0); +- level = index2stack(L, idx); /* stack may be moved */ ++ level = luaF_close(L, level, CLOSEKTOP, 0); + setnilvalue(s2v(level)); + lua_unlock(L); + } +diff --git a/ldo.c b/ldo.c +index 5aa6d59d4..13498905f 100644 +--- a/src/ldo.c ++++ b/src/ldo.c +@@ -430,14 +430,15 @@ l_sinline void moveresults (lua_State *L, StkId res, int nres, int wanted) { + break; + default: /* two/more results and/or to-be-closed variables */ + if (hastocloseCfunc(wanted)) { /* to-be-closed variables? */ +- ptrdiff_t savedres = savestack(L, res); + L->ci->callstatus |= CIST_CLSRET; /* in case of yields */ + L->ci->u2.nres = nres; +- luaF_close(L, res, CLOSEKTOP, 1); ++ res = luaF_close(L, res, CLOSEKTOP, 1); + L->ci->callstatus &= ~CIST_CLSRET; +- if (L->hookmask) /* if needed, call hook after '__close's */ ++ if (L->hookmask) { /* if needed, call hook after '__close's */ ++ ptrdiff_t savedres = savestack(L, res); + rethook(L, L->ci, nres); +- res = restorestack(L, savedres); /* close and hook can move stack */ ++ res = restorestack(L, savedres); /* hook can move stack */ ++ } + wanted = decodeNresults(wanted); + if (wanted == LUA_MULTRET) + wanted = nres; /* we want all results */ +@@ -654,8 +655,7 @@ static int finishpcallk (lua_State *L, CallInfo *ci) { + else { /* error */ + StkId func = restorestack(L, ci->u2.funcidx); + L->allowhook = getoah(ci->callstatus); /* restore 'allowhook' */ +- luaF_close(L, func, status, 1); /* can yield or raise an error */ +- func = restorestack(L, ci->u2.funcidx); /* stack may be moved */ ++ func = luaF_close(L, func, status, 1); /* can yield or raise an error */ + luaD_seterrorobj(L, status, func); + luaD_shrinkstack(L); /* restore stack size in case of overflow */ + setcistrecst(ci, LUA_OK); /* clear original status */ +diff --git a/lfunc.c b/lfunc.c +index f5889a21d..3ed65de2b 100644 +--- a/src/lfunc.c ++++ b/src/lfunc.c +@@ -223,9 +223,9 @@ static void poptbclist (lua_State *L) { + + /* + ** Close all upvalues and to-be-closed variables up to the given stack +-** level. ++** level. Return restored 'level'. + */ +-void luaF_close (lua_State *L, StkId level, int status, int yy) { ++StkId luaF_close (lua_State *L, StkId level, int status, int yy) { + ptrdiff_t levelrel = savestack(L, level); + luaF_closeupval(L, level); /* first, close the upvalues */ + while (L->tbclist >= level) { /* traverse tbc's down to that level */ +@@ -234,6 +234,7 @@ void luaF_close (lua_State *L, StkId level, int status, int yy) { + prepcallclosemth(L, tbc, status, yy); /* close variable */ + level = restorestack(L, levelrel); + } ++ return level; + } + + +diff --git a/lfunc.h b/lfunc.h +index dc1cebccd..3d296971e 100644 +--- a/src/lfunc.h ++++ b/src/lfunc.h +@@ -54,7 +54,7 @@ LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl); + LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); + LUAI_FUNC void luaF_newtbcupval (lua_State *L, StkId level); + LUAI_FUNC void luaF_closeupval (lua_State *L, StkId level); +-LUAI_FUNC void luaF_close (lua_State *L, StkId level, int status, int yy); ++LUAI_FUNC StkId luaF_close (lua_State *L, StkId level, int status, int yy); + LUAI_FUNC void luaF_unlinkupval (UpVal *uv); + LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f); + LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, +diff --git a/testes/locals.lua b/testes/locals.lua +index 62a88df57..ddb75054f 100644 +--- a/testes/locals.lua ++++ b/testes/locals.lua +@@ -592,6 +592,28 @@ end + + if rawget(_G, "T") then + ++ do ++ -- bug in 5.4.3 ++ -- 'lua_settop' may use a pointer to stack invalidated by 'luaF_close' ++ ++ -- reduce stack size ++ collectgarbage(); collectgarbage(); collectgarbage() ++ ++ -- force a stack reallocation ++ local function loop (n) ++ if n < 400 then loop(n + 1) end ++ end ++ ++ -- close metamethod will reallocate the stack ++ local o = setmetatable({}, {__close = function () loop(0) end}) ++ ++ local script = [[toclose 2; settop 1; return 1]] ++ ++ assert(T.testC(script, o) == script) ++ ++ end ++ ++ + -- memory error inside closing function + local function foo () + local y = func2close(function () T.alloccount() end)