From aeb0644bd33e67f24e2411a651ac9ff72ddc96b4 Mon Sep 17 00:00:00 2001 From: Jabar Asadi Date: Fri, 19 May 2023 09:31:25 +0000 Subject: [PATCH] io: prevent seeking to position prior to offsetwrite.base We don't want to permit writing before the start of an OffsetWriter. One of the goals of OffsetWriter is to restrict where data can be written. However, this rule can be violated by WriteAt() method of OffsetWriter as the following code shows: f, _ := os.Create("file.txt") owr := io.NewOffsetWriter(f, 10) owr.Write([]byte("world")) owr.WriteAt([]byte("hello"), -10) Change-Id: I6c7519fea68daefa641f25130cdd9803dc8aae22 GitHub-Last-Rev: a29d890d6f32fd5a1ecef84d012b8447b406e2e2 GitHub-Pull-Request: golang/go#60222 Reviewed-on: https://go-review.googlesource.com/c/go/+/495155 Run-TryBot: Ian Lance Taylor Reviewed-by: Ian Lance Taylor Auto-Submit: Ian Lance Taylor Run-TryBot: Ian Lance Taylor TryBot-Result: Gopher Robot Reviewed-by: Jabar Asadi Reviewed-by: Dmitri Shuralyov --- src/io/io.go | 4 ++++ src/io/io_test.go | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/io/io.go b/src/io/io.go index 7b8ee10a56..bcb9f774f6 100644 --- a/src/io/io.go +++ b/src/io/io.go @@ -575,6 +575,10 @@ func (o *OffsetWriter) Write(p []byte) (n int, err error) { } func (o *OffsetWriter) WriteAt(p []byte, off int64) (n int, err error) { + if off < 0 { + return 0, errOffset + } + off += o.base return o.w.WriteAt(p, off) } diff --git a/src/io/io_test.go b/src/io/io_test.go index 35db15c3ba..c09b5e34d2 100644 --- a/src/io/io_test.go +++ b/src/io/io_test.go @@ -608,6 +608,26 @@ func TestOffsetWriter_WriteAt(t *testing.T) { } } +func TestWriteAt_PositionPriorToBase(t *testing.T) { + tmpdir := t.TempDir() + tmpfilename := "TestOffsetWriter_WriteAt" + tmpfile, err := os.CreateTemp(tmpdir, tmpfilename) + if err != nil { + t.Fatalf("CreateTemp(%s) failed: %v", tmpfilename, err) + } + defer tmpfile.Close() + + // start writing position in OffsetWriter + offset := int64(10) + // position we want to write to the tmpfile + at := int64(-1) + w := NewOffsetWriter(tmpfile, offset) + _, e := w.WriteAt([]byte("hello"), at) + if e == nil { + t.Errorf("error expected to be not nil") + } +} + func TestOffsetWriter_Write(t *testing.T) { const content = "0123456789ABCDEF" contentSize := len(content) -- 2.50.0