Fix ECG case in concat where stack top not recalculated

This commit is contained in:
TerryE 2015-12-03 19:16:30 +00:00
parent f951077544
commit e71a2dd64a

View File

@ -319,22 +319,25 @@ void luaV_concat (lua_State *L, int total, int last) {
lu_mem max_sizet = MAX_SIZET; lu_mem max_sizet = MAX_SIZET;
if (G(L)->memlimit < max_sizet) max_sizet = G(L)->memlimit; if (G(L)->memlimit < max_sizet) max_sizet = G(L)->memlimit;
do { 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; StkId top = L->base + last + 1;
fixedstack(L);
int n = 2; /* number of elements handled in this pass (at least 2) */ int n = 2; /* number of elements handled in this pass (at least 2) */
if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) { 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)) { if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) {
/* restore 'top' pointer, since stack might have been reallocted */ /* restore 'top' pointer, since stack might have been reallocted */
top = L->base + last + 1; top = L->base + last + 1;
luaG_concaterror(L, top-2, top-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) */ (void)tostring(L, top - 2); /* result is first op (as string) */
else { } else {
/* at least two string values; get as many as possible */ /* at least two string values; get as many as possible */
size_t tl = tsvalue(top-1)->len; size_t tl = tsvalue(top-1)->len;
char *buffer; char *buffer;
int i; int i;
fixedstack(L);
/* collect total length */ /* collect total length */
for (n = 1; n < total && tostring(L, top-n-1); n++) { for (n = 1; n < total && tostring(L, top-n-1); n++) {
size_t l = tsvalue(top-n-1)->len; 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)); setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl));
luaZ_resetbuffer(&G(L)->buff); luaZ_resetbuffer(&G(L)->buff);
unfixedstack(L);
} }
total -= n-1; /* got `n' strings to create 1 new */ total -= n-1; /* got `n' strings to create 1 new */
last -= n-1; last -= n-1;
unfixedstack(L);
} while (total > 1); /* repeat until only 1 result left */ } while (total > 1); /* repeat until only 1 result left */
} }