mirror of
https://github.com/anchore/syft.git
synced 2026-10-30 14:02:26 +01:00
chore: archive memory and disk limits of 0 mean 0
Signed-off-by: Keith Zantow <keith.zantow@anchore.com>
This commit is contained in:
@@ -28,8 +28,9 @@ note: this only applies to the java package cataloger, and is ignored when neste
|
||||
these packages are removed if an overlap with a non-synthetic package is found`)
|
||||
descriptions.Add(&o.NestedArchiveMaxDepth, `maximum depth to recursively catalog nested archives (0 = disabled, -1 = as deep as 16 levels)
|
||||
note: when enabled this replaces the java cataloger's own unbounded jar-in-jar recursion, so archives deeper than this are reported as unknowns rather than cataloged`)
|
||||
descriptions.Add(&o.NestedArchiveMaxMemoryBytes, `maximum bytes of nested archive content held in memory at once (0 = default, -1 = unbounded)`)
|
||||
descriptions.Add(&o.NestedArchiveMaxDiskBytes, `maximum bytes of nested archive content on disk at once (0 = default, -1 = unbounded)`)
|
||||
descriptions.Add(&o.NestedArchiveMaxMemoryBytes, `maximum bytes of nested archive content held in memory at once (0 = none, -1 = unbounded)`)
|
||||
descriptions.Add(&o.NestedArchiveMaxDiskBytes, `maximum bytes of nested archive content on disk at once (0 = none, -1 = unbounded)
|
||||
note: this and nested-archive-max-memory-bytes cannot both be 0 when nested-archive-max-depth is not 0`)
|
||||
}
|
||||
|
||||
func defaultPackageConfig() packageConfig {
|
||||
|
||||
@@ -433,7 +433,7 @@ func Test_mixedFamilyNesting_diskLimitTruncatesTheLevelItCannotAdmit(t *testing.
|
||||
|
||||
func Test_mixedFamilyNesting_unboundedLimitsEnforceNothing(t *testing.T) {
|
||||
// a caller can opt out of one bound without the other, and opting out of both must still find the
|
||||
// deepest leaf. Both opt out with a negative value, since zero means the default.
|
||||
// deepest leaf. Opting out is a negative value; zero forbids the resource.
|
||||
for _, row := range nestingRows() {
|
||||
t.Run(row.name, func(t *testing.T) {
|
||||
scanDir := t.TempDir()
|
||||
|
||||
@@ -41,13 +41,8 @@ func NewArchiveCatalogerTask(cfg cataloging.ArchiveSearchConfig, subPipeline []T
|
||||
return newArchiveCatalogerTask(cfg.MaxDepth, archiveLimits(cfg), subPipeline, exclusions)
|
||||
}
|
||||
|
||||
// archiveLimits maps the configured limits onto the limiter's. Zero means the default, so the limiter's
|
||||
// own zero (which forbids the resource) is not reachable from configuration.
|
||||
func archiveLimits(cfg cataloging.ArchiveSearchConfig) archive.Limits {
|
||||
return archive.Limits{
|
||||
MaxMemoryBytes: cmp.Or(cfg.MaxMemoryBytes, int64(cataloging.DefaultArchiveMaxMemoryBytes)),
|
||||
MaxDiskBytes: cmp.Or(cfg.MaxDiskBytes, int64(cataloging.DefaultArchiveMaxDiskBytes)),
|
||||
}
|
||||
return archive.Limits{MaxMemoryBytes: cfg.MaxMemoryBytes, MaxDiskBytes: cfg.MaxDiskBytes}
|
||||
}
|
||||
|
||||
func newArchiveCatalogerTask(maxDepth int, limits archive.Limits, subPipeline []Task, exclusions []string) Task {
|
||||
|
||||
@@ -172,23 +172,6 @@ func Test_archiveCataloger_traversalThreading(t *testing.T) {
|
||||
}, seen)
|
||||
}
|
||||
|
||||
func Test_archiveCataloger_zeroLimitsMeanDefault(t *testing.T) {
|
||||
// a config literal naming only the depth must catalog archives, not forbid both memory and disk
|
||||
rootDir := t.TempDir()
|
||||
require.NoError(t, os.WriteFile(filepath.Join(rootDir, "outer.zip"), makeZip(t, map[string][]byte{"a.txt": []byte("a")}), 0o600))
|
||||
|
||||
var seen []string
|
||||
fileCounts := map[string]int{}
|
||||
tsk := newTestTask(t, cataloging.ArchiveSearchConfig{MaxDepth: 1}, capturingTask(t, &seen, &fileCounts))
|
||||
|
||||
s := newTestSBOM()
|
||||
require.NoError(t, tsk.Execute(context.Background(), dirTestResolver{dir: rootDir}, sbomsync.NewBuilder(s)))
|
||||
|
||||
assert.Equal(t, []string{"/outer.zip"}, seen)
|
||||
assert.Equal(t, 1, fileCounts["/outer.zip"])
|
||||
assert.Empty(t, s.Artifacts.Unknowns)
|
||||
}
|
||||
|
||||
func Test_archiveCataloger_truncationStillCatalogs(t *testing.T) {
|
||||
// reaching a limit is a truncation, not a failure: the sub-pipeline still runs over what was stored
|
||||
big := bytes.Repeat([]byte("x"), 4096)
|
||||
|
||||
@@ -27,11 +27,12 @@ type ArchiveSearchConfig struct {
|
||||
MaxDepth int `yaml:"max-depth" json:"max-depth" mapstructure:"max-depth"`
|
||||
|
||||
// MaxMemoryBytes bounds the archive content held in memory at once; content that does not fit is
|
||||
// written to disk. Zero means DefaultArchiveMaxMemoryBytes, negative is unbounded.
|
||||
// written to disk. Zero holds nothing in memory, negative is unbounded.
|
||||
MaxMemoryBytes int64 `yaml:"max-memory-bytes" json:"max-memory-bytes" mapstructure:"max-memory-bytes"`
|
||||
|
||||
// MaxDiskBytes bounds the archive content written to disk at once; an archive whose content does
|
||||
// not fit is skipped or truncated. Zero means DefaultArchiveMaxDiskBytes, negative is unbounded.
|
||||
// not fit is skipped or truncated. Zero writes nothing to disk, negative is unbounded. MaxMemoryBytes
|
||||
// and MaxDiskBytes cannot both be zero while MaxDepth is not.
|
||||
MaxDiskBytes int64 `yaml:"max-disk-bytes" json:"max-disk-bytes" mapstructure:"max-disk-bytes"`
|
||||
}
|
||||
|
||||
|
||||
@@ -148,8 +148,7 @@ func (c *CreateSBOMConfig) WithFilesConfig(cfg filecataloging.Config) *CreateSBO
|
||||
}
|
||||
|
||||
// WithArchiveConfig sets how archives are cataloged: how deep to recurse into nested archives (MaxDepth
|
||||
// 0, the default, does not recurse) and how much extracted content the scan may hold at once (a zero
|
||||
// limit means the default).
|
||||
// 0, the default, does not recurse) and how much extracted content the scan may hold at once.
|
||||
func (c *CreateSBOMConfig) WithArchiveConfig(cfg cataloging.ArchiveSearchConfig) *CreateSBOMConfig {
|
||||
c.Archive = cfg
|
||||
return c
|
||||
@@ -515,6 +514,9 @@ func (c *CreateSBOMConfig) validate() error {
|
||||
if j := c.Packages.JavaArchive.ArchiveSearchConfig; j.MaxDepth != 0 || j.MaxMemoryBytes != 0 || j.MaxDiskBytes != 0 {
|
||||
return fmt.Errorf("invalid configuration: nested archive depth and limits are not java cataloger settings, set them with CreateSBOMConfig.Archive")
|
||||
}
|
||||
if a := c.Archive; a.MaxDepth != 0 && a.MaxMemoryBytes == 0 && a.MaxDiskBytes == 0 {
|
||||
return fmt.Errorf("invalid configuration: nested archive cataloging is enabled but its memory and disk limits are both 0, leaving nowhere to extract archives")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -555,6 +555,31 @@ func TestCreateSBOMConfig_validate(t *testing.T) {
|
||||
),
|
||||
wantErr: assert.Error,
|
||||
},
|
||||
{
|
||||
name: "nested archives enabled with no memory or disk",
|
||||
cfg: DefaultCreateSBOMConfig().WithArchiveConfig(
|
||||
cataloging.DefaultArchiveSearchConfig().WithMaxDepth(1).WithMaxMemoryBytes(0).WithMaxDiskBytes(0),
|
||||
),
|
||||
wantErr: assert.Error,
|
||||
},
|
||||
{
|
||||
name: "nested archives enabled with memory only",
|
||||
cfg: DefaultCreateSBOMConfig().WithArchiveConfig(
|
||||
cataloging.DefaultArchiveSearchConfig().WithMaxDepth(1).WithMaxDiskBytes(0),
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "nested archives enabled with disk only",
|
||||
cfg: DefaultCreateSBOMConfig().WithArchiveConfig(
|
||||
cataloging.DefaultArchiveSearchConfig().WithMaxDepth(1).WithMaxMemoryBytes(0),
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "nested archives disabled with no memory or disk",
|
||||
cfg: DefaultCreateSBOMConfig().WithArchiveConfig(
|
||||
cataloging.DefaultArchiveSearchConfig().WithMaxMemoryBytes(0).WithMaxDiskBytes(0),
|
||||
),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user