@@ -713,13 +713,15 @@ auto device_selection =
713
713
named_file_types_x (types, i)\
714
714
).min(0 ).doc_non_optional(true )
715
715
716
- #define optional_untyped_file_selection_x (name, i )\
716
+ #define optional_untyped_path_selection_x (name, desc , i )\
717
717
(\
718
718
value (name).with_exclusion_filter([](const string &value) {\
719
719
return value.find_first_of (' -' ) == 0 ;\
720
- }).set(settings.filenames[i]).min(0 ) % " The file name " \
720
+ }).set(settings.filenames[i]).min(0 ) % desc \
721
721
).min(0 ).doc_non_optional(true )
722
722
723
+ #define optional_untyped_file_selection_x (name, i ) optional_untyped_path_selection_x(name, " The file name" , i)
724
+
723
725
#define option_file_selection_x (option, i )\
724
726
(\
725
727
option & value (" filename" ).with_exclusion_filter([](const string &value) {\
@@ -834,7 +836,7 @@ auto bdev_options = (
834
836
integer (" partition" ).set(settings.bdev.partition) % "partition number").force_expand_help(true ) +
835
837
(option(" --filesystem" ) % "Specify filesystem to use" &
836
838
bdev_fs(" fs" ).set(settings.bdev.fs) % "littlefs|fatfs").force_expand_help(true ) +
837
- (option(' f ' , " --format" ).set(settings.bdev.format) % "Format the drive if necessary (may result in data loss)")
839
+ (option(" --format" ).set(settings.bdev.format) % "Format the drive if necessary (may result in data loss)")
838
840
).min(0 ).doc_non_optional(true ) % "Block device options";
839
841
840
842
struct bdev_ls_command : public cmd {
@@ -843,7 +845,7 @@ struct bdev_ls_command : public cmd {
843
845
844
846
group get_cli () override {
845
847
return (
846
- optional_untyped_file_selection_x (" dirname" , 0 ) +
848
+ optional_untyped_path_selection_x (" dirname" , " The directory name to list (optional) " , 0 ) +
847
849
option (' r' , " --recursive" ).set (settings.bdev .recursive ) % " List files in directories recursively" +
848
850
bdev_options +
849
851
device_selection % " Target device selection"
@@ -2370,8 +2372,15 @@ struct picoboot_memory_access : public memory_access {
2370
2372
return ;
2371
2373
}
2372
2374
// Check if we need to erase (ie check for non 0xff)
2373
- if (!std::all_of (write_data.cbegin (), write_data.cend (), [](uint8_t v) { return v == 0xff ; })) {
2374
- // Do automatically erase flash, and make it aligned
2375
+ bool do_erase = false ;
2376
+ for (int i = 0 ; i < write_data.size (); i++) {
2377
+ if (buffer[i] & ~write_data[i]) {
2378
+ do_erase = true ;
2379
+ break ;
2380
+ }
2381
+ }
2382
+ if (do_erase) {
2383
+ // Automatically erase flash, and make it aligned
2375
2384
// we have to erase in whole pages
2376
2385
range aligned_range (address & ~(FLASH_SECTOR_ERASE_SIZE - 1 ),
2377
2386
((address + size) & ~(FLASH_SECTOR_ERASE_SIZE - 1 )) + FLASH_SECTOR_ERASE_SIZE);
@@ -6230,11 +6239,19 @@ static_assert(FF_MAX_SS == FF_MIN_SS, "FF_MAX_SS must be equal to FF_MIN_SS");
6230
6239
#define SECTOR_SIZE FF_MAX_SS
6231
6240
6232
6241
DRESULT disk_read (void *drv, BYTE* buff, DWORD sector, UINT count) {
6242
+ if (sector >= bdevfs_setup.size / SECTOR_SIZE) {
6243
+ fail (ERROR_NOT_POSSIBLE, " Sector %d is out of range" , sector);
6244
+ return RES_PARERR;
6245
+ }
6233
6246
bdevfs_setup.access ->read (bdevfs_setup.base_addr + (sector * SECTOR_SIZE), (uint8_t *)buff, count * SECTOR_SIZE, false );
6234
6247
return RES_OK;
6235
6248
}
6236
6249
6237
6250
DRESULT disk_write (void *drv, const BYTE* buff, DWORD sector, UINT count) {
6251
+ if (sector >= bdevfs_setup.size / SECTOR_SIZE) {
6252
+ fail (ERROR_NOT_POSSIBLE, " Sector %d is out of range" , sector);
6253
+ return RES_PARERR;
6254
+ }
6238
6255
if (bdevfs_setup.writeable ) {
6239
6256
bdevfs_setup.access ->write (bdevfs_setup.base_addr + (sector * SECTOR_SIZE), (uint8_t *)buff, count * SECTOR_SIZE);
6240
6257
return RES_OK;
@@ -6276,6 +6293,11 @@ DRESULT disk_ioctl (void *drv, BYTE cmd, void* buff) {
6276
6293
// Only trim complete flash sectors
6277
6294
if (start % FLASH_SECTOR_ERASE_SIZE) start += FLASH_SECTOR_ERASE_SIZE - (start % FLASH_SECTOR_ERASE_SIZE);
6278
6295
end -= end % FLASH_SECTOR_ERASE_SIZE;
6296
+ // Check if start and end are in range
6297
+ if (start < bdevfs_setup.base_addr || end > bdevfs_setup.base_addr + bdevfs_setup.size ) {
6298
+ fail (ERROR_NOT_POSSIBLE, " Start or end is out of range" );
6299
+ return RES_PARERR;
6300
+ }
6279
6301
for (uint32_t addr = start; addr < end; addr += FLASH_SECTOR_ERASE_SIZE) {
6280
6302
bdevfs_setup.connection ->flash_erase (addr, FLASH_SECTOR_ERASE_SIZE);
6281
6303
}
@@ -6388,11 +6410,19 @@ void do_fatfs_op(fatfs_op_fn fatfs_op) {
6388
6410
6389
6411
// LittleFS Functions
6390
6412
int lfs_read (const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size) {
6413
+ if (block >= bdevfs_setup.size / c->block_size ) {
6414
+ fail (ERROR_NOT_POSSIBLE, " Block %d is out of range" , block);
6415
+ return LFS_ERR_INVAL;
6416
+ }
6391
6417
bdevfs_setup.access ->read (bdevfs_setup.base_addr + (block * c->block_size ) + off, (uint8_t *)buffer, size, false );
6392
6418
return LFS_ERR_OK;
6393
6419
}
6394
6420
6395
6421
int lfs_prog (const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size) {
6422
+ if (block >= bdevfs_setup.size / c->block_size ) {
6423
+ fail (ERROR_NOT_POSSIBLE, " Block %d is out of range" , block);
6424
+ return LFS_ERR_INVAL;
6425
+ }
6396
6426
if (bdevfs_setup.writeable ) {
6397
6427
bdevfs_setup.access ->write (bdevfs_setup.base_addr + (block * c->block_size ) + off, (uint8_t *)buffer, size);
6398
6428
return LFS_ERR_OK;
@@ -6403,6 +6433,10 @@ int lfs_prog(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const
6403
6433
};
6404
6434
6405
6435
int lfs_erase (const struct lfs_config *c, lfs_block_t block) {
6436
+ if (block >= bdevfs_setup.size / c->block_size ) {
6437
+ fail (ERROR_NOT_POSSIBLE, " Block %d is out of range" , block);
6438
+ return LFS_ERR_INVAL;
6439
+ }
6406
6440
if (bdevfs_setup.writeable ) {
6407
6441
bdevfs_setup.connection ->flash_erase (bdevfs_setup.base_addr + (block * c->block_size ), c->block_size );
6408
6442
return LFS_ERR_OK;
@@ -6613,6 +6647,11 @@ bool bdev_cp_command::execute(device_map &devices) {
6613
6647
if (!srcRemote) {
6614
6648
auto infile = get_file_idx (ios::in|ios::binary|ios::ate, 0 );
6615
6649
auto size = infile->tellg ();
6650
+ uint32_t max_size = bdevfs_setup.access ->get_model ()->flash_end () - bdevfs_setup.access ->get_model ()->flash_start ();
6651
+ if (size > max_size) {
6652
+ fail (ERROR_NOT_POSSIBLE, " File size %dMB is too large for flash device (max %dMB)" , size / (1024 * 1024 ), max_size / (1024 * 1024 ));
6653
+ return false ;
6654
+ }
6616
6655
infile->seekg (0 , std::ios::beg);
6617
6656
data_buf.resize (size);
6618
6657
infile->read (data_buf.data (), size);
0 commit comments