snapshot: read meta.json correctly. (#5193)
* snapshot: read meta.json correctly. Fixes #4452.
This commit is contained in:
parent
7b1bd33add
commit
08502cfa61
|
@ -18,6 +18,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"hash"
|
"hash"
|
||||||
"io"
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/hashicorp/raft"
|
"github.com/hashicorp/raft"
|
||||||
|
@ -193,8 +194,19 @@ func read(in io.Reader, metadata *raft.SnapshotMeta, snap io.Writer) error {
|
||||||
|
|
||||||
switch hdr.Name {
|
switch hdr.Name {
|
||||||
case "meta.json":
|
case "meta.json":
|
||||||
dec := json.NewDecoder(io.TeeReader(archive, metaHash))
|
// Previously we used json.Decode to decode the archive stream. There are
|
||||||
if err := dec.Decode(&metadata); err != nil {
|
// 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)
|
return fmt.Errorf("failed to decode snapshot metadata: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
func TestArchive_BadData(t *testing.T) {
|
||||||
cases := []struct {
|
cases := []struct {
|
||||||
Name string
|
Name string
|
||||||
|
|
Binary file not shown.
Loading…
Reference in New Issue