From 5ac9c1157acb3ee7a828b5c6914f9f0cde7256dd Mon Sep 17 00:00:00 2001 From: Trey Moore Date: Tue, 16 Apr 2019 20:26:20 -0700 Subject: [PATCH] Prevent "slice bounds out of range" error if prefix is longer than snapshot IDs. This includes tests as well as other tests for the backend_find.Find function. Issue #2104. --- internal/restic/backend_find.go | 2 +- internal/restic/backend_find_test.go | 51 ++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/internal/restic/backend_find.go b/internal/restic/backend_find.go index 4d11739e8..096ac214c 100644 --- a/internal/restic/backend_find.go +++ b/internal/restic/backend_find.go @@ -24,7 +24,7 @@ func Find(be Lister, t FileType, prefix string) (string, error) { defer cancel() err := be.List(ctx, t, func(fi FileInfo) error { - if prefix == fi.Name[:len(prefix)] { + if len(fi.Name) >= len(prefix) && prefix == fi.Name[:len(prefix)] { if match == "" { match = fi.Name } else { diff --git a/internal/restic/backend_find_test.go b/internal/restic/backend_find_test.go index 2cec35b1f..4b1828a92 100644 --- a/internal/restic/backend_find_test.go +++ b/internal/restic/backend_find_test.go @@ -24,6 +24,57 @@ var samples = IDs{ TestParseID("fa31d65b87affcd167b119e9d3d2a27b8236ca4836cb077ed3e96fcbe209b792"), } +func TestFind(t *testing.T) { + list := samples + + m := mockBackend{} + m.list = func(ctx context.Context, t FileType, fn func(FileInfo) error) error { + for _, id := range list { + err := fn(FileInfo{Name: id.String()}) + if err != nil { + return err + } + } + return nil + } + + f, err := Find(m, SnapshotFile, "20bdc1402a6fc9b633aa") + if err != nil { + t.Error(err) + } + expected_match := "20bdc1402a6fc9b633aaffffffffffffffffffffffffffffffffffffffffffff" + if f != expected_match { + t.Errorf("Wrong match returned want %s, got %s", expected_match, f) + } + + f, err = Find(m, SnapshotFile, "NotAPrefix") + if err != ErrNoIDPrefixFound { + t.Error("Expected no snapshots to be found.") + } + if f != "" { + t.Errorf("Find should not return a match on error.") + } + + // Try to match with a prefix longer than any ID. + extra_length_id := samples[0].String() + "f" + f, err = Find(m, SnapshotFile, extra_length_id) + if err != ErrNoIDPrefixFound { + t.Error("Expected no snapshots to be matched.") + } + if f != "" { + t.Errorf("Find should not return a match on error.") + } + + // Use a prefix that will match the prefix of multiple Ids in `samples`. + f, err = Find(m, SnapshotFile, "20bdc140") + if err != ErrMultipleIDMatches { + t.Error("Expected multiple snapshots to be matched.") + } + if f != "" { + t.Errorf("Find should not return a match on error.") + } +} + func TestPrefixLength(t *testing.T) { list := samples