Commit Graph
10 Commits
Author SHA1 Message Date
Alex Goodman 27655c2be0 fix: bound archive recursion with a cycle guard and depth ceiling
a negative `MaxDepth` really was unbounded, and nothing noticed an archive nested inside a copy of itself. A zip quine at `-1` recursed until memory, disk or file descriptors ran out, running the full sub-pipeline at every level.

- the walk keeps a stack of the digests of the archives it's inside, and an archive identical to one of them is recorded as an unknown instead of being entered
- negative depth now stops at 16 levels (docs and CLI description updated)
- cancellation is checked between candidates, so a cancelled scan stops walking instead of finishing the archive tree

the three unknown-recording blocks in `processArchive` became a one-line helper to stay under `funlen`.

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2026-09-24 11:32:15 -04:00
Alex Goodman c9b4f9c085 fix: recover from panics while extracting an archive
sub-pipeline catalogers were already run under `runTaskSafely`, but extraction wasn't: the zip, tar and compressor decoders run on untrusted bytes, and a panic in one unwound the whole walk and failed `CreateSBOM` with "failed to run tasks".

- `processArchive` recovers and returns the panic (with its stack) as an error at the archive's coordinates, so it becomes an unknown and the sibling archives are still cataloged
- `Extract` now defers `Cleanup` on failure instead of calling it on each error path, so a panic no longer leaks the limiter charge or the spill file

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2026-09-24 11:28:26 -04:00
Alex Goodman f5bac4a026 fix: build ArchivePath from real paths, not access paths
each `ArchivePath` segment came from `loc.Path()`, so it was the link path when an archive was reached through a symlink and the real path otherwise. That depended on how discovery happened to find the archive. The package location said `store/3f9a1c` while the files inside the same jar were recorded under `...:app/lib/json-simple-1.1.1.jar`, so a consumer couldn't join a package to its files by prefix.

The chain for extracted files is now built from `RealPath`. `Traversal.Location` still carries the access path, so java's name check and `VirtualPath` metadata behave the same as before. The field comment and schema now say every segment has links resolved.

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2026-09-24 11:26:38 -04:00
Alex Goodman 5fc384dddb fix: keep the access path of archives discovered through a link
`discoverArchives` collects MIME hits first, and those are bare real paths. When the glob pass then found the same file through a symlink, it was dropped as a duplicate along with its access path. Java decides whether to describe an archive by its name, so a content-addressed jar (`store/3f9a1c`, linked from `lib/json-simple-1.1.1.jar`) was extracted but produced no package. This is the pnpm / nix / bazel layout.

When deduping, the candidate now takes the first location that carries an access path.

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2026-09-24 11:25:40 -04:00
Alex Goodman a4a1d7afa7 fix: treat zero archive limits as the default
`ArchiveSearchConfig{MaxDepth: 2}` is the natural literal, but zero memory and zero disk meant "forbid both", so every archive was truncated to nothing and only unknowns came out.

- `MaxMemoryBytes` / `MaxDiskBytes` of `0` now mean the default, negative is still unbounded
- the limiter keeps its own zero-forbids semantics internally; it's just no longer reachable from config
- tests that relied on zero to force spilling now pass `archive.Limits` directly, and the two "both limits zero" tests are gone since that config no longer exists

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2026-09-24 11:14:23 -04:00
Alex Goodman fe4a9a287a chore: use only the default title for archive progress
matches how the per-cataloger progress rows are titled (`Default` only), so the archive row reads like its siblings.

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2026-09-24 11:11:36 -04:00
Keith Zantow b36234cfe7 feat: simplify+improve resolver implementation / glob search
Signed-off-by: Keith Zantow <keith.zantow@anchore.com>
2026-09-22 11:32:30 -04:00
Keith Zantow 47cafae01b chore: simplify and cleanup
Signed-off-by: Keith Zantow <keith.zantow@anchore.com>
2026-09-22 00:23:36 -04:00
Keith Zantow 53cd4254e4 chore: revert custom index in favor of key_Split
Signed-off-by: Keith Zantow <keith.zantow@anchore.com>
2026-09-20 11:22:10 -04:00
Keith Zantow 8c0d3747ce feat: initial recursive archive cataloging impl
Signed-off-by: Keith Zantow <keith.zantow@anchore.com>
2026-09-10 08:45:36 -04:00