fix: a damaged entry truncates the archive instead of failing it

a read error while copying one entry (a zip CRC mismatch, a corrupt deflate stream) was returned from `add`. That aborted the walk, and `Extract` threw away every entry already stored. So a large war with one damaged, irrelevant entry produced zero packages with the feature on, while java's legacy path (which reads only the entries it needs) still cataloged it.

- a read error on one entry now drops that entry and marks the resolver truncated (`entry "x" could not be read: ...`), and the walk continues
- if the stream itself breaks partway (a truncated `.tar.gz`), whatever was read before the break is kept and the archive is truncated. With nothing read it is still an error, as before
- disk limit and decompression budget errors still stop the walk

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
This commit is contained in:
Alex Goodman
2026-09-24 13:28:53 -04:00
parent 14bae1a0d9
commit 0152e5b59c
4 changed files with 44 additions and 22 deletions
+5 -3
View File
@@ -167,10 +167,12 @@ func (r *Resolver) add(hdr tar.Header, content io.Reader) error {
r.truncate(fmt.Sprintf("an entry larger than %s was skipped", humanize.IBytes(uint64(maxEntryBytes))))
return nil
}
if !errors.Is(err, ErrDiskLimitReached) {
return fmt.Errorf("unable to read archive entry %q: %w", hdr.Name, err)
if errors.Is(err, ErrDiskLimitReached) || errors.Is(err, errBudgetSpent) {
return err
}
return err
// a damaged entry (a CRC mismatch, a corrupt deflate stream) costs only that entry
r.truncate(fmt.Sprintf("entry %q could not be read: %v", hdr.Name, err))
return nil
}
}