From e71a2dd64aa09a478eb3300c82a4c6d18cd3c929 Mon Sep 17 00:00:00 2001 From: TerryE Date: Thu, 3 Dec 2015 19:16:30 +0000 Subject: [PATCH] Fix ECG case in concat where stack top not recalculated --- app/lua/lvm.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/app/lua/lvm.c b/app/lua/lvm.c index f475e3e9..965f4a3c 100644 --- a/app/lua/lvm.c +++ b/app/lua/lvm.c @@ -319,22 +319,25 @@ void luaV_concat (lua_State *L, int total, int last) { lu_mem max_sizet = MAX_SIZET; if (G(L)->memlimit < max_sizet) max_sizet = G(L)->memlimit; do { + /* Any call which does a memory allocation may trim the stack, + invalidating top unless the stack is fixed duri ng the allocation */ StkId top = L->base + last + 1; + fixedstack(L); int n = 2; /* number of elements handled in this pass (at least 2) */ if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) { + unfixedstack(L); if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) { /* restore 'top' pointer, since stack might have been reallocted */ top = L->base + last + 1; luaG_concaterror(L, top-2, top-1); } - } else if (tsvalue(top-1)->len == 0) /* second op is empty? */ + } else if (tsvalue(top-1)->len == 0) { /* second op is empty? */ (void)tostring(L, top - 2); /* result is first op (as string) */ - else { + } else { /* at least two string values; get as many as possible */ size_t tl = tsvalue(top-1)->len; char *buffer; int i; - fixedstack(L); /* collect total length */ for (n = 1; n < total && tostring(L, top-n-1); n++) { size_t l = tsvalue(top-n-1)->len; @@ -351,10 +354,10 @@ void luaV_concat (lua_State *L, int total, int last) { } setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl)); luaZ_resetbuffer(&G(L)->buff); - unfixedstack(L); } total -= n-1; /* got `n' strings to create 1 new */ last -= n-1; + unfixedstack(L); } while (total > 1); /* repeat until only 1 result left */ }