Added checks for out-of-bound seeks

- out-of-bound read results in eof
- out-of-bound write will fill missing area with zeros

The write behaviour matches expected posix behaviour, but was
under consideration for not being dropped, since littlefs does
not support holes, and support of out-of-band seeks adds complexity.

However, it turned out filling with zeros was trivial, and only
cost an extra 74 bytes of flash (0.48%).
This commit is contained in:
Christopher Haster
2017-09-17 17:57:12 -05:00
parent a8fa5e6571
commit a83b2fe463
2 changed files with 64 additions and 0 deletions

26
lfs.c
View File

@@ -1377,6 +1377,11 @@ lfs_ssize_t lfs_file_read(lfs_t *lfs, lfs_file_t *file,
} }
} }
if (file->pos >= file->size) {
// eof if past end
return 0;
}
size = lfs_min(size, file->size - file->pos); size = lfs_min(size, file->size - file->pos);
nsize = size; nsize = size;
@@ -1432,6 +1437,19 @@ lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file,
file->pos = file->size; file->pos = file->size;
} }
if (!(file->flags & LFS_F_WRITING) && file->pos > file->size) {
// fill with zeros
lfs_off_t pos = file->pos;
file->pos = file->size;
while (file->pos < pos) {
lfs_ssize_t res = lfs_file_write(lfs, file, &(uint8_t){0}, 1);
if (res < 0) {
return res;
}
}
}
while (nsize > 0) { while (nsize > 0) {
// check if we need a new block // check if we need a new block
if (!(file->flags & LFS_F_WRITING) || if (!(file->flags & LFS_F_WRITING) ||
@@ -1506,8 +1524,16 @@ lfs_soff_t lfs_file_seek(lfs_t *lfs, lfs_file_t *file,
if (whence == LFS_SEEK_SET) { if (whence == LFS_SEEK_SET) {
file->pos = off; file->pos = off;
} else if (whence == LFS_SEEK_CUR) { } else if (whence == LFS_SEEK_CUR) {
if (-off > file->pos) {
return LFS_ERR_INVAL;
}
file->pos = file->pos + off; file->pos = file->pos + off;
} else if (whence == LFS_SEEK_END) { } else if (whence == LFS_SEEK_END) {
if (-off > file->size) {
return LFS_ERR_INVAL;
}
file->pos = file->size + off; file->pos = file->size + off;
} }

View File

@@ -305,5 +305,43 @@ tests/test.py << TEST
lfs_unmount(&lfs) => 0; lfs_unmount(&lfs) => 0;
TEST TEST
echo "--- Out-of-bounds seek ---"
tests/test.py << TEST
lfs_mount(&lfs, &cfg) => 0;
lfs_file_open(&lfs, &file[0], "hello/kitty42", LFS_O_RDWR) => 0;
size = strlen("kittycatcat");
lfs_file_size(&lfs, &file[0]) => $LARGESIZE*size;
lfs_file_seek(&lfs, &file[0],
($LARGESIZE+$SMALLSIZE)*size, LFS_SEEK_SET) => 0;
lfs_file_read(&lfs, &file[0], buffer, size) => 0;
memcpy(buffer, "porcupineee", size);
lfs_file_write(&lfs, &file[0], buffer, size) => size;
lfs_file_seek(&lfs, &file[0],
($LARGESIZE+$SMALLSIZE)*size, LFS_SEEK_SET) =>
($LARGESIZE+$SMALLSIZE+1)*size;
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "porcupineee", size) => 0;
lfs_file_seek(&lfs, &file[0],
$LARGESIZE*size, LFS_SEEK_SET) =>
($LARGESIZE+$SMALLSIZE+1)*size;
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "\0\0\0\0\0\0\0\0\0\0\0", size) => 0;
lfs_file_seek(&lfs, &file[0],
-(($LARGESIZE+$SMALLSIZE)*size), LFS_SEEK_CUR) => LFS_ERR_INVAL;
lfs_file_tell(&lfs, &file[0]) => ($LARGESIZE+1)*size;
lfs_file_seek(&lfs, &file[0],
-(($LARGESIZE+2*$SMALLSIZE)*size), LFS_SEEK_END) => LFS_ERR_INVAL;
lfs_file_tell(&lfs, &file[0]) => ($LARGESIZE+1)*size;
lfs_file_close(&lfs, &file[0]) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Results ---" echo "--- Results ---"
tests/stats.py tests/stats.py