Skip to content

Commit

Permalink
Allow restricting filesystem walk to specific folders
Browse files Browse the repository at this point in the history
  • Loading branch information
lebauce committed Oct 31, 2023
1 parent e2fb3dd commit 6482fee
Show file tree
Hide file tree
Showing 15 changed files with 52 additions and 13 deletions.
1 change: 1 addition & 0 deletions pkg/commands/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -632,6 +632,7 @@ func NewConfigCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command {
// Enable only '--skip-dirs' and '--skip-files' and disable other flags
SkipDirs: &flag.SkipDirsFlag,
SkipFiles: &flag.SkipFilesFlag,
OnlyDirs: &flag.OnlyDirsFlag,
FilePatterns: &flag.FilePatternsFlag,
}

Expand Down
1 change: 1 addition & 0 deletions pkg/commands/artifact/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,7 @@ func initScannerConfig(opts flag.Options, cacheClient cache.Cache) (ScannerConfi
DisabledAnalyzers: disabledAnalyzers(opts),
SkipFiles: opts.SkipFiles,
SkipDirs: opts.SkipDirs,
OnlyDirs: opts.OnlyDirs,
FilePatterns: opts.FilePatterns,
Offline: opts.OfflineScan,
NoProgress: opts.NoProgress || opts.Quiet,
Expand Down
2 changes: 2 additions & 0 deletions pkg/fanal/artifact/artifact.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type Option struct {
DisabledHandlers []types.HandlerType
SkipFiles []string
SkipDirs []string
OnlyDirs []string
FilePatterns []string
NoProgress bool
Insecure bool
Expand Down Expand Up @@ -57,6 +58,7 @@ func (o *Option) Sort() {
sort.Strings(o.SkipFiles)
sort.Strings(o.SkipDirs)
sort.Strings(o.FilePatterns)
sort.Strings(o.OnlyDirs)
}

type Artifact interface {
Expand Down
2 changes: 1 addition & 1 deletion pkg/fanal/artifact/image/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func NewArtifact(img types.Image, c cache.ArtifactCache, opt artifact.Option) (a
return Artifact{
image: img,
cache: c,
walker: walker.NewLayerTar(opt.SkipFiles, opt.SkipDirs, opt.Slow),
walker: walker.NewLayerTar(opt.SkipFiles, opt.SkipDirs, opt.OnlyDirs, opt.Slow),
analyzer: a,
configAnalyzer: ca,
handlerManager: handlerManager,
Expand Down
2 changes: 1 addition & 1 deletion pkg/fanal/artifact/local/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func NewArtifact(rootPath string, c cache.ArtifactCache, opt artifact.Option) (a
return Artifact{
rootPath: filepath.ToSlash(filepath.Clean(rootPath)),
cache: c,
walker: walker.NewFS(buildPathsToSkip(rootPath, opt.SkipFiles), buildPathsToSkip(rootPath, opt.SkipDirs),
walker: walker.NewFS(buildPathsToSkip(rootPath, opt.SkipFiles), buildPathsToSkip(rootPath, opt.SkipDirs), buildPathsToSkip(rootPath, opt.OnlyDirs),
opt.Slow, opt.WalkOption.ErrorCallback),
analyzer: a,
handlerManager: handlerManager,
Expand Down
2 changes: 1 addition & 1 deletion pkg/fanal/artifact/vm/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ func NewArtifact(target string, c cache.ArtifactCache, opt artifact.Option) (art
cache: c,
analyzer: a,
handlerManager: handlerManager,
walker: walker.NewVM(opt.SkipFiles, opt.SkipDirs, opt.Slow),
walker: walker.NewVM(opt.SkipFiles, opt.SkipDirs, opt.OnlyDirs, opt.Slow),
artifactOption: opt,
}

Expand Down
3 changes: 2 additions & 1 deletion pkg/fanal/cache/key.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ func CalcKey(id string, analyzerVersions analyzer.Versions, hookVersions map[str
HookVersions map[string]int
SkipFiles []string
SkipDirs []string
OnlyDirs []string
FilePatterns []string `json:",omitempty"`
}{id, analyzerVersions, hookVersions, artifactOpt.SkipFiles, artifactOpt.SkipDirs, artifactOpt.FilePatterns}
}{id, analyzerVersions, hookVersions, artifactOpt.SkipFiles, artifactOpt.SkipDirs, artifactOpt.OnlyDirs, artifactOpt.FilePatterns}

if err := json.NewEncoder(h).Encode(keyBase); err != nil {
return "", xerrors.Errorf("json encode error: %w", err)
Expand Down
4 changes: 2 additions & 2 deletions pkg/fanal/walker/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ type FS struct {
errCallback ErrorCallback
}

func NewFS(skipFiles, skipDirs []string, slow bool, errCallback ErrorCallback) FS {
func NewFS(skipFiles, skipDirs, onlyDirs []string, slow bool, errCallback ErrorCallback) FS {
if errCallback == nil {
errCallback = func(pathname string, err error) error {
// ignore permission errors
Expand All @@ -32,7 +32,7 @@ func NewFS(skipFiles, skipDirs []string, slow bool, errCallback ErrorCallback) F
}

return FS{
walker: newWalker(skipFiles, skipDirs, slow),
walker: newWalker(skipFiles, skipDirs, onlyDirs, slow),
errCallback: errCallback,
}
}
Expand Down
3 changes: 2 additions & 1 deletion pkg/fanal/walker/fs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ func TestDir_Walk(t *testing.T) {
type fields struct {
skipFiles []string
skipDirs []string
onlyDirs []string
errCallback walker.ErrorCallback
}
tests := []struct {
Expand Down Expand Up @@ -93,7 +94,7 @@ func TestDir_Walk(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
w := walker.NewFS(tt.fields.skipFiles, tt.fields.skipDirs, true, tt.fields.errCallback)
w := walker.NewFS(tt.fields.skipFiles, tt.fields.skipDirs, tt.fields.onlyDirs, true, tt.fields.errCallback)

err := w.Walk(tt.rootDir, tt.analyzeFn)
if tt.wantErr != "" {
Expand Down
4 changes: 2 additions & 2 deletions pkg/fanal/walker/tar.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ type LayerTar struct {
threshold int64
}

func NewLayerTar(skipFiles, skipDirs []string, slow bool) LayerTar {
func NewLayerTar(skipFiles, skipDirs, onlyDirs []string, slow bool) LayerTar {
threshold := defaultSizeThreshold
if slow {
threshold = slowSizeThreshold
}

return LayerTar{
walker: newWalker(skipFiles, skipDirs, slow),
walker: newWalker(skipFiles, skipDirs, onlyDirs, slow),
threshold: threshold,
}
}
Expand Down
3 changes: 2 additions & 1 deletion pkg/fanal/walker/tar_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ func TestLayerTar_Walk(t *testing.T) {
type fields struct {
skipFiles []string
skipDirs []string
onlyDirs []string
}
tests := []struct {
name string
Expand Down Expand Up @@ -81,7 +82,7 @@ func TestLayerTar_Walk(t *testing.T) {
f, err := os.Open("testdata/test.tar")
require.NoError(t, err)

w := walker.NewLayerTar(tt.fields.skipFiles, tt.fields.skipDirs, true)
w := walker.NewLayerTar(tt.fields.skipFiles, tt.fields.skipDirs, tt.fields.onlyDirs, true)

gotOpqDirs, gotWhFiles, err := w.Walk(f, tt.analyzeFn)
if tt.wantErr != "" {
Expand Down
4 changes: 2 additions & 2 deletions pkg/fanal/walker/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,14 @@ type VM struct {
analyzeFn WalkFunc
}

func NewVM(skipFiles, skipDirs []string, slow bool) VM {
func NewVM(skipFiles, skipDirs, onlyDirs []string, slow bool) VM {
threshold := defaultSizeThreshold
if slow {
threshold = slowSizeThreshold
}

return VM{
walker: newWalker(skipFiles, skipDirs, slow),
walker: newWalker(skipFiles, skipDirs, onlyDirs, slow),
threshold: threshold,
}
}
Expand Down
20 changes: 19 additions & 1 deletion pkg/fanal/walker/walk.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,11 @@ type WalkFunc func(filePath string, info os.FileInfo, opener analyzer.Opener) er
type walker struct {
skipFiles []string
skipDirs []string
onlyDirs []string
slow bool
}

func newWalker(skipFiles, skipDirs []string, slow bool) walker {
func newWalker(skipFiles, skipDirs, onlyDirs []string, slow bool) walker {
var cleanSkipFiles, cleanSkipDirs []string
for _, skipFile := range skipFiles {
skipFile = filepath.ToSlash(filepath.Clean(skipFile))
Expand All @@ -49,9 +50,17 @@ func newWalker(skipFiles, skipDirs []string, slow bool) walker {
cleanSkipDirs = append(cleanSkipDirs, skipDir)
}

var cleanOnlyDirs []string
for _, onlyDir := range onlyDirs {
onlyDir = filepath.ToSlash(filepath.Clean(onlyDir))
onlyDir = strings.TrimLeft(onlyDir, "/")
cleanOnlyDirs = append(cleanOnlyDirs, onlyDir)
}

return walker{
skipFiles: cleanSkipFiles,
skipDirs: cleanSkipDirs,
onlyDirs: cleanOnlyDirs,
slow: slow,
}
}
Expand Down Expand Up @@ -91,5 +100,14 @@ func (w *walker) shouldSkipDir(dir string) bool {
}
}

if dir != "." && len(w.onlyDirs) > 0 {
for _, onlyDir := range w.onlyDirs {
if strings.HasPrefix(dir, onlyDir) || strings.HasPrefix(onlyDir, dir) {
return false
}
}
return true
}

return false
}
11 changes: 11 additions & 0 deletions pkg/flag/scan_flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ var (
Default: []string{},
Usage: "specify the files or glob patterns to skip",
}
OnlyDirsFlag = Flag{
Name: "only-dirs",
ConfigName: "scan.only-dirs",
Default: []string{},
Usage: "specify the directories where the traversal is allowed",
}
OfflineScanFlag = Flag{
Name: "offline-scan",
ConfigName: "scan.offline",
Expand Down Expand Up @@ -82,6 +88,7 @@ var (
type ScanFlagGroup struct {
SkipDirs *Flag
SkipFiles *Flag
OnlyDirs *Flag
OfflineScan *Flag
Scanners *Flag
FilePatterns *Flag
Expand All @@ -95,6 +102,7 @@ type ScanOptions struct {
Target string
SkipDirs []string
SkipFiles []string
OnlyDirs []string
OfflineScan bool
Scanners types.Scanners
FilePatterns []string
Expand All @@ -108,6 +116,7 @@ func NewScanFlagGroup() *ScanFlagGroup {
return &ScanFlagGroup{
SkipDirs: &SkipDirsFlag,
SkipFiles: &SkipFilesFlag,
OnlyDirs: &OnlyDirsFlag,
OfflineScan: &OfflineScanFlag,
Scanners: &ScannersFlag,
FilePatterns: &FilePatternsFlag,
Expand All @@ -126,6 +135,7 @@ func (f *ScanFlagGroup) Flags() []*Flag {
return []*Flag{
f.SkipDirs,
f.SkipFiles,
f.OnlyDirs,
f.OfflineScan,
f.Scanners,
f.FilePatterns,
Expand All @@ -146,6 +156,7 @@ func (f *ScanFlagGroup) ToOptions(args []string) (ScanOptions, error) {
Target: target,
SkipDirs: getStringSlice(f.SkipDirs),
SkipFiles: getStringSlice(f.SkipFiles),
OnlyDirs: getStringSlice(f.OnlyDirs),
OfflineScan: getBool(f.OfflineScan),
Scanners: getUnderlyingStringSlice[types.Scanner](f.Scanners),
FilePatterns: getStringSlice(f.FilePatterns),
Expand Down
3 changes: 3 additions & 0 deletions pkg/flag/scan_flags_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ func TestScanFlagGroup_ToOptions(t *testing.T) {
type fields struct {
skipDirs []string
skipFiles []string
onlyDirs []string
offlineScan bool
scanners string
}
Expand Down Expand Up @@ -111,13 +112,15 @@ func TestScanFlagGroup_ToOptions(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
viper.Set(flag.SkipDirsFlag.ConfigName, tt.fields.skipDirs)
viper.Set(flag.SkipFilesFlag.ConfigName, tt.fields.skipFiles)
viper.Set(flag.OnlyDirsFlag.ConfigName, tt.fields.onlyDirs)
viper.Set(flag.OfflineScanFlag.ConfigName, tt.fields.offlineScan)
viper.Set(flag.ScannersFlag.ConfigName, tt.fields.scanners)

// Assert options
f := &flag.ScanFlagGroup{
SkipDirs: &flag.SkipDirsFlag,
SkipFiles: &flag.SkipFilesFlag,
OnlyDirs: &flag.OnlyDirsFlag,
OfflineScan: &flag.OfflineScanFlag,
Scanners: &flag.ScannersFlag,
}
Expand Down

0 comments on commit 6482fee

Please sign in to comment.