diff options
author | William Wilgus <me.theuser@yahoo.com> | 2019-08-05 21:20:30 -0500 |
---|---|---|
committer | William Wilgus <me.theuser@yahoo.com> | 2019-08-05 21:20:30 -0500 |
commit | 1b41e6ec438fa6b66d1d84fadd02b9554ddc2a9c (patch) | |
tree | 6d148c965cdc2b9091aee8fa216e75672371fb2f | |
parent | 305ec1211f912cf8d3b6dcd8e973efb216eb1cde (diff) | |
download | rockbox-1b41e6e.tar.gz rockbox-1b41e6e.zip |
lua fix crashes EGC failure to lock stack in concat
Change-Id: I980637b1d8aa91d7ac0ed71fd0e7d21bda7876c4
-rw-r--r-- | apps/plugins/lua/lvm.c | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/apps/plugins/lua/lvm.c b/apps/plugins/lua/lvm.c index 4979b6a88e..52d12d0371 100644 --- a/apps/plugins/lua/lvm.c +++ b/apps/plugins/lua/lvm.c @@ -290,22 +290,25 @@ int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) { void luaV_concat (lua_State *L, int total, int last) { do { + /* Any call which does a memory allocation may trim the stack, + invalidating top unless the stack is fixed during 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; @@ -322,10 +325,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 */ } |