From daca6d0eb76a7fc8134de35ddb7a4a1d0e184e0c Mon Sep 17 00:00:00 2001 From: Runxi Yu Date: Thu, 29 Jan 2026 20:33:59 +0100 Subject: zlibx: Make DecompressSized return the number of bytes consumed --- internal/zlibx/decompress.go | 21 +++++++++++---------- internal/zlibx/decompress_test.go | 2 +- packed_read_pack.go | 2 +- packed_write_test.go | 37 ++++--------------------------------- 4 files changed, 17 insertions(+), 45 deletions(-) diff --git a/internal/zlibx/decompress.go b/internal/zlibx/decompress.go index 23fae8fa..6bb5d45c 100644 --- a/internal/zlibx/decompress.go +++ b/internal/zlibx/decompress.go @@ -10,44 +10,45 @@ import ( ) 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 } diff --git a/internal/zlibx/decompress_test.go b/internal/zlibx/decompress_test.go index 2b9f0672..bea348d2 100644 --- a/internal/zlibx/decompress_test.go +++ b/internal/zlibx/decompress_test.go @@ -155,7 +155,7 @@ func TestDecompressSizedUsesHint(t *testing.T) { 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) } diff --git a/packed_read_pack.go b/packed_read_pack.go index 593fe97f..31279c8f 100644 --- a/packed_read_pack.go +++ b/packed_read_pack.go @@ -97,7 +97,7 @@ func packSectionInflate(pf *packFile, start uint64, sizeHint int) (bufpool.Buffe 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 } diff --git a/packed_write_test.go b/packed_write_test.go index 08f4484b..63fd9266 100644 --- a/packed_write_test.go +++ b/packed_write_test.go @@ -10,9 +10,8 @@ import ( "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 @@ func checkPackStream(path string, algo hashAlgorithm, objectCount int) error { 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: @@ -492,36 +493,6 @@ func checkPackStream(path string, algo hashAlgorithm, objectCount int) error { 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) { pos := 0 baseSize, err := packVarintRead(delta, &pos) -- cgit v1.3.1-10-gc9f91