mirror of
				https://github.com/eledio-devices/thirdparty-littlefs.git
				synced 2025-10-31 08:42:40 +01:00 
			
		
		
		
	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:
		
							
								
								
									
										26
									
								
								lfs.c
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								lfs.c
									
									
									
									
									
								
							| @@ -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; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user