diff --git a/snap/snapshotter.go b/snap/snapshotter.go index 818df922a..fb23a2c6e 100644 --- a/snap/snapshotter.go +++ b/snap/snapshotter.go @@ -38,9 +38,10 @@ const ( ) var ( - ErrNoSnapshot = errors.New("snap: no available snapshot") - ErrCRCMismatch = errors.New("snap: crc mismatch") - crcTable = crc32.MakeTable(crc32.Castagnoli) + ErrNoSnapshot = errors.New("snap: no available snapshot") + ErrEmptySnapshot = errors.New("snap: empty snapshot") + ErrCRCMismatch = errors.New("snap: crc mismatch") + crcTable = crc32.MakeTable(crc32.Castagnoli) ) type Snapshotter struct { @@ -108,11 +109,16 @@ func loadSnap(dir, name string) (*raftpb.Snapshot, error) { log.Printf("snap: corrupted snapshot file %v: %v", name, err) return nil, err } + + if len(serializedSnap.Data) == 0 || serializedSnap.Crc == 0 { + log.Printf("snap: unexpected empty snapshot") + return nil, ErrEmptySnapshot + } + crc := crc32.Update(0, crcTable, serializedSnap.Data) if crc != serializedSnap.Crc { log.Printf("snap: corrupted snapshot file %v: crc mismatch", name) - err = ErrCRCMismatch - return nil, err + return nil, ErrCRCMismatch } var snap raftpb.Snapshot diff --git a/snap/snapshotter_test.go b/snap/snapshotter_test.go index 6998d62e9..0020eb1f5 100644 --- a/snap/snapshotter_test.go +++ b/snap/snapshotter_test.go @@ -188,3 +188,23 @@ func TestNoSnapshot(t *testing.T) { t.Errorf("err = %v, want %v", err, ErrNoSnapshot) } } + +func TestEmptySnapshot(t *testing.T) { + dir := path.Join(os.TempDir(), "snapshot") + err := os.Mkdir(dir, 0700) + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(dir) + + err = ioutil.WriteFile(path.Join(dir, "1.snap"), []byte("shit"), 0x700) + if err != nil { + t.Fatal(err) + } + + ss := New(dir) + _, err = ss.Load() + if err == nil || err != ErrEmptySnapshot { + t.Errorf("err = %v, want %v", err, ErrEmptySnapshot) + } +}