From 9de82c2af2a67ab991c3aac687020bb0759c4ab8 Mon Sep 17 00:00:00 2001 From: TheRodzz <81969589+TheRodzz@users.noreply.github.com> Date: Wed, 5 Aug 2026 09:47:49 +0530 Subject: [PATCH 1/2] embed: return fs.ErrInvalid for invalid Seek whence This commit addresses an inconsistency in the behavior of the Seek method implemented by embed.FS compared to os.File. Previously, when an invalid whence value was provided to Seek on an embedded file, the method would silently ignore the error and perform no operation. To align the behavior with the standard io.Seeker interface and os.File, we now explicitly validate the whence parameter. If the provided whence is not one of io.SeekStart, io.SeekCurrent, or io.SeekEnd, the method will return an fs.ErrInvalid error. A regression test has also been added to ensure this behavior remains correct. Fixes #80696 --- src/embed/embed.go | 2 ++ src/embed/internal/embedtest/embed_test.go | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/src/embed/embed.go b/src/embed/embed.go index 4d5e418c9024b3..d5d436d3ce0d0f 100644 --- a/src/embed/embed.go +++ b/src/embed/embed.go @@ -365,6 +365,8 @@ func (f *openFile) Seek(offset int64, whence int) (int64, error) { offset += f.offset case 2: offset += int64(len(f.f.data)) + default: + return 0, &fs.PathError{Op: "seek", Path: f.f.name, Err: fs.ErrInvalid} } if offset < 0 || offset > int64(len(f.f.data)) { return 0, &fs.PathError{Op: "seek", Path: f.f.name, Err: fs.ErrInvalid} diff --git a/src/embed/internal/embedtest/embed_test.go b/src/embed/internal/embedtest/embed_test.go index 875265556f0940..2af4f7438a1668 100644 --- a/src/embed/internal/embedtest/embed_test.go +++ b/src/embed/internal/embedtest/embed_test.go @@ -6,7 +6,9 @@ package embedtest import ( "embed" + "errors" "io" + "io/fs" "reflect" "slices" "testing" @@ -220,6 +222,15 @@ func TestOffset(t *testing.T) { t.Fatal("Seek:", off) } + // Use Seek with an invalid whence. + _, err = seeker.Seek(0, 3) + if err == nil { + t.Fatal("Seek: expected error for invalid whence") + } + if !errors.Is(err, fs.ErrInvalid) { + t.Fatalf("Seek: expected fs.ErrInvalid, got %v", err) + } + // Use ReadAt to read the entire file, ignoring the offset. at := file.(io.ReaderAt) got = make([]byte, len(want)) From a9f28f4f5cc28a5b662aa5452939c5c8e39ccbca Mon Sep 17 00:00:00 2001 From: TheRodzz <81969589+TheRodzz@users.noreply.github.com> Date: Thu, 6 Aug 2026 11:35:32 +0530 Subject: [PATCH 2/2] embed: use io.Seek constants in Seek whence switch and tests Use io.SeekStart, io.SeekCurrent, and io.SeekEnd constants in openFile.Seek instead of raw numeric literals. Also update the invalid whence test to use io.SeekEnd+5. --- src/embed/embed.go | 6 +++--- src/embed/internal/embedtest/embed_test.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/embed/embed.go b/src/embed/embed.go index d5d436d3ce0d0f..5b99c5e69a6526 100644 --- a/src/embed/embed.go +++ b/src/embed/embed.go @@ -359,11 +359,11 @@ func (f *openFile) Read(b []byte) (int, error) { func (f *openFile) Seek(offset int64, whence int) (int64, error) { switch whence { - case 0: + case io.SeekStart: // offset += 0 - case 1: + case io.SeekCurrent: offset += f.offset - case 2: + case io.SeekEnd: offset += int64(len(f.f.data)) default: return 0, &fs.PathError{Op: "seek", Path: f.f.name, Err: fs.ErrInvalid} diff --git a/src/embed/internal/embedtest/embed_test.go b/src/embed/internal/embedtest/embed_test.go index 2af4f7438a1668..3c69cce21f9059 100644 --- a/src/embed/internal/embedtest/embed_test.go +++ b/src/embed/internal/embedtest/embed_test.go @@ -223,7 +223,7 @@ func TestOffset(t *testing.T) { } // Use Seek with an invalid whence. - _, err = seeker.Seek(0, 3) + _, err = seeker.Seek(0, io.SeekEnd+5) if err == nil { t.Fatal("Seek: expected error for invalid whence") }