From c83d8b7abce4a992096e17cbb5f808a9633394c3 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Tue, 25 Apr 2023 01:58:42 -0500 Subject: [PATCH] Added lfsr_data_add for more lfsr_data_t manipulation Also fixed an internal (currently unreachable) bug in lfs_bd_cmp where the hint could underflow if zero. --- lfs.c | 73 ++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 28 deletions(-) diff --git a/lfs.c b/lfs.c index 6010ff80..8de997b0 100644 --- a/lfs.c +++ b/lfs.c @@ -164,6 +164,8 @@ static int lfs_bd_cmp(lfs_t *lfs, const void *buffer, lfs_size_t size) { const uint8_t *data = buffer; lfs_size_t diff = 0; + // make sure our hint is at least as big as our buffer + hint = lfs_max(hint, size); for (lfs_off_t i = 0; i < size; i += diff) { uint8_t dat[8]; @@ -1000,6 +1002,21 @@ static inline lfs_size_t lfsr_data_setondisk(lfs_size_t size) { return size | 0x80000000; } +static lfsr_data_t lfsr_data_add(lfsr_data_t data, lfs_off_t off) { + // limit our off to data range + lfs_off_t off_ = lfs_min32(off, lfsr_data_size(data)); + + if (lfsr_data_ondisk(data)) { + data.disk.off += off_; + data.disk.size -= off_; + } else { + data.buf.buffer += off_; + data.buf.size -= off_; + } + + return data; +} + // data<->bd interactions static lfs_ssize_t lfsr_data_read(lfs_t *lfs, lfsr_data_t data, lfs_off_t off, void *buffer, lfs_size_t size) { @@ -1023,6 +1040,34 @@ static lfs_ssize_t lfsr_data_read(lfs_t *lfs, lfsr_data_t data, return size_; } +static lfs_ssize_t lfsr_data_readle32(lfs_t *lfs, lfsr_data_t data, + lfs_off_t off, uint32_t *word) { + lfs_ssize_t d = lfsr_data_read(lfs, data, off, word, sizeof(uint32_t)); + if (d < 0) { + return d; + } + + // truncated? + if ((lfs_size_t)d < sizeof(uint32_t)) { + return LFS_ERR_CORRUPT; + } + + *word = lfs_fromle32_(word); + return sizeof(uint32_t); +} + +static lfs_ssize_t lfsr_data_readleb128(lfs_t *lfs, lfsr_data_t data, + lfs_off_t off, uint32_t *word) { + // for 32-bits we can assume worst-case leb128 size is 5-bytes + uint8_t buf[5]; + lfs_ssize_t d = lfsr_data_read(lfs, data, off, buf, 5); + if (d < 0) { + return d; + } + + return lfs_fromleb128(word, buf, d); +} + static int lfsr_data_cmp(lfs_t *lfs, lfsr_data_t data, lfs_off_t off, const void *buffer, lfs_size_t size, int *cmp) { @@ -1053,34 +1098,6 @@ static int lfsr_data_cmp(lfs_t *lfs, lfsr_data_t data, return 0; } -static lfs_ssize_t lfsr_data_readle32(lfs_t *lfs, lfsr_data_t data, - lfs_off_t off, uint32_t *word) { - lfs_ssize_t d = lfsr_data_read(lfs, data, off, word, sizeof(uint32_t)); - if (d < 0) { - return d; - } - - // truncated? - if ((lfs_size_t)d < sizeof(uint32_t)) { - return LFS_ERR_CORRUPT; - } - - *word = lfs_fromle32_(word); - return sizeof(uint32_t); -} - -static lfs_ssize_t lfsr_data_readleb128(lfs_t *lfs, lfsr_data_t data, - lfs_off_t off, uint32_t *word) { - // for 32-bits we can assume worst-case leb128 size is 5-bytes - uint8_t buf[5]; - lfs_ssize_t d = lfsr_data_read(lfs, data, off, buf, 5); - if (d < 0) { - return d; - } - - return lfs_fromleb128(word, buf, d); -} - static lfs_ssize_t lfsr_bd_progdata(lfs_t *lfs, lfs_block_t block, lfs_off_t off, lfsr_data_t data,