Skip to content

Commit

Permalink
fix(misconf): don't shift ignore rule related to code (#6708)
Browse files Browse the repository at this point in the history
  • Loading branch information
nikpivkin authored May 17, 2024
1 parent d6dc567 commit 39a746c
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 21 deletions.
42 changes: 26 additions & 16 deletions pkg/iac/ignore/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"strings"
"time"

"github.com/samber/lo"

"github.com/aquasecurity/trivy/pkg/iac/types"
"github.com/aquasecurity/trivy/pkg/log"
)
Expand Down Expand Up @@ -36,23 +38,34 @@ func Parse(src, path string, parsers ...RuleSectionParser) Rules {
func parseLine(line string, rng types.Range, parsers []RuleSectionParser) []Rule {
var rules []Rule

sections := strings.Split(strings.TrimSpace(line), " ")
for _, section := range sections {
section := strings.TrimSpace(section)
section = strings.TrimLeftFunc(section, func(r rune) bool {
parts := strings.Split(strings.TrimSpace(line), " ")
parts = lo.FilterMap(parts, func(part string, _ int) (string, bool) {
part = strings.TrimSpace(part)
part = strings.TrimLeftFunc(part, func(r rune) bool {
return r == '#' || r == '/' || r == '*'
})

section, exists := hasIgnoreRulePrefix(section)
return part, part != ""
})

for i, part := range parts {
part, exists := hasIgnoreRulePrefix(part)
if !exists {
continue
}

rule, err := parseComment(section, rng, parsers)
sections, err := parseRuleSections(part, rng, parsers)
if err != nil {
log.Debug("Failed to parse rule", log.String("range", rng.String()), log.Err(err))
continue
}

rule := Rule{
rng: rng,
isStartLine: i == 0 || (len(rules) > 0 && rules[0].isStartLine),
sections: sections,
}

rules = append(rules, rule)
}

Expand All @@ -72,11 +85,8 @@ func hasIgnoreRulePrefix(s string) (string, bool) {
return "", false
}

func parseComment(input string, rng types.Range, parsers []RuleSectionParser) (Rule, error) {
rule := Rule{
rng: rng,
sections: make(map[string]any),
}
func parseRuleSections(input string, rng types.Range, parsers []RuleSectionParser) (map[string]any, error) {
sections := make(map[string]any)

parsers = append(parsers, &expiryDateParser{
rng: rng,
Expand All @@ -93,7 +103,7 @@ func parseComment(input string, rng types.Range, parsers []RuleSectionParser) (R
StringMatchParser{SectionKey: "id"},
}
if idParser.Parse(val) {
rule.sections[idParser.Key()] = idParser.Param()
sections[idParser.Key()] = idParser.Param()
}
}

Expand All @@ -103,16 +113,16 @@ func parseComment(input string, rng types.Range, parsers []RuleSectionParser) (R
}

if parser.Parse(val) {
rule.sections[parser.Key()] = parser.Param()
sections[parser.Key()] = parser.Param()
}
}
}

if _, exists := rule.sections["id"]; !exists {
return Rule{}, errors.New("rule section with the `ignore` key is required")
if _, exists := sections["id"]; !exists {
return nil, errors.New("rule section with the `ignore` key is required")
}

return rule, nil
return sections, nil
}

type StringMatchParser struct {
Expand Down
16 changes: 11 additions & 5 deletions pkg/iac/ignore/rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,16 @@ func (r Rules) shift() {
)

for i := len(r) - 1; i > 0; i-- {
currentIgnore, nextIgnore := r[i], r[i-1]
currentRule, prevRule := r[i], r[i-1]

if !prevRule.isStartLine {
continue
}

if currentRange == nil {
currentRange = &currentIgnore.rng
currentRange = &currentRule.rng
}
if nextIgnore.rng.GetStartLine()+1+offset == currentIgnore.rng.GetStartLine() {
if prevRule.rng.GetStartLine()+1+offset == currentRule.rng.GetStartLine() {
r[i-1].rng = *currentRange
offset++
} else {
Expand All @@ -46,8 +51,9 @@ func (r Rules) shift() {

// Rule represents a rule for ignoring vulnerabilities.
type Rule struct {
rng types.Range
sections map[string]any
rng types.Range
isStartLine bool
sections map[string]any
}

func (r Rule) ignore(m types.Metadata, ids []string, ignorers map[string]Ignorer) bool {
Expand Down
44 changes: 44 additions & 0 deletions pkg/iac/ignore/rule_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,50 @@ func TestRules_Ignore(t *testing.T) {
},
shouldIgnore: false,
},
{
name: "multiple ignore rules on the same line",
src: `test #trivy:ignore:rule-1
test #trivy:ignore:rule-2
`,
args: args{
metadata: metadataWithLine(filename, 1),
ids: []string{"rule-1"},
},
shouldIgnore: true,
},
{
name: "multiple ignore rules on the same line",
src: `# trivy:ignore:rule-1
# trivy:ignore:rule-2
test #trivy:ignore:rule-3
`,
args: args{
metadata: metadataWithLine(filename, 3),
ids: []string{"rule-1"},
},
shouldIgnore: true,
},
{
name: "multiple ignore rules on the same line",
src: `# trivy:ignore:rule-1 # trivy:ignore:rule-2
# trivy:ignore:rule-3
test #trivy:ignore:rule-4
`,
args: args{
metadata: metadataWithLine(filename, 3),
ids: []string{"rule-2"},
},
shouldIgnore: true,
},
{
name: "multiple ids",
src: `# trivy:ignore:rule-1`,
args: args{
metadata: metadataWithLine(filename, 1),
ids: []string{"rule-1", "rule-2"},
},
shouldIgnore: true,
},
}

for _, tt := range tests {
Expand Down

0 comments on commit 39a746c

Please sign in to comment.