forked from TrueCloudLab/restic
internal/repository: Fix LoadBlob + fuzz test
When given a buf that is big enough for a compressed blob but not its decompressed contents, the copy at the end of LoadBlob would skip the last part of the contents. Fixes #3783.
This commit is contained in:
parent
b7c990871f
commit
c9557b2822
4 changed files with 50 additions and 1 deletions
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
# Workaround for https://github.com/golang/go/issues/52268.
|
||||
**/testdata/fuzz/*/* eol=lf
|
43
internal/repository/fuzz_test.go
Normal file
43
internal/repository/fuzz_test.go
Normal file
|
@ -0,0 +1,43 @@
|
|||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/restic/restic/internal/backend/mem"
|
||||
"github.com/restic/restic/internal/restic"
|
||||
)
|
||||
|
||||
// Test saving a blob and loading it again, with varying buffer sizes.
|
||||
// Also a regression test for #3783.
|
||||
func FuzzSaveLoadBlob(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, blob []byte, buflen uint) {
|
||||
if buflen > 64<<20 {
|
||||
// Don't allocate enormous buffers. We're not testing the allocator.
|
||||
t.Skip()
|
||||
}
|
||||
|
||||
id := restic.Hash(blob)
|
||||
repo, _ := TestRepositoryWithBackend(t, mem.New(), 2)
|
||||
|
||||
_, _, err := repo.SaveBlob(context.TODO(), restic.DataBlob, blob, id, false)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = repo.Flush(context.TODO())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
buf, err := repo.LoadBlob(context.TODO(), restic.DataBlob, id, make([]byte, buflen))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if restic.Hash(buf) != id {
|
||||
t.Fatal("mismatch")
|
||||
}
|
||||
})
|
||||
}
|
|
@ -303,8 +303,9 @@ func (r *Repository) LoadBlob(ctx context.Context, t restic.BlobType, id restic.
|
|||
return plaintext, nil
|
||||
}
|
||||
// move decrypted data to the start of the buffer
|
||||
buf = buf[:len(plaintext)]
|
||||
copy(buf, plaintext)
|
||||
return buf[:len(plaintext)], nil
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
if lastError != nil {
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
go test fuzz v1
|
||||
[]byte("\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6")
|
||||
uint(109)
|
Loading…
Reference in a new issue