Skip to content

Commit 39a746c

Browse files
authored
fix(misconf): don't shift ignore rule related to code (#6708)
1 parent d6dc567 commit 39a746c

File tree

3 files changed

+81
-21
lines changed

3 files changed

+81
-21
lines changed

pkg/iac/ignore/parse.go

+26-16
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55
"strings"
66
"time"
77

8+
"github.com/samber/lo"
9+
810
"github.com/aquasecurity/trivy/pkg/iac/types"
911
"github.com/aquasecurity/trivy/pkg/log"
1012
)
@@ -36,23 +38,34 @@ func Parse(src, path string, parsers ...RuleSectionParser) Rules {
3638
func parseLine(line string, rng types.Range, parsers []RuleSectionParser) []Rule {
3739
var rules []Rule
3840

39-
sections := strings.Split(strings.TrimSpace(line), " ")
40-
for _, section := range sections {
41-
section := strings.TrimSpace(section)
42-
section = strings.TrimLeftFunc(section, func(r rune) bool {
41+
parts := strings.Split(strings.TrimSpace(line), " ")
42+
parts = lo.FilterMap(parts, func(part string, _ int) (string, bool) {
43+
part = strings.TrimSpace(part)
44+
part = strings.TrimLeftFunc(part, func(r rune) bool {
4345
return r == '#' || r == '/' || r == '*'
4446
})
4547

46-
section, exists := hasIgnoreRulePrefix(section)
48+
return part, part != ""
49+
})
50+
51+
for i, part := range parts {
52+
part, exists := hasIgnoreRulePrefix(part)
4753
if !exists {
4854
continue
4955
}
5056

51-
rule, err := parseComment(section, rng, parsers)
57+
sections, err := parseRuleSections(part, rng, parsers)
5258
if err != nil {
5359
log.Debug("Failed to parse rule", log.String("range", rng.String()), log.Err(err))
5460
continue
5561
}
62+
63+
rule := Rule{
64+
rng: rng,
65+
isStartLine: i == 0 || (len(rules) > 0 && rules[0].isStartLine),
66+
sections: sections,
67+
}
68+
5669
rules = append(rules, rule)
5770
}
5871

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

75-
func parseComment(input string, rng types.Range, parsers []RuleSectionParser) (Rule, error) {
76-
rule := Rule{
77-
rng: rng,
78-
sections: make(map[string]any),
79-
}
88+
func parseRuleSections(input string, rng types.Range, parsers []RuleSectionParser) (map[string]any, error) {
89+
sections := make(map[string]any)
8090

8191
parsers = append(parsers, &expiryDateParser{
8292
rng: rng,
@@ -93,7 +103,7 @@ func parseComment(input string, rng types.Range, parsers []RuleSectionParser) (R
93103
StringMatchParser{SectionKey: "id"},
94104
}
95105
if idParser.Parse(val) {
96-
rule.sections[idParser.Key()] = idParser.Param()
106+
sections[idParser.Key()] = idParser.Param()
97107
}
98108
}
99109

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

105115
if parser.Parse(val) {
106-
rule.sections[parser.Key()] = parser.Param()
116+
sections[parser.Key()] = parser.Param()
107117
}
108118
}
109119
}
110120

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

115-
return rule, nil
125+
return sections, nil
116126
}
117127

118128
type StringMatchParser struct {

pkg/iac/ignore/rule.go

+11-5
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,16 @@ func (r Rules) shift() {
3030
)
3131

3232
for i := len(r) - 1; i > 0; i-- {
33-
currentIgnore, nextIgnore := r[i], r[i-1]
33+
currentRule, prevRule := r[i], r[i-1]
34+
35+
if !prevRule.isStartLine {
36+
continue
37+
}
38+
3439
if currentRange == nil {
35-
currentRange = &currentIgnore.rng
40+
currentRange = &currentRule.rng
3641
}
37-
if nextIgnore.rng.GetStartLine()+1+offset == currentIgnore.rng.GetStartLine() {
42+
if prevRule.rng.GetStartLine()+1+offset == currentRule.rng.GetStartLine() {
3843
r[i-1].rng = *currentRange
3944
offset++
4045
} else {
@@ -46,8 +51,9 @@ func (r Rules) shift() {
4651

4752
// Rule represents a rule for ignoring vulnerabilities.
4853
type Rule struct {
49-
rng types.Range
50-
sections map[string]any
54+
rng types.Range
55+
isStartLine bool
56+
sections map[string]any
5157
}
5258

5359
func (r Rule) ignore(m types.Metadata, ids []string, ignorers map[string]Ignorer) bool {

pkg/iac/ignore/rule_test.go

+44
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,50 @@ func TestRules_Ignore(t *testing.T) {
190190
},
191191
shouldIgnore: false,
192192
},
193+
{
194+
name: "multiple ignore rules on the same line",
195+
src: `test #trivy:ignore:rule-1
196+
test #trivy:ignore:rule-2
197+
`,
198+
args: args{
199+
metadata: metadataWithLine(filename, 1),
200+
ids: []string{"rule-1"},
201+
},
202+
shouldIgnore: true,
203+
},
204+
{
205+
name: "multiple ignore rules on the same line",
206+
src: `# trivy:ignore:rule-1
207+
# trivy:ignore:rule-2
208+
test #trivy:ignore:rule-3
209+
`,
210+
args: args{
211+
metadata: metadataWithLine(filename, 3),
212+
ids: []string{"rule-1"},
213+
},
214+
shouldIgnore: true,
215+
},
216+
{
217+
name: "multiple ignore rules on the same line",
218+
src: `# trivy:ignore:rule-1 # trivy:ignore:rule-2
219+
# trivy:ignore:rule-3
220+
test #trivy:ignore:rule-4
221+
`,
222+
args: args{
223+
metadata: metadataWithLine(filename, 3),
224+
ids: []string{"rule-2"},
225+
},
226+
shouldIgnore: true,
227+
},
228+
{
229+
name: "multiple ids",
230+
src: `# trivy:ignore:rule-1`,
231+
args: args{
232+
metadata: metadataWithLine(filename, 1),
233+
ids: []string{"rule-1", "rule-2"},
234+
},
235+
shouldIgnore: true,
236+
},
193237
}
194238

195239
for _, tt := range tests {

0 commit comments

Comments
 (0)