fix: make CreateSBOMConfig.Archive the one place to configure archive search

`ArchiveSearchConfig` lived in two places and each half was dead in one of them: the top-level booleans were never read (only java's copy was), and java's depth and limits did nothing. A library caller setting `Packages.JavaArchive.MaxDepth = 3` got no nested cataloging, and no error.

- java's embedded `ArchiveSearchConfig` and `WithArchiveTraversal` are deprecated; `WithMaxParentRecursiveDepth` replaces the latter's other half
- `CreateSBOM` now rejects `MaxDepth`, `MaxMemoryBytes` or `MaxDiskBytes` set on java's copy with an `invalid configuration` error
- the top-level `IncludeIndexedArchives` / `IncludeUnindexedArchives` are overlaid onto a copy of java's config, and win when they differ from the default. Callers who only set java's copy see no change
- `java.DefaultArchiveCatalogerConfig()` now carries only the booleans, so its descriptor no longer reports limits that java never used
- the CLI fills only the top-level config, and the option descriptions now say the search booleans are ignored when nested cataloging is on

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
This commit is contained in:
Alex Goodman
2026-09-24 11:18:51 -04:00
parent a4a1d7afa7
commit 3f0a599d31
7 changed files with 81 additions and 27 deletions
@@ -114,17 +114,6 @@ func Test_nestedArchiveOwnershipSwitch(t *testing.T) {
require.Len(t, pkgs, 1)
assert.Equal(t, "example-app", pkgs[0].Name)
})
t.Run("java's own archive-search depth does not hand off recursion", func(t *testing.T) {
// a library consumer setting java's squash-inlined MaxDepth must neither enable nor disable
// nested archive cataloging: that knob is Archive.MaxDepth on CreateSBOMConfig. Getting it
// wrong silently drops nested jars for every consumer that is not the CLI.
cfg := DefaultArchiveCatalogerConfig()
cfg.ArchiveSearchConfig = cfg.ArchiveSearchConfig.WithMaxDepth(2)
pkgs := parse(t, pkgtest.Context(t), cfg)
require.Len(t, pkgs, 2, "this cataloger must still recurse itself")
})
}
func Test_NewArchiveCataloger_wrappedParserRegistration(t *testing.T) {
+4
View File
@@ -9,6 +9,7 @@ import (
"github.com/bmatcuk/doublestar/v4"
"github.com/anchore/syft/internal/archive"
"github.com/anchore/syft/internal/log"
"github.com/anchore/syft/internal/unknown"
"github.com/anchore/syft/syft/artifact"
"github.com/anchore/syft/syft/file"
@@ -18,6 +19,9 @@ import (
// NewArchiveCataloger returns a new Java archive cataloger object for detecting packages with archives (jar, war, ear, par, sar, jpi, hpi, and native-image formats)
func NewArchiveCataloger(cfg ArchiveCatalogerConfig) pkg.Cataloger {
if a := cfg.ArchiveSearchConfig; a.MaxDepth != 0 || a.MaxMemoryBytes != 0 || a.MaxDiskBytes != 0 {
log.Debug("java archive cataloger ignores nested archive depth and limits, set them with syft.CreateSBOMConfig.Archive")
}
gap := newGenericArchiveParserAdapter(cfg)
c := generic.NewCataloger("java-archive-cataloger").
+16 -1
View File
@@ -8,6 +8,9 @@ import (
)
type ArchiveCatalogerConfig struct {
// Deprecated: use syft.CreateSBOMConfig.Archive. Only the two Include* booleans are read here, and
// setting MaxDepth, MaxMemoryBytes or MaxDiskBytes is a configuration error. This will be removed in a
// future release.
cataloging.ArchiveSearchConfig `yaml:",inline" json:"" mapstructure:",squash"`
// UseNetwork enables network operations for java package metadata enrichment, such as fetching parent POMs and license information.
@@ -37,8 +40,13 @@ type ArchiveCatalogerConfig struct {
func DefaultArchiveCatalogerConfig() ArchiveCatalogerConfig {
mavenCfg := maven.DefaultConfig()
search := cataloging.DefaultArchiveSearchConfig()
return ArchiveCatalogerConfig{
ArchiveSearchConfig: cataloging.DefaultArchiveSearchConfig(),
// only the booleans: depth and limits are not java settings
ArchiveSearchConfig: cataloging.ArchiveSearchConfig{
IncludeIndexedArchives: search.IncludeIndexedArchives,
IncludeUnindexedArchives: search.IncludeUnindexedArchives,
},
UseNetwork: mavenCfg.UseNetwork,
UseMavenLocalRepository: mavenCfg.UseLocalRepository,
MavenLocalRepositoryDir: mavenCfg.LocalRepositoryDir,
@@ -75,12 +83,19 @@ func (j ArchiveCatalogerConfig) WithResolveTransitiveDependencies(resolveTransit
return j
}
// Deprecated: set archive search with syft.CreateSBOMConfig.Archive and the parent depth with
// WithMaxParentRecursiveDepth. This will be removed in a future release.
func (j ArchiveCatalogerConfig) WithArchiveTraversal(search cataloging.ArchiveSearchConfig, maxDepth int) ArchiveCatalogerConfig {
j.MaxParentRecursiveDepth = maxDepth
j.ArchiveSearchConfig = search
return j
}
func (j ArchiveCatalogerConfig) WithMaxParentRecursiveDepth(depth int) ArchiveCatalogerConfig {
j.MaxParentRecursiveDepth = depth
return j
}
func (j ArchiveCatalogerConfig) mavenConfig() maven.Config {
return maven.Config{
UseNetwork: j.UseNetwork,