From 1539ffc997ab1dde3b0391ac3cd87ef71ec6dc85 Mon Sep 17 00:00:00 2001 From: "Earle F. Philhower, III" Date: Sun, 24 May 2020 09:22:25 -0700 Subject: [PATCH] Return FALSE on seek past EOF Fixes #7323 While I'm not a fan, the Arduino FileSeek API online shows that a seek() past EOF should return FALSE. https://www.arduino.cc/en/Reference/FileSeek SPIFFS and SDFS obey this, but LittleFS followed the POSIX standard or allowing seeks past EOF. Update LittleFS::seek() to follow the Arduino API and add tests for it. --- libraries/LittleFS/src/LittleFS.h | 5 +++++ tests/host/fs/test_fs.inc | 24 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/libraries/LittleFS/src/LittleFS.h b/libraries/LittleFS/src/LittleFS.h index 4d417905e4..f78680f662 100644 --- a/libraries/LittleFS/src/LittleFS.h +++ b/libraries/LittleFS/src/LittleFS.h @@ -377,11 +377,16 @@ class LittleFSFileImpl : public FileImpl if (mode == SeekEnd) { offset = -offset; // TODO - this seems like its plain wrong vs. POSIX } + auto lastPos = position(); int rc = lfs_file_seek(_fs->getFS(), _getFD(), offset, (int)mode); // NB. SeekMode === LFS_SEEK_TYPES if (rc < 0) { DEBUGV("lfs_file_seek rc=%d\n", rc); return false; } + if (position() > size()) { + seek(lastPos, SeekSet); // Pretend the seek() never happened + return false; + } return true; } diff --git a/tests/host/fs/test_fs.inc b/tests/host/fs/test_fs.inc index 9a10e688f4..0a2cc423fc 100644 --- a/tests/host/fs/test_fs.inc +++ b/tests/host/fs/test_fs.inc @@ -174,6 +174,30 @@ TEST_CASE(TESTPRE "open(w+) truncates file", TESTPAT) REQUIRE( t == ""); } +TEST_CASE(TESTPRE "peek() returns -1 on EOF", TESTPAT) +{ + FS_MOCK_DECLARE(64, 8, 512, ""); + REQUIRE(FSTYPE.begin()); + createFile("/file1", "some text"); + auto f = FSTYPE.open("/file1", "r+"); + REQUIRE(f.seek(8)); + REQUIRE(f.peek() == 't'); + REQUIRE(f.read() == 't'); + REQUIRE(f.peek() == -1); + REQUIRE(f.read() == -1); + f.close(); +} + +TEST_CASE(TESTPRE "seek() pase EOF returns error (#7323)", TESTPAT) +{ + FS_MOCK_DECLARE(64, 8, 512, ""); + REQUIRE(FSTYPE.begin()); + createFile("/file1", "some text"); + auto f = FSTYPE.open("/file1", "r+"); + REQUIRE_FALSE(f.seek(10)); + f.close(); +} + #ifdef FS_HAS_DIRS #if FSTYPE != SDFS