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 /apps/plugins | |
parent | 305ec1211f912cf8d3b6dcd8e973efb216eb1cde (diff) | |
download | rockbox-1b41e6ec438fa6b66d1d84fadd02b9554ddc2a9c.tar.gz rockbox-1b41e6ec438fa6b66d1d84fadd02b9554ddc2a9c.zip |
lua fix crashes EGC failure to lock stack in concat
Change-Id: I980637b1d8aa91d7ac0ed71fd0e7d21bda7876c4
Diffstat (limited to 'apps/plugins')
-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) { | |||
290 | 290 | ||
291 | void luaV_concat (lua_State *L, int total, int last) { | 291 | void 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 | ||