Skip to content

plumbing: format/packfile, harden malformed pack handling#2113

Merged
pjbgf merged 4 commits into
mainfrom
validation2
May 18, 2026
Merged

plumbing: format/packfile, harden malformed pack handling#2113
pjbgf merged 4 commits into
mainfrom
validation2

Conversation

@pjbgf

@pjbgf pjbgf commented May 12, 2026

Copy link
Copy Markdown
Member

This PR hardens packfile parsing and iteration against malformed or adversarial pack data.

  • Propagates objectFromHeader errors from packfile iteration so delta resolution failures are returned to callers instead of being masked or risking nil dereferences.
  • Rejects Git’s reserved object type 5 explicitly in ObjectType.Valid, causing malformed pack entries to fail with ErrMalformedPackfile.
  • Enforces Git’s delta chain depth ceiling of 4095 before resolving delta content.

Copilot AI review requested due to automatic review settings May 12, 2026 09:48
hiddeco
hiddeco previously approved these changes May 12, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens packfile parsing/iteration against malformed or adversarial pack data, aiming to surface delta/iteration failures to callers and reject malformed pack entries earlier/safer.

Changes:

  • Tightens object-type validation (explicitly rejecting Git’s reserved type 5).
  • Adds stricter object inflation bounds (declared size + 1 byte) and rejects oversized/overflowing sizes during scan/parse.
  • Enforces a delta chain depth ceiling (4095) and propagates delta resolution errors during iteration.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
plumbing/object.go Makes ObjectType.Valid() explicitly whitelist valid object types (reject reserved type 5).
plumbing/format/packfile/scanner.go Adds copyObjectContent size enforcement; updates inflation paths to use declared size; adds size overflow rejection.
plumbing/format/packfile/parser.go Uses size-bounded inflation, adds max delta chain depth enforcement, and reuses copyObjectContent.
plumbing/format/packfile/packfile.go Propagates scanner errors from headerFromOffset; uses size-bounded inflation in object retrieval.
plumbing/format/packfile/packfile_iter.go Propagates objectFromHeader errors when iterating deltas (avoids masking failures).
plumbing/format/packfile/testpack_internal_test.go Adds internal test helpers to construct minimal packfiles with controlled malformations.
plumbing/format/packfile/scanner_test.go Adds tests for reserved object type rejection and oversized inflation rejection.
plumbing/format/packfile/parser_internal_test.go Adds tests for delta chain depth ceiling and oversized inflation rejection in Parser.
plumbing/format/packfile/packfile_iter_test.go Adds tests for iterator behavior on malformed/missing-base deltas and oversized inflation.
plumbing/format/packfile/delta_test.go Adds a delta round-trip fuzz test to validate delta encode/decode application paths.

Comment thread plumbing/format/packfile/scanner.go Outdated
Comment thread plumbing/format/packfile/scanner.go
Comment thread plumbing/format/packfile/packfile_iter_test.go Outdated
pjbgf added 4 commits May 18, 2026 13:05
The delta branch of objectIter.next dereferenced the returned object
before checking the error, masking failures (and risking a nil
dereference) when delta resolution failed. Check err first and surface
it so callers see ErrObjectNotFound or ErrMalformedPackfile instead of
silently skipping the entry.

Assisted-by: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: Paulo Gomes <paulo@entire.io>
ObjectType.Valid used a range check that accepted type 5, which Git
reserves and never assigns. Switch to an explicit enumeration so the
scanner surfaces ErrMalformedPackfile on packs that carry the reserved
type instead of letting them through.

Assisted-by: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: Paulo Gomes <paulo@entire.io>
headerFromOffset treated a failed Scan as ErrObjectNotFound, hiding the
underlying scanner error (e.g. ErrMalformedPackfile, I/O errors) from
callers. Check scanner.Error() first so callers see the real reason
instead of a generic missing-object error.

Assisted-by: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: Paulo Gomes <paulo@entire.io>
A pack with a deeply chained delta sequence forced unbounded recursion
during parse, letting a malformed input drive arbitrary stack growth.
Walk the parent chain in processDelta and reject anything beyond 4095
links — the same ceiling upstream Git enforces via OE_DEPTH_BITS in
pack-objects.h — surfacing ErrMalformedPackfile.

Move the packfile_iter helpers into internal_test.go alongside the new
TestParserRejectsDeepDeltaChain coverage and drop the inflated-size
test that duplicates scanner_test.go's ErrInflatedSizeMismatch
coverage.

Assisted-by: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: Paulo Gomes <paulo@entire.io>
@pjbgf pjbgf merged commit d9a6983 into main May 18, 2026
19 checks passed
@pjbgf pjbgf deleted the validation2 branch May 18, 2026 13:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants