diff options
| -rw-r--r-- | objectstore/loose/parse.go | 12 | ||||
| -rw-r--r-- | objectstore/loose/read_header.go | 2 | ||||
| -rw-r--r-- | objectstore/loose/read_reader.go | 27 | ||||
| -rw-r--r-- | objectstore/packed/read_reader.go | 5 |
4 files changed, 30 insertions, 16 deletions
diff --git a/objectstore/loose/parse.go b/objectstore/loose/parse.go index fc678262..4021e333 100644 --- a/objectstore/loose/parse.go +++ b/objectstore/loose/parse.go @@ -34,16 +34,16 @@ func parseRaw(raw []byte) (objecttype.Type, []byte, error) { return ty, content, nil } -// readHeader reads and parses a loose object header from br. -// br must be positioned at the start of decoded loose object bytes. -func readHeader(br *bufio.Reader) (objecttype.Type, int64, error) { +// readHeader reads and parses a loose object header from br, and returns +// the raw header bytes including the trailing NUL. +func readHeader(br *bufio.Reader) ([]byte, objecttype.Type, int64, error) { header, err := br.ReadSlice(0) if err != nil { - return objecttype.TypeInvalid, 0, err + return nil, objecttype.TypeInvalid, 0, err } ty, size, _, ok := objectheader.Parse(header) if !ok { - return objecttype.TypeInvalid, 0, errors.New("objectstore/loose: malformed object header") + return nil, objecttype.TypeInvalid, 0, errors.New("objectstore/loose: malformed object header") } - return ty, size, nil + return header, ty, size, nil } diff --git a/objectstore/loose/read_header.go b/objectstore/loose/read_header.go index 0fa587fc..e6db30cd 100644 --- a/objectstore/loose/read_header.go +++ b/objectstore/loose/read_header.go @@ -22,7 +22,7 @@ func (store *Store) ReadHeader(id objectid.ObjectID) (objecttype.Type, int64, er } defer func() { _ = zr.Close() }() - ty, size, err := readHeader(bufio.NewReader(zr)) + _, ty, size, err := readHeader(bufio.NewReader(zr)) if err != nil { return objecttype.TypeInvalid, 0, err } diff --git a/objectstore/loose/read_reader.go b/objectstore/loose/read_reader.go index dde0de07..68df820d 100644 --- a/objectstore/loose/read_reader.go +++ b/objectstore/loose/read_reader.go @@ -2,18 +2,19 @@ package loose import ( "bufio" + "bytes" "compress/zlib" "errors" "io" "os" + "codeberg.org/lindenii/furgit/internal/iolimit" "codeberg.org/lindenii/furgit/objectid" "codeberg.org/lindenii/furgit/objecttype" ) type objectReader struct { - // reader is the stream exposed by Read. It may be the raw zlib reader - // (full object) or a buffered reader positioned at content bytes only. + // reader is the stream exposed by Read. reader io.Reader // file is the underlying loose object file and is closed by Close. file *os.File @@ -53,10 +54,22 @@ func (store *Store) ReadReaderFull(id objectid.ObjectID) (io.ReadCloser, error) if err != nil { return nil, err } + + br := bufio.NewReader(zr) + header, _, size, err := readHeader(br) + if err != nil { + _ = zr.Close() + _ = file.Close() + return nil, err + } + return &objectReader{ - reader: zr, - file: file, - zr: zr, + reader: io.MultiReader( + bytes.NewReader(header), + iolimit.ExpectLengthReader(br, size), + ), + file: file, + zr: zr, }, nil } @@ -69,7 +82,7 @@ func (store *Store) ReadReaderContent(id objectid.ObjectID) (objecttype.Type, in } br := bufio.NewReader(zr) - ty, size, err := readHeader(br) + _, ty, size, err := readHeader(br) if err != nil { _ = zr.Close() _ = file.Close() @@ -77,7 +90,7 @@ func (store *Store) ReadReaderContent(id objectid.ObjectID) (objecttype.Type, in } return ty, size, &objectReader{ - reader: br, + reader: iolimit.ExpectLengthReader(br, size), file: file, zr: zr, }, nil diff --git a/objectstore/packed/read_reader.go b/objectstore/packed/read_reader.go index 4f40792d..bcafe975 100644 --- a/objectstore/packed/read_reader.go +++ b/objectstore/packed/read_reader.go @@ -5,6 +5,7 @@ import ( "fmt" "io" + "codeberg.org/lindenii/furgit/internal/iolimit" "codeberg.org/lindenii/furgit/objectheader" "codeberg.org/lindenii/furgit/objectid" "codeberg.org/lindenii/furgit/objecttype" @@ -45,7 +46,7 @@ func (store *Store) ReadReaderContent(id objectid.ObjectID) (objecttype.Type, in return objecttype.TypeInvalid, 0, nil, err } return meta.ty, meta.size, &readCloser{ - reader: io.LimitReader(zr, meta.size), + reader: iolimit.ExpectLengthReader(zr, meta.size), closer: zr, }, nil } @@ -80,7 +81,7 @@ func (store *Store) ReadReaderFull(id objectid.ObjectID) (io.ReadCloser, error) return nil, err } return &readCloser{ - reader: io.MultiReader(bytes.NewReader(header), io.LimitReader(zr, meta.size)), + reader: io.MultiReader(bytes.NewReader(header), iolimit.ExpectLengthReader(zr, meta.size)), closer: zr, }, nil } |
