diff options
| author | 2026-03-28 16:13:55 +0000 | |
|---|---|---|
| committer | 2026-03-28 16:13:55 +0000 | |
| commit | d3cfc1932e71994ec866f6bea67615c58878f952 (patch) | |
| tree | b2e05e30b4b84423d51bd2a9dbdd49cea257062e /object/store/packed | |
| parent | object/store: Document writing interface lack (diff) | |
| signature | No signature | |
object/store/packed: Expect length and verify Adler-32
Diffstat (limited to 'object/store/packed')
| -rw-r--r-- | object/store/packed/entry_inflate.go | 9 | ||||
| -rw-r--r-- | object/store/packed/read_bytes.go | 8 |
2 files changed, 17 insertions, 0 deletions
diff --git a/object/store/packed/entry_inflate.go b/object/store/packed/entry_inflate.go index 1c3943e9..f79d86c0 100644 --- a/object/store/packed/entry_inflate.go +++ b/object/store/packed/entry_inflate.go @@ -7,6 +7,7 @@ import ( "math" "codeberg.org/lindenii/furgit/internal/compress/zlib" + "codeberg.org/lindenii/furgit/internal/iolimit" ) // zlibReaderAt opens a zlib reader starting at data offset within pack. @@ -36,6 +37,7 @@ func inflateAt(pack *packFile, offset int, expectedSize int64) ([]byte, error) { ) } + reader := iolimit.ExpectLengthReader(reader, expectedSize) body := make([]byte, int(expectedSize)) _, err := io.ReadFull(reader, body) @@ -43,6 +45,13 @@ func inflateAt(pack *packFile, offset int, expectedSize int64) ([]byte, error) { return nil, err } + var probe [1]byte + + _, err = reader.Read(probe[:]) + if err != nil && err != io.EOF { + return nil, err + } + return body, nil } diff --git a/object/store/packed/read_bytes.go b/object/store/packed/read_bytes.go index 333cfaae..98ae6995 100644 --- a/object/store/packed/read_bytes.go +++ b/object/store/packed/read_bytes.go @@ -9,6 +9,10 @@ import ( ) // ReadBytesContent reads an object's type and content bytes. +// +// It fully resolves the requested object bytes. For base pack entries, this +// includes verifying that the zlib stream inflates to exactly the declared +// object size and reaches its Adler-32 trailer. func (store *Store) ReadBytesContent(id objectid.ObjectID) (objecttype.Type, []byte, error) { loc, err := store.lookup(id) if err != nil { @@ -19,6 +23,10 @@ func (store *Store) ReadBytesContent(id objectid.ObjectID) (objecttype.Type, []b } // ReadBytesFull reads a full serialized object as "type size\0content". +// +// Like ReadBytesContent, it fully resolves the requested object bytes. For +// base pack entries, this includes verifying that the zlib stream inflates to +// exactly the declared object size and reaches its Adler-32 trailer. func (store *Store) ReadBytesFull(id objectid.ObjectID) ([]byte, error) { ty, content, err := store.ReadBytesContent(id) if err != nil { |
