summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam Wilgus <me.theuser@yahoo.com>2019-08-05 21:20:30 -0500
committerWilliam Wilgus <me.theuser@yahoo.com>2019-08-05 21:20:30 -0500
commit1b41e6ec438fa6b66d1d84fadd02b9554ddc2a9c (patch)
tree6d148c965cdc2b9091aee8fa216e75672371fb2f
parent305ec1211f912cf8d3b6dcd8e973efb216eb1cde (diff)
downloadrockbox-1b41e6ec438fa6b66d1d84fadd02b9554ddc2a9c.tar.gz
rockbox-1b41e6ec438fa6b66d1d84fadd02b9554ddc2a9c.zip
lua fix crashes EGC failure to lock stack in concat
Change-Id: I980637b1d8aa91d7ac0ed71fd0e7d21bda7876c4
-rw-r--r--apps/plugins/lua/lvm.c11
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) {
290 290
291void luaV_concat (lua_State *L, int total, int last) { 291void luaV_concat (lua_State *L, int total, int last) {
292 do { 292 do {
293 /* Any call which does a memory allocation may trim the stack,
294 invalidating top unless the stack is fixed during the allocation */
293 StkId top = L->base + last + 1; 295 StkId top = L->base + last + 1;
296 fixedstack(L);
294 int n = 2; /* number of elements handled in this pass (at least 2) */ 297 int n = 2; /* number of elements handled in this pass (at least 2) */
295 if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) { 298 if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) {
299 unfixedstack(L);
296 if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) { 300 if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) {
297 /* restore 'top' pointer, since stack might have been reallocted */ 301 /* restore 'top' pointer, since stack might have been reallocted */
298 top = L->base + last + 1; 302 top = L->base + last + 1;
299 luaG_concaterror(L, top-2, top-1); 303 luaG_concaterror(L, top-2, top-1);
300 } 304 }
301 } else if (tsvalue(top-1)->len == 0) /* second op is empty? */ 305 } else if (tsvalue(top-1)->len == 0) { /* second op is empty? */
302 (void)tostring(L, top - 2); /* result is first op (as string) */ 306 (void)tostring(L, top - 2); /* result is first op (as string) */
303 else { 307 } else {
304 /* at least two string values; get as many as possible */ 308 /* at least two string values; get as many as possible */
305 size_t tl = tsvalue(top-1)->len; 309 size_t tl = tsvalue(top-1)->len;
306 char *buffer; 310 char *buffer;
307 int i; 311 int i;
308 fixedstack(L);
309 /* collect total length */ 312 /* collect total length */
310 for (n = 1; n < total && tostring(L, top-n-1); n++) { 313 for (n = 1; n < total && tostring(L, top-n-1); n++) {
311 size_t l = tsvalue(top-n-1)->len; 314 size_t l = tsvalue(top-n-1)->len;
@@ -322,10 +325,10 @@ void luaV_concat (lua_State *L, int total, int last) {
322 } 325 }
323 setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl)); 326 setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl));
324 luaZ_resetbuffer(&G(L)->buff); 327 luaZ_resetbuffer(&G(L)->buff);
325 unfixedstack(L);
326 } 328 }
327 total -= n-1; /* got `n' strings to create 1 new */ 329 total -= n-1; /* got `n' strings to create 1 new */
328 last -= n-1; 330 last -= n-1;
331 unfixedstack(L);
329 } while (total > 1); /* repeat until only 1 result left */ 332 } while (total > 1); /* repeat until only 1 result left */
330} 333}
331 334