@@ -405,3 +405,111 @@ code = '''
405
405
lfs_file_close(&lfs, &file) => 0;
406
406
lfs_unmount(&lfs) => 0;
407
407
'''
408
+
409
+
410
+ # test possible overflow/underflow conditions
411
+ #
412
+ # note these need -fsanitize=undefined to consistently detect
413
+ # overflow/underflow conditions
414
+
415
+ [cases .test_seek_filemax ]
416
+ code = '''
417
+ lfs_t lfs;
418
+ lfs_format(&lfs, cfg) => 0;
419
+ lfs_mount(&lfs, cfg) => 0;
420
+ lfs_file_t file;
421
+ lfs_file_open(&lfs, &file, "kitty",
422
+ LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0;
423
+ uint8_t buffer[1024];
424
+ strcpy((char*)buffer, "kittycatcat");
425
+ size_t size = strlen((char*)buffer);
426
+ lfs_file_write(&lfs, &file, buffer, size) => size;
427
+
428
+ // seek with LFS_SEEK_SET
429
+ lfs_file_seek(&lfs, &file, LFS_FILE_MAX, LFS_SEEK_SET) => LFS_FILE_MAX;
430
+
431
+ // seek with LFS_SEEK_CUR
432
+ lfs_file_seek(&lfs, &file, 0, LFS_SEEK_CUR) => LFS_FILE_MAX;
433
+
434
+ // the file hasn't changed size, so seek end takes us back to the offset=0
435
+ lfs_file_seek(&lfs, &file, +10, LFS_SEEK_END) => size+10;
436
+
437
+ lfs_file_close(&lfs, &file) => 0;
438
+ lfs_unmount(&lfs) => 0;
439
+ '''
440
+
441
+ [cases .test_seek_underflow ]
442
+ code = '''
443
+ lfs_t lfs;
444
+ lfs_format(&lfs, cfg) => 0;
445
+ lfs_mount(&lfs, cfg) => 0;
446
+ lfs_file_t file;
447
+ lfs_file_open(&lfs, &file, "kitty",
448
+ LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0;
449
+ uint8_t buffer[1024];
450
+ strcpy((char*)buffer, "kittycatcat");
451
+ size_t size = strlen((char*)buffer);
452
+ lfs_file_write(&lfs, &file, buffer, size) => size;
453
+
454
+ // underflow with LFS_SEEK_CUR, should error
455
+ lfs_file_seek(&lfs, &file, -(size+10), LFS_SEEK_CUR) => LFS_ERR_INVAL;
456
+ lfs_file_seek(&lfs, &file, -LFS_FILE_MAX, LFS_SEEK_CUR) => LFS_ERR_INVAL;
457
+ lfs_file_seek(&lfs, &file, -(size+LFS_FILE_MAX), LFS_SEEK_CUR)
458
+ => LFS_ERR_INVAL;
459
+
460
+ // underflow with LFS_SEEK_END, should error
461
+ lfs_file_seek(&lfs, &file, -(size+10), LFS_SEEK_END) => LFS_ERR_INVAL;
462
+ lfs_file_seek(&lfs, &file, -LFS_FILE_MAX, LFS_SEEK_END) => LFS_ERR_INVAL;
463
+ lfs_file_seek(&lfs, &file, -(size+LFS_FILE_MAX), LFS_SEEK_END)
464
+ => LFS_ERR_INVAL;
465
+
466
+ // file pointer should not have changed
467
+ lfs_file_tell(&lfs, &file) => size;
468
+
469
+ lfs_file_close(&lfs, &file) => 0;
470
+ lfs_unmount(&lfs) => 0;
471
+ '''
472
+
473
+ [cases .test_seek_overflow ]
474
+ code = '''
475
+ lfs_t lfs;
476
+ lfs_format(&lfs, cfg) => 0;
477
+ lfs_mount(&lfs, cfg) => 0;
478
+ lfs_file_t file;
479
+ lfs_file_open(&lfs, &file, "kitty",
480
+ LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0;
481
+ uint8_t buffer[1024];
482
+ strcpy((char*)buffer, "kittycatcat");
483
+ size_t size = strlen((char*)buffer);
484
+ lfs_file_write(&lfs, &file, buffer, size) => size;
485
+
486
+ // seek to LFS_FILE_MAX
487
+ lfs_file_seek(&lfs, &file, LFS_FILE_MAX, LFS_SEEK_SET) => LFS_FILE_MAX;
488
+
489
+ // overflow with LFS_SEEK_CUR, should error
490
+ lfs_file_seek(&lfs, &file, +10, LFS_SEEK_CUR) => LFS_ERR_INVAL;
491
+ lfs_file_seek(&lfs, &file, +LFS_FILE_MAX, LFS_SEEK_CUR) => LFS_ERR_INVAL;
492
+
493
+ // LFS_SEEK_SET/END don't care about the current file position, but we can
494
+ // still overflow with a large offset
495
+
496
+ // overflow with LFS_SEEK_SET, should error
497
+ lfs_file_seek(&lfs, &file,
498
+ +((uint32_t)LFS_FILE_MAX+10),
499
+ LFS_SEEK_SET) => LFS_ERR_INVAL;
500
+ lfs_file_seek(&lfs, &file,
501
+ +((uint32_t)LFS_FILE_MAX+(uint32_t)LFS_FILE_MAX),
502
+ LFS_SEEK_SET) => LFS_ERR_INVAL;
503
+
504
+ // overflow with LFS_SEEK_END, should error
505
+ lfs_file_seek(&lfs, &file, +(LFS_FILE_MAX-size+10), LFS_SEEK_END)
506
+ => LFS_ERR_INVAL;
507
+ lfs_file_seek(&lfs, &file, +(LFS_FILE_MAX-size+LFS_FILE_MAX), LFS_SEEK_END)
508
+ => LFS_ERR_INVAL;
509
+
510
+ // file pointer should not have changed
511
+ lfs_file_tell(&lfs, &file) => LFS_FILE_MAX;
512
+
513
+ lfs_file_close(&lfs, &file) => 0;
514
+ lfs_unmount(&lfs) => 0;
515
+ '''
0 commit comments