diff --git a/pkg/flag/report_flags_test.go b/pkg/flag/report_flags_test.go index b113d7c62f97..ab4baa53fbff 100644 --- a/pkg/flag/report_flags_test.go +++ b/pkg/flag/report_flags_test.go @@ -213,7 +213,7 @@ func TestReportFlagGroup_ToOptions(t *testing.T) { t.Run("Error on non existing ignore file", func(t *testing.T) { t.Cleanup(viper.Reset) - setValue(flag.IgnoreFileFlag.ConfigName, string("doesntexist")) + setValue(flag.IgnoreFileFlag.ConfigName, "doesntexist") f := &flag.ReportFlagGroup{ IgnoreFile: flag.IgnoreFileFlag.Clone(), } diff --git a/pkg/result/ignore.go b/pkg/result/ignore.go index dbd1cab83db9..9a75224c7b2f 100644 --- a/pkg/result/ignore.go +++ b/pkg/result/ignore.go @@ -183,8 +183,9 @@ func (c *IgnoreConfig) MatchLicense(licenseID, filePath string) *IgnoreFinding { func ParseIgnoreFile(ctx context.Context, ignoreFile string) (IgnoreConfig, error) { var conf IgnoreConfig - if _, err := os.Stat(ignoreFile); errors.Is(err, fs.ErrNotExist) { - // .trivyignore doesn't necessarily exist + if fi, err := os.Stat(ignoreFile); errors.Is(err, fs.ErrNotExist) || fi.Size() == 0 { + // .trivyignore doesn't necessarily exist or maybe empty + log.Debug("Specified ignore file does not exist or is empty", log.String("file", ignoreFile), log.Int64("size", fi.Size())) return IgnoreConfig{}, nil } else if filepath.Ext(ignoreFile) == ".yml" || filepath.Ext(ignoreFile) == ".yaml" { conf, err = parseIgnoreYAML(ignoreFile) diff --git a/pkg/result/ignore_test.go b/pkg/result/ignore_test.go new file mode 100644 index 000000000000..4019beb83f68 --- /dev/null +++ b/pkg/result/ignore_test.go @@ -0,0 +1,77 @@ +package result + +import ( + "context" + "os" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestParseIgnoreFile(t *testing.T) { + t.Run("happy path valid config file", func(t *testing.T) { + got, err := ParseIgnoreFile(context.TODO(), "testdata/.trivyignore") + require.NoError(t, err) + assert.Equal(t, "testdata/.trivyignore", got.FilePath) + + // IDs in .trivyignore are treated as IDs for all scanners + // as it is unclear which type of security issue they are + assert.Len(t, got.Vulnerabilities, 6) + assert.Len(t, got.Misconfigurations, 6) + assert.Len(t, got.Secrets, 6) + assert.Len(t, got.Licenses, 6) + }) + + t.Run("happy path valid YAML config file", func(t *testing.T) { + got, err := ParseIgnoreFile(context.TODO(), "testdata/.trivyignore.yaml") + require.NoError(t, err) + assert.Equal(t, "testdata/.trivyignore.yaml", got.FilePath) + assert.Len(t, got.Vulnerabilities, 5) + assert.Len(t, got.Misconfigurations, 3) + assert.Len(t, got.Secrets, 3) + assert.Len(t, got.Licenses, 1) + }) + + t.Run("empty YAML file passed", func(t *testing.T) { + f, err := os.CreateTemp("", "TestParseIgnoreFile-*.yaml") + require.NoError(t, err) + defer os.Remove(f.Name()) + + got, err := ParseIgnoreFile(context.TODO(), f.Name()) + require.NoError(t, err) + assert.Empty(t, got) + }) + + t.Run("invalid YAML file passed", func(t *testing.T) { + f, err := os.CreateTemp("", "TestParseIgnoreFile-*.yaml") + require.NoError(t, err) + defer os.Remove(f.Name()) + _, _ = f.WriteString("this file is not a yaml file") + + got, err := ParseIgnoreFile(context.TODO(), f.Name()) + assert.Contains(t, err.Error(), "yaml decode error") + assert.Empty(t, got) + }) + + // TODO(simar7): This test currently fails as we don't validate + // the correctness of ignore file when not in YAML format + /* + t.Run("invalid file passed", func(t *testing.T) { + f, err := os.CreateTemp("", "TestParseIgnoreFile-*") + require.NoError(t, err) + defer os.Remove(f.Name()) + _, _ = f.WriteString("this file is not a valid trivyignore file") + + _, err = ParseIgnoreFile(context.TODO(), f.Name()) + require.Error(t, err) + }) + */ + + t.Run("non existing file passed", func(t *testing.T) { + got, err := ParseIgnoreFile(context.TODO(), "does-not-exist.yaml") + require.NoError(t, err) + assert.Empty(t, got) + }) + +}