From d3b62b9144470e0c06fc3098a0b3fad0acd1eaf3 Mon Sep 17 00:00:00 2001 From: Johny Mattsson Date: Sat, 20 Nov 2021 08:50:27 +1100 Subject: [PATCH] Minor Lua fixes. (#3467) Discovered over on the dev-esp32-idf4 branch. - Off by one error in loadLFS, leading to slight memory leak and potential corruption. - Insufficient return value check in loadLFS, where uzlib may return one of two success conditions, one of which would result in an out-of-bounds access and related pain. - One case of a side effect within a lua_assert(), leading to silently broken LFS image handling when compiling without asserts enabled, the issue showing up as module names being shuffled around. - Incorrect encoding of TValues in LFS when 64bit numbers in use. --- app/lua/lflash.c | 7 ++++--- app/lua53/lundump.c | 13 +++++++++---- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/app/lua/lflash.c b/app/lua/lflash.c index 6875106d..bfb454ce 100644 --- a/app/lua/lflash.c +++ b/app/lua/lflash.c @@ -473,7 +473,7 @@ static int loadLFS (lua_State *L) { vfs_lseek(in->fd, 0, VFS_SEEK_SET); /* Allocate the out buffers */ - for(i = 0; i <= WRITE_BLOCKS; i++) + for(i = 0; i < WRITE_BLOCKS; i++) out->block[i] = luaM_new(L, outBlock); /* first inflate pass */ @@ -497,8 +497,9 @@ static int loadLFS (lua_State *L) { flashErase(0,(out->flashLen - 1)/FLASH_PAGE_SIZE); flashSetPosition(0); - if ((res = uzlib_inflate(get_byte, put_byte, recall_byte, - in->len, &crc, &in->inflate_state)) != UZLIB_DONE) { + res = uzlib_inflate(get_byte, put_byte, recall_byte, + in->len, &crc, &in->inflate_state); + if (res < 0) { // UZLIB_OK == 0, UZLIB_DONE == 1 const char *err[] = {"Data_error during decompression", "Chksum_error during decompression", "Dictionary error during decompression", diff --git a/app/lua53/lundump.c b/app/lua53/lundump.c index 578e2d29..3ec6bd40 100644 --- a/app/lua53/lundump.c +++ b/app/lua53/lundump.c @@ -145,11 +145,15 @@ static void *Store_(LoadState *S, void *a, int ndx, const void *e, size_t s /* These compression maps must match the definitions in lobject.h etc. */ # define OFFSET_TSTRING (2*(sizeof(lu_int32)-sizeof(size_t))) # define FMT_TSTRING "AwwA" -# define FMT_TVALUE "WA" +#if defined(CONFIG_LUA_NUMBER_INT64) || defined(CONFIG_LUA_NUMBER_DOUBLE) || defined(LUA_NUMBER_64BITS) +# define FMT_TVALUE "www" +#else +# define FMT_TVALUE "AW" +#endif # define FMT_PROTO "AwwwwwwwwwwAAAAAAAA" # define FMT_UPVALUE "AW" # define FMT_LOCVAR "Aww" -# define FMT_ROTENTRY "AWA" +# define FMT_ROTENTRY "A" FMT_TVALUE # define FMT_ROTABLE "AWAA" # define StoreR(S,a, i, v, f) Store_(S, (a), i, &(v), sizeof(v), f) # define Store(S, a, i, v) StoreR(S, (a), i, v, NULL) @@ -575,9 +579,10 @@ static void LoadAllProtos (LoadState *S) { S->pv[i] = LoadFunction(S, luaF_newproto(L), NULL); } /* generate the ROTable entries from first N constants; the last is a timestamp */ - lua_assert(n+1 == LoadInt(S)); + int nk = LoadInt(S); + lua_assert(n+1 == nk); ROTable_entry *entry_list = cast(ROTable_entry *, StoreGetPos(S)); - for (i = 0; i < n; i++) { + for (i = 0; i < nk - 1; i++) { // -1 to ignore timestamp lu_byte tt_data = LoadByte(S); TString *Tname = LoadString2(S, tt_data); const char *name = getstr(Tname) + OFFSET_TSTRING;