From 81a4db53e4d0a242bd7f946ffe9acc0eb5396cb5 Mon Sep 17 00:00:00 2001 From: TerryE Date: Sat, 25 Feb 2017 17:37:06 +0200 Subject: [PATCH] [PATCH] Fix ECG case in concat where stack top not recalculated --- src/lua/lvm.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/lua/lvm.c b/src/lua/lvm.c index 3e65503b..e49bcd0d 100644 --- a/src/lua/lvm.c +++ b/src/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 */ }