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
View File
@@ -156,6 +156,11 @@ func (r *Resolver) extract(ctx context.Context, format archives.Extractor, conte
r.truncate("extraction stopped: the archive and those nested in it decompressed to far more than its size (possible decompression bomb)")
return nil
}
if err != nil && ctx.Err() == nil && len(r.files) > 0 {
// the stream broke partway (a truncated .tar.gz); what was read before that is still good
r.truncate(fmt.Sprintf("extraction stopped early: %v", err))
return nil
}
return err
}