Skip to content

Commit

Permalink
snapshot: read meta.json correctly. (#5193)
Browse files Browse the repository at this point in the history
* snapshot: read meta.json correctly.

Fixes #4452.
  • Loading branch information
hanshasselberg committed Jan 8, 2019
1 parent 9f33353 commit 0fc1c20
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 2 deletions.
16 changes: 14 additions & 2 deletions snapshot/archive.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"fmt"
"hash"
"io"
"io/ioutil"
"time"

"github.com/hashicorp/raft"
Expand Down Expand Up @@ -193,8 +194,19 @@ func read(in io.Reader, metadata *raft.SnapshotMeta, snap io.Writer) error {

switch hdr.Name {
case "meta.json":
dec := json.NewDecoder(io.TeeReader(archive, metaHash))
if err := dec.Decode(&metadata); err != nil {
// Previously we used json.Decode to decode the archive stream. There are
// edgecases in which it doesn't read all the bytes from the stream, even
// though the json object is still being parsed properly. Since we
// simutaniously feeded everything to metaHash, our hash ended up being
// different than what we calculated when creating the snapshot. Which in
// turn made the snapshot verification fail. By explicitly reading the
// whole thing first we ensure that we calculate the correct hash
// independent of how json.Decode works internally.
buf, err := ioutil.ReadAll(io.TeeReader(archive, metaHash))
if err != nil {
return fmt.Errorf("failed to read snapshot metadata: %v", err)
}
if err := json.Unmarshal(buf, &metadata); err != nil {
return fmt.Errorf("failed to decode snapshot metadata: %v", err)
}

Expand Down
19 changes: 19 additions & 0 deletions snapshot/archive_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,25 @@ func TestArchive(t *testing.T) {
}
}

func TestArchive_GoodData(t *testing.T) {
paths := []string{
"../test/snapshot/spaces-meta.tar",
}
for i, p := range paths {
f, err := os.Open(p)
if err != nil {
t.Fatalf("err: %v", err)
}
defer f.Close()

var metadata raft.SnapshotMeta
err = read(f, &metadata, ioutil.Discard)
if err != nil {
t.Fatalf("case %d: should've read the snapshot, but didn't: %v", i, err)
}
}
}

func TestArchive_BadData(t *testing.T) {
cases := []struct {
Name string
Expand Down
Binary file added test/snapshot/spaces-meta.tar
Binary file not shown.

0 comments on commit 0fc1c20

Please sign in to comment.