shithub: furgit

Download patch

ref: daca6d0eb76a7fc8134de35ddb7a4a1d0e184e0c
parent: 2b87aa39ab9d19cb93a087f0cf6641334d103048
author: Runxi Yu <me@runxiyu.org>
date: Thu Jan 29 15:33:59 EST 2026

zlibx: Make DecompressSized return the number of bytes consumed

--- a/internal/zlibx/decompress.go
+++ b/internal/zlibx/decompress.go
@@ -10,44 +10,45 @@
 )
 
 func Decompress(src []byte) (bufpool.Buffer, error) {
-	return DecompressSized(src, 0)
+	out, _, err := DecompressSized(src, 0)
+	return out, err
 }
 
-func DecompressSized(src []byte, sizeHint int) (bufpool.Buffer, error) {
+func DecompressSized(src []byte, sizeHint int) (bufpool.Buffer, int, error) {
 	if len(src) < 6 {
-		return bufpool.Buffer{}, io.ErrUnexpectedEOF
+		return bufpool.Buffer{}, 0, io.ErrUnexpectedEOF
 	}
 
 	cmf := src[0]
 	flg := src[1]
 	if (cmf&0x0f != zlibDeflate) || (cmf>>4 > zlibMaxWindow) || (binary.BigEndian.Uint16(src[:2])%31 != 0) {
-		return bufpool.Buffer{}, ErrHeader
+		return bufpool.Buffer{}, 0, ErrHeader
 	}
 
 	offset := 2
 	if flg&0x20 != 0 {
-		return bufpool.Buffer{}, ErrHeader
+		return bufpool.Buffer{}, 0, ErrHeader
 	}
 
 	if len(src[offset:]) < 4 {
-		return bufpool.Buffer{}, io.ErrUnexpectedEOF
+		return bufpool.Buffer{}, 0, io.ErrUnexpectedEOF
 	}
 
 	deflateData := src[offset:]
 	out, consumed, err := flatex.DecompressSized(deflateData, sizeHint)
 	if err != nil {
-		return bufpool.Buffer{}, err
+		return bufpool.Buffer{}, 0, err
 	}
 
 	checksumPos := offset + consumed
 	if checksumPos+4 > len(src) {
 		out.Release()
-		return bufpool.Buffer{}, io.ErrUnexpectedEOF
+		return bufpool.Buffer{}, 0, io.ErrUnexpectedEOF
 	}
 	expected := binary.BigEndian.Uint32(src[checksumPos : checksumPos+4])
 	if expected != adler32.Checksum(out.Bytes()) {
 		out.Release()
-		return bufpool.Buffer{}, ErrChecksum
+		return bufpool.Buffer{}, 0, ErrChecksum
 	}
-	return out, nil
+	return out, checksumPos + 4, nil
 }
--- a/internal/zlibx/decompress_test.go
+++ b/internal/zlibx/decompress_test.go
@@ -155,7 +155,7 @@
 	compressed := compressZlib(t, payload)
 
 	const hint = 1 << 20
-	out, err := DecompressSized(compressed, hint)
+	out, _, err := DecompressSized(compressed, hint)
 	if err != nil {
 		t.Fatalf("DecompressSized: %v", err)
 	}
--- a/packed_read_pack.go
+++ b/packed_read_pack.go
@@ -97,7 +97,7 @@
 	if start > uint64(len(pf.data)) {
 		return bufpool.Buffer{}, ErrInvalidObject
 	}
-	body, err := zlibx.DecompressSized(pf.data[start:], sizeHint)
+	body, _, err := zlibx.DecompressSized(pf.data[start:], sizeHint)
 	if err != nil {
 		return bufpool.Buffer{}, err
 	}
--- a/packed_write_test.go
+++ b/packed_write_test.go
@@ -10,9 +10,8 @@
 	"strings"
 	"testing"
 
-	"codeberg.org/lindenii/furgit/internal/adler32"
 	"codeberg.org/lindenii/furgit/internal/bufpool"
-	"codeberg.org/lindenii/furgit/internal/flatex"
+	"codeberg.org/lindenii/furgit/internal/zlibx"
 )
 
 func TestPackHeaderEncodeParseRoundtrip(t *testing.T) {
@@ -422,10 +421,12 @@
 		default:
 		}
 
-		payload, zconsumed, err := consumeZlibStream(data[pos:], size)
+		payloadBuf, zconsumed, err := zlibx.DecompressSized(data[pos:], size)
 		if err != nil {
 			return fmt.Errorf("obj %d zlib at %d: %v", i, pos, err)
 		}
+		payload := append([]byte(nil), payloadBuf.Bytes()...)
+		payloadBuf.Release()
 		pos += zconsumed
 		switch ty {
 		case ObjectTypeOfsDelta:
@@ -490,36 +491,6 @@
 		}
 	}
 	return nil
-}
-
-func consumeZlibStream(src []byte, sizeHint int) ([]byte, int, error) {
-	if len(src) < 6 {
-		return nil, 0, fmt.Errorf("zlib too short")
-	}
-	cmf := src[0]
-	flg := src[1]
-	if (cmf&0x0f != 8) || (cmf>>4 > 7) || (uint16(cmf)<<8|uint16(flg))%31 != 0 {
-		return nil, 0, fmt.Errorf("zlib header invalid")
-	}
-	if flg&0x20 != 0 {
-		return nil, 0, fmt.Errorf("zlib dict not supported")
-	}
-	deflateData := src[2:]
-	out, consumed, err := flatex.DecompressSized(deflateData, sizeHint)
-	if err != nil {
-		return nil, 0, err
-	}
-	payload := append([]byte(nil), out.Bytes()...)
-	out.Release()
-	total := 2 + consumed + 4
-	if total > len(src) {
-		return nil, 0, fmt.Errorf("zlib truncated")
-	}
-	expected := readBE32(src[2+consumed : 2+consumed+4])
-	if expected != adler32.Checksum(payload) {
-		return nil, 0, fmt.Errorf("zlib checksum mismatch")
-	}
-	return payload, total, nil
 }
 
 func readDeltaSizes(delta []byte) (int, int, error) {
--