diff options
Diffstat (limited to 'format/packfile/ingest/trailer.go')
| -rw-r--r-- | format/packfile/ingest/trailer.go | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/format/packfile/ingest/trailer.go b/format/packfile/ingest/trailer.go new file mode 100644 index 00000000..7a26a8f2 --- /dev/null +++ b/format/packfile/ingest/trailer.go @@ -0,0 +1,58 @@ +package ingest + +import ( + "bytes" + "errors" + "fmt" + "io" +) + +// finishAndFlushTrailer reads trailer hash bytes, verifies trailer checksum, +// and optionally requires the source stream to hit EOF afterward. +func (scanner *streamScanner) finishAndFlushTrailer(requireTrailingEOF bool) error { + if scanner.hashSize <= 0 { + return fmt.Errorf("packfile/ingest: invalid hash size") + } + + trailer := make([]byte, scanner.hashSize) + + scanner.hashEnabled = false + + err := scanner.readFull(trailer) + if err != nil { + return &PackTrailerMismatchError{} + } + + scanner.packTrailer = append(scanner.packTrailer[:0], trailer...) + + if scanner.n-scanner.off > 0 { + return fmt.Errorf("packfile/ingest: pack has trailing garbage") + } + + if !requireTrailingEOF { + computed := scanner.hash.Sum(nil) + if !bytes.Equal(computed, trailer) { + return &PackTrailerMismatchError{} + } + + return nil + } + + var probe [1]byte + + n, err := scanner.Read(probe[:]) + if n > 0 || err == nil { + return fmt.Errorf("packfile/ingest: pack has trailing garbage") + } + + if !errors.Is(err, io.EOF) { + return err + } + + computed := scanner.hash.Sum(nil) + if !bytes.Equal(computed, trailer) { + return &PackTrailerMismatchError{} + } + + return nil +} |
