diff options
| author | 2026-02-22 10:28:29 +0800 | |
|---|---|---|
| committer | 2026-02-22 10:28:29 +0800 | |
| commit | 918a17362c8a07221a65d4d60af0667ee7f0dd61 (patch) | |
| tree | 64bf9e1c95d3cec54e732e0d8a047550fd5365fe | |
| parent | objectstore/packed: Pre-allocate instead of ReadAll (diff) | |
| signature | No signature | |
format/delta/apply, etc.: ReadHeaderSizes should use ByteReader
| -rw-r--r-- | format/delta/apply/header.go | 53 | ||||
| -rw-r--r-- | objectstore/packed/delta_plan.go | 4 |
2 files changed, 26 insertions, 31 deletions
diff --git a/format/delta/apply/header.go b/format/delta/apply/header.go index f6aadea3..996b006b 100644 --- a/format/delta/apply/header.go +++ b/format/delta/apply/header.go @@ -6,44 +6,37 @@ import ( ) // ReadHeaderSizes reads the first two varints in one inflated delta stream. -func ReadHeaderSizes(reader io.Reader) (int, int, error) { - // Two Git varints are read here. Each can take up to 10 bytes. - var buf [20]byte - n := 0 - - for { - if n >= len(buf) { - return 0, 0, fmt.Errorf("format/delta/apply: malformed delta varint") - } - if _, err := io.ReadFull(reader, buf[n:n+1]); err != nil { - return 0, 0, fmt.Errorf("format/delta/apply: malformed delta varint: %w", err) - } - n++ - if buf[n-1]&0x80 == 0 { - break - } +// +// Callers that continue reading the same stream should pass their own buffered +// byte reader and keep using that same reader afterwards. +func ReadHeaderSizes(reader io.ByteReader) (int, int, error) { + srcSize, err := readVarintFromByteReader(reader) + if err != nil { + return 0, 0, err } - pos := 0 - srcSize, err := readVarint(buf[:n], &pos) + dstSize, err := readVarintFromByteReader(reader) if err != nil { return 0, 0, err } + return srcSize, dstSize, nil +} +// readVarintFromByteReader parses one Git delta varint from reader. +func readVarintFromByteReader(reader io.ByteReader) (int, error) { + value := 0 + shift := uint(0) for { - if n >= len(buf) { - return 0, 0, fmt.Errorf("format/delta/apply: malformed delta varint") + b, err := reader.ReadByte() + if err != nil { + return 0, fmt.Errorf("format/delta/apply: malformed delta varint: %w", err) } - if _, err := io.ReadFull(reader, buf[n:n+1]); err != nil { - return 0, 0, fmt.Errorf("format/delta/apply: malformed delta varint: %w", err) + value |= int(b&0x7f) << shift + if b&0x80 == 0 { + return value, nil } - n++ - if buf[n-1]&0x80 == 0 { - break + shift += 7 + if shift > 63 { + return 0, fmt.Errorf("format/delta/apply: delta varint overflow") } } - dstSize, err := readVarint(buf[:n], &pos) - if err != nil { - return 0, 0, err - } - return srcSize, dstSize, nil } diff --git a/objectstore/packed/delta_plan.go b/objectstore/packed/delta_plan.go index 05c4b714..5f2ae959 100644 --- a/objectstore/packed/delta_plan.go +++ b/objectstore/packed/delta_plan.go @@ -1,6 +1,7 @@ package packed import ( + "bufio" "fmt" deltaapply "codeberg.org/lindenii/furgit/format/delta/apply" @@ -89,7 +90,8 @@ func deltaDeclaredSizeAt(pack *packFile, dataOffset int) (int64, error) { } defer func() { _ = reader.Close() }() - _, size, err := deltaapply.ReadHeaderSizes(reader) + br := bufio.NewReaderSize(reader, 32) + _, size, err := deltaapply.ReadHeaderSizes(br) if err != nil { return 0, err } |
