Skip to content

Commit 27bf0e4

Browse files
authored
Fix rule index reference into sarif report (#934)
1 parent e7b896f commit 27bf0e4

File tree

2 files changed

+94
-21
lines changed

2 files changed

+94
-21
lines changed

report/sarif/formatter.go

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,13 @@ import (
1212
"github.com/securego/gosec/v2/issue"
1313
)
1414

15-
// GenerateReport Convert a gosec report to a Sarif Report
15+
// GenerateReport converts a gosec report into a SARIF report
1616
func GenerateReport(rootPaths []string, data *gosec.ReportInfo) (*Report, error) {
17-
type rule struct {
18-
index int
19-
rule *ReportingDescriptor
20-
}
21-
22-
rules := make([]*ReportingDescriptor, 0)
23-
rulesIndices := make(map[string]rule)
24-
lastRuleIndex := -1
17+
rules := []*ReportingDescriptor{}
2518

2619
results := []*Result{}
27-
cweTaxa := make([]*ReportingDescriptor, 0)
28-
weaknesses := make(map[string]*cwe.Weakness)
20+
cweTaxa := []*ReportingDescriptor{}
21+
weaknesses := map[string]*cwe.Weakness{}
2922

3023
for _, issue := range data.Issues {
3124
if issue.Cwe != nil {
@@ -38,26 +31,26 @@ func GenerateReport(rootPaths []string, data *gosec.ReportInfo) (*Report, error)
3831
}
3932
}
4033

41-
r, ok := rulesIndices[issue.RuleID]
42-
if !ok {
43-
lastRuleIndex++
44-
r = rule{index: lastRuleIndex, rule: parseSarifRule(issue)}
45-
rulesIndices[issue.RuleID] = r
46-
rules = append(rules, r.rule)
47-
}
34+
rule := parseSarifRule(issue)
35+
ruleIndex := 0
36+
rules, ruleIndex = addRuleInOrder(rules, rule)
4837

4938
location, err := parseSarifLocation(issue, rootPaths)
5039
if err != nil {
5140
return nil, err
5241
}
5342

54-
result := NewResult(r.rule.ID, r.index, getSarifLevel(issue.Severity.String()), issue.What, buildSarifSuppressions(issue.Suppressions)).
55-
WithLocations(location)
43+
result := NewResult(
44+
issue.RuleID,
45+
ruleIndex,
46+
getSarifLevel(issue.Severity.String()),
47+
issue.What,
48+
buildSarifSuppressions(issue.Suppressions),
49+
).WithLocations(location)
5650

5751
results = append(results, result)
5852
}
5953

60-
sort.SliceStable(rules, func(i, j int) bool { return rules[i].ID < rules[j].ID })
6154
sort.SliceStable(cweTaxa, func(i, j int) bool { return cweTaxa[i].ID < cweTaxa[j].ID })
6255

6356
tool := NewTool(buildSarifDriver(rules, data.GosecVersion))
@@ -72,6 +65,26 @@ func GenerateReport(rootPaths []string, data *gosec.ReportInfo) (*Report, error)
7265
WithRuns(run), nil
7366
}
7467

68+
// addRuleInOrder inserts a rule into the rules slice keeping the rules IDs order, it returns the new rules
69+
// slice and the position where the rule was inserted
70+
func addRuleInOrder(rules []*ReportingDescriptor, rule *ReportingDescriptor) ([]*ReportingDescriptor, int) {
71+
position := 0
72+
for i, r := range rules {
73+
if r.ID < rule.ID {
74+
continue
75+
}
76+
if r.ID == rule.ID {
77+
return rules, i
78+
}
79+
position = i
80+
break
81+
}
82+
rules = append(rules, nil)
83+
copy(rules[position+1:], rules[position:])
84+
rules[position] = rule
85+
return rules, position
86+
}
87+
7588
// parseSarifRule return SARIF rule field struct
7689
func parseSarifRule(i *issue.Issue) *ReportingDescriptor {
7790
cwe := issue.GetCweByRule(i.RuleID)

report/sarif/sarif_test.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,5 +111,65 @@ var _ = Describe("Sarif Formatter", func() {
111111
Expect(err).ShouldNot(HaveOccurred())
112112
Expect(sarifReport.Runs[0].Results[0].Locations[0].PhysicalLocation.Region.Snippet.Text).Should(Equal(expectedCode))
113113
})
114+
It("sarif formatted report should have proper rule index", func() {
115+
rules := []string{"G404", "G101", "G102", "G103"}
116+
issues := []*issue.Issue{}
117+
for _, rule := range rules {
118+
cwe := issue.GetCweByRule(rule)
119+
newissue := issue.Issue{
120+
File: "/home/src/project/test.go",
121+
Line: "69-70",
122+
Col: "14",
123+
RuleID: rule,
124+
What: "test",
125+
Confidence: issue.High,
126+
Severity: issue.High,
127+
Cwe: cwe,
128+
Suppressions: []issue.SuppressionInfo{
129+
{
130+
Kind: "kind",
131+
Justification: "justification",
132+
},
133+
},
134+
}
135+
issues = append(issues, &newissue)
136+
137+
}
138+
dupRules := []string{"G102", "G404"}
139+
for _, rule := range dupRules {
140+
cwe := issue.GetCweByRule(rule)
141+
newissue := issue.Issue{
142+
File: "/home/src/project/test.go",
143+
Line: "69-70",
144+
Col: "14",
145+
RuleID: rule,
146+
What: "test",
147+
Confidence: issue.High,
148+
Severity: issue.High,
149+
Cwe: cwe,
150+
Suppressions: []issue.SuppressionInfo{
151+
{
152+
Kind: "kind",
153+
Justification: "justification",
154+
},
155+
},
156+
}
157+
issues = append(issues, &newissue)
158+
}
159+
reportInfo := gosec.NewReportInfo(issues, &gosec.Metrics{}, map[string][]gosec.Error{}).WithVersion("v2.7.0")
160+
161+
sarifReport, err := sarif.GenerateReport([]string{}, reportInfo)
162+
163+
Expect(err).ShouldNot(HaveOccurred())
164+
resultRuleIdexes := map[string]int{}
165+
for _, result := range sarifReport.Runs[0].Results {
166+
resultRuleIdexes[result.RuleID] = result.RuleIndex
167+
}
168+
driverRuleIndexes := map[string]int{}
169+
for ruleIndex, rule := range sarifReport.Runs[0].Tool.Driver.Rules {
170+
driverRuleIndexes[rule.ID] = ruleIndex
171+
}
172+
Expect(resultRuleIdexes).Should(Equal(driverRuleIndexes))
173+
})
114174
})
115175
})

0 commit comments

Comments
 (0)