diff options
Diffstat (limited to 'objects')
-rw-r--r-- | objects/object_snapshot.go | 64 | ||||
-rw-r--r-- | objects/object_snapshot_test.go | 15 |
2 files changed, 63 insertions, 16 deletions
diff --git a/objects/object_snapshot.go b/objects/object_snapshot.go index 18a534f..59c7121 100644 --- a/objects/object_snapshot.go +++ b/objects/object_snapshot.go @@ -9,11 +9,20 @@ import ( "time" ) +const ( + snapshot_start_marker = "== BEGIN SNAPSHOT ==" + snapshot_end_marker = "== END SNAPSHOT ==" + + snapshot_start_line = snapshot_start_marker + "\n" + snapshot_end_line = snapshot_end_marker + "\n" +) + type Snapshot struct { Tree ObjectId Date time.Time Archive string Comment string + Signed bool } func (s Snapshot) Type() ObjectType { @@ -29,14 +38,26 @@ func appendKVPair(b []byte, k, v string) []byte { } func (s Snapshot) Payload() (out []byte) { + out = append(out, []byte(snapshot_start_line)...) out = appendKVPair(out, "archive", s.Archive) out = appendKVPair(out, "date", s.Date.Format(time.RFC3339)) + if s.Signed { + out = appendKVPair(out, "signed", "yes") + } out = appendKVPair(out, "tree", s.Tree.String()) if s.Comment != "" { + // We must prevent that the comment includes an end marker + comment := strings.Replace(s.Comment, snapshot_end_marker, "~~ END SNAPSHOT ~~", -1) + + if comment[len(comment)-1] != '\n' { + comment += "\n" + } + out = append(out, '\n') - out = append(out, []byte(s.Comment)...) + out = append(out, []byte(comment)...) } + out = append(out, []byte(snapshot_end_line)...) return out } @@ -48,15 +69,39 @@ func (s *Snapshot) FromPayload(payload []byte) error { seenDate := false seenTree := false + start := false + terminated := false + comment := false + for { line, err := r.ReadString('\n') if err != nil && err != io.EOF { return err + } else if err == io.EOF { + break } + line = strings.TrimSpace(line) + if !start { + if line == snapshot_start_marker { + start = true + } + continue + } + + if line == snapshot_end_marker { + terminated = true + break + } + + if comment { + s.Comment += line + "\n" + continue + } if line == "" { - break // Header read successfully + comment = true + continue } parts := strings.SplitN(line, " ", 2) @@ -76,6 +121,8 @@ func (s *Snapshot) FromPayload(payload []byte) error { } s.Date = d seenDate = true + case "signed": + s.Signed = headerval == "yes" case "tree": oid, err := ParseObjectId(headerval) if err != nil { @@ -84,22 +131,17 @@ func (s *Snapshot) FromPayload(payload []byte) error { s.Tree = oid seenTree = true } + } - if err == io.EOF { - break - } + if !terminated { + return errors.New("The snapshot was not properly terminated") } if !seenArchive || !seenDate || !seenTree { return errors.New("Missing archive, date or tree header") } - b := new(bytes.Buffer) - if _, err := io.Copy(b, r); err != nil { - return err - } - - s.Comment = strings.TrimSpace(string(b.Bytes())) + s.Comment = strings.TrimSpace(s.Comment) return nil } diff --git a/objects/object_snapshot_test.go b/objects/object_snapshot_test.go index df150de..d62c78a 100644 --- a/objects/object_snapshot_test.go +++ b/objects/object_snapshot_test.go @@ -11,17 +11,21 @@ var ( Archive: "foo", Comment: "foo\nbar\nbaz!", Date: time.Date(2017, 07, 01, 21, 40, 00, 0, time.FixedZone("", 2*60*60)), + Signed: true, Tree: genId(0xff), } testSnapshotSerialization = []byte("" + + "== BEGIN SNAPSHOT ==\n" + "archive foo\n" + "date 2017-07-01T21:40:00+02:00\n" + + "signed yes\n" + "tree sha3-256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + "\n" + "foo\n" + "bar\n" + - "baz!") + "baz!\n" + + "== END SNAPSHOT ==\n") ) func TestSerializeSnapshot(t *testing.T) { @@ -46,10 +50,11 @@ func TestUnserializeSnapshot(t *testing.T) { func TestUnserializeSnapshotFailure(t *testing.T) { subtests := []struct{ name, payload string }{ {"empty", ""}, - {"missing tree", "archive foo\ndate 2017-07-01T22:02:00+02:00\n"}, - {"missing archive", "date 2017-07-01T22:02:00+02:00\ntree sha3-256:0000000000000000000000000000000000000000000000000000000000000000\n"}, - {"missing date", "archive foo\ntree sha3-256:0000000000000000000000000000000000000000000000000000000000000000\n"}, - {"invalid date", "archive foo\ndate foobar\ntree sha3-256:0000000000000000000000000000000000000000000000000000000000000000\n"}, + {"missing tree", snapshot_start_line + "archive foo\ndate 2017-07-01T22:02:00+02:00\n" + snapshot_end_line}, + {"missing archive", snapshot_start_line + "date 2017-07-01T22:02:00+02:00\ntree sha3-256:0000000000000000000000000000000000000000000000000000000000000000\n" + snapshot_end_line}, + {"missing date", snapshot_start_line + "archive foo\ntree sha3-256:0000000000000000000000000000000000000000000000000000000000000000\n" + snapshot_end_line}, + {"invalid date", snapshot_start_line + "archive foo\ndate foobar\ntree sha3-256:0000000000000000000000000000000000000000000000000000000000000000\n" + snapshot_end_line}, + {"End marker missing", snapshot_start_line + "archive foo\ndate 2017-07-01T22:02:00+02:00\ntree sha3-256:0000000000000000000000000000000000000000000000000000000000000000\n"}, } for _, subtest := range subtests { |