From 7b47fea3fcab1a7c4eb07b3b80bc931273cad213 Mon Sep 17 00:00:00 2001 From: tdakkota Date: Fri, 12 Feb 2021 13:02:47 +0300 Subject: [PATCH] fix(mem): do not overwrite old data in some cases (fixes #286) --- mem/file.go | 2 +- mem/file_test.go | 51 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/mem/file.go b/mem/file.go index 290369ad..5a20730c 100644 --- a/mem/file.go +++ b/mem/file.go @@ -267,7 +267,7 @@ func (f *File) Write(b []byte) (n int, err error) { tail = f.fileData.data[n+int(cur):] } if diff > 0 { - f.fileData.data = append(bytes.Repeat([]byte{00}, int(diff)), b...) + f.fileData.data = append(f.fileData.data, append(bytes.Repeat([]byte{00}, int(diff)), b...)...) f.fileData.data = append(f.fileData.data, tail...) } else { f.fileData.data = append(f.fileData.data[:cur], b...) diff --git a/mem/file_test.go b/mem/file_test.go index 22af9707..998a5d0b 100644 --- a/mem/file_test.go +++ b/mem/file_test.go @@ -95,6 +95,57 @@ func TestFileDataModeRace(t *testing.T) { } } +// See https://github.com/spf13/afero/issues/286. +func TestFileWriteAt(t *testing.T) { + t.Parallel() + + data := CreateFile("abc.txt") + f := NewFileHandle(data) + + testData := []byte{1, 2, 3, 4, 5} + offset := len(testData) + + // 5 zeros + testdata + _, err := f.WriteAt(testData, int64(offset)) + if err != nil { + t.Fatal(err) + } + + // 2 * testdata + _, err = f.WriteAt(testData, 0) + if err != nil { + t.Fatal(err) + } + + // 3 * testdata + _, err = f.WriteAt(testData, int64(offset*2)) + if err != nil { + t.Fatal(err) + } + + // 3 * testdata + 5 zeros + testdata + _, err = f.WriteAt(testData, int64(offset*4)) + if err != nil { + t.Fatal(err) + } + + // 5 * testdata + _, err = f.WriteAt(testData, int64(offset*3)) + if err != nil { + t.Fatal(err) + } + + err = f.Close() + if err != nil { + t.Fatal(err) + } + + expected := bytes.Repeat(testData, 5) + if !bytes.Equal(expected, data.data) { + t.Fatalf("expected: %v, got: %v", expected, data.data) + } +} + func TestFileDataIsDirRace(t *testing.T) { t.Parallel()