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.
This commit is contained in:
Johny Mattsson 2021-11-20 08:50:27 +11:00 committed by GitHub
parent f7b48b9214
commit 1965a12efc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 13 additions and 7 deletions

View File

@ -473,7 +473,7 @@ static int loadLFS (lua_State *L) {
vfs_lseek(in->fd, 0, VFS_SEEK_SET); vfs_lseek(in->fd, 0, VFS_SEEK_SET);
/* Allocate the out buffers */ /* 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); out->block[i] = luaM_new(L, outBlock);
/* first inflate pass */ /* first inflate pass */
@ -497,8 +497,9 @@ static int loadLFS (lua_State *L) {
flashErase(0,(out->flashLen - 1)/FLASH_PAGE_SIZE); flashErase(0,(out->flashLen - 1)/FLASH_PAGE_SIZE);
flashSetPosition(0); flashSetPosition(0);
if ((res = uzlib_inflate(get_byte, put_byte, recall_byte, res = uzlib_inflate(get_byte, put_byte, recall_byte,
in->len, &crc, &in->inflate_state)) != UZLIB_DONE) { in->len, &crc, &in->inflate_state);
if (res < 0) { // UZLIB_OK == 0, UZLIB_DONE == 1
const char *err[] = {"Data_error during decompression", const char *err[] = {"Data_error during decompression",
"Chksum_error during decompression", "Chksum_error during decompression",
"Dictionary error during decompression", "Dictionary error during decompression",

View File

@ -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. */ /* These compression maps must match the definitions in lobject.h etc. */
# define OFFSET_TSTRING (2*(sizeof(lu_int32)-sizeof(size_t))) # define OFFSET_TSTRING (2*(sizeof(lu_int32)-sizeof(size_t)))
# define FMT_TSTRING "AwwA" # 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_PROTO "AwwwwwwwwwwAAAAAAAA"
# define FMT_UPVALUE "AW" # define FMT_UPVALUE "AW"
# define FMT_LOCVAR "Aww" # define FMT_LOCVAR "Aww"
# define FMT_ROTENTRY "AWA" # define FMT_ROTENTRY "A" FMT_TVALUE
# define FMT_ROTABLE "AWAA" # define FMT_ROTABLE "AWAA"
# define StoreR(S,a, i, v, f) Store_(S, (a), i, &(v), sizeof(v), f) # 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) # 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); S->pv[i] = LoadFunction(S, luaF_newproto(L), NULL);
} }
/* generate the ROTable entries from first N constants; the last is a timestamp */ /* 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)); 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); lu_byte tt_data = LoadByte(S);
TString *Tname = LoadString2(S, tt_data); TString *Tname = LoadString2(S, tt_data);
const char *name = getstr(Tname) + OFFSET_TSTRING; const char *name = getstr(Tname) + OFFSET_TSTRING;