diff options
| author | 2026-02-21 03:57:20 +0800 | |
|---|---|---|
| committer | 2026-02-21 03:57:20 +0800 | |
| commit | eeadac1851149248e788579cc83b925c27c2a8e1 (patch) | |
| tree | 16e96a0d9d344e4f728d7759006b846cf95af688 | |
| parent | objectstore: Clarify the hash contract in ReadBytesFull (diff) | |
| signature | No signature | |
objectstore/loose: Verify the length where possible.
| -rw-r--r-- | objectstore/loose/parse.go | 8 | ||||
| -rw-r--r-- | objectstore/loose/read_bytes.go | 11 |
2 files changed, 15 insertions, 4 deletions
diff --git a/objectstore/loose/parse.go b/objectstore/loose/parse.go index 30c7e251..fc678262 100644 --- a/objectstore/loose/parse.go +++ b/objectstore/loose/parse.go @@ -23,11 +23,15 @@ func decodeAll(file *os.File) ([]byte, error) { // parseRaw parses a loose object payload in "type size\0content" format. func parseRaw(raw []byte) (objecttype.Type, []byte, error) { - ty, _, headerLen, ok := objectheader.Parse(raw) + ty, size, headerLen, ok := objectheader.Parse(raw) if !ok { return objecttype.TypeInvalid, nil, errors.New("objectstore/loose: malformed object header") } - return ty, raw[headerLen:], nil + content := raw[headerLen:] + if int64(len(content)) != size { + return objecttype.TypeInvalid, nil, errors.New("objectstore/loose: object header size/content mismatch") + } + return ty, content, nil } // readHeader reads and parses a loose object header from br. diff --git a/objectstore/loose/read_bytes.go b/objectstore/loose/read_bytes.go index 4d1cb439..80350809 100644 --- a/objectstore/loose/read_bytes.go +++ b/objectstore/loose/read_bytes.go @@ -12,7 +12,14 @@ func (store *Store) ReadBytesFull(id objectid.ObjectID) ([]byte, error) { return nil, err } defer func() { _ = file.Close() }() - return decodeAll(file) + raw, err := decodeAll(file) + if err != nil { + return nil, err + } + if _, _, err := parseRaw(raw); err != nil { + return nil, err + } + return raw, nil } // ReadBytesContent reads an object's type and content bytes. @@ -21,7 +28,7 @@ func (store *Store) ReadBytesContent(id objectid.ObjectID) (objecttype.Type, []b if err != nil { return objecttype.TypeInvalid, nil, err } - ty, content, err := parseRaw(raw) + ty, content, err := parseRaw(raw) // Just for the size check. if err != nil { return objecttype.TypeInvalid, nil, err } |
