Skip to content

Commit 36a82ea

Browse files
authored
Merge pull request #328 from ccojocar/fix-sonarqute-report
Fix the file path in the Sonarqube report and also add support for multiple root folders
2 parents 04dc713 + 020479a commit 36a82ea

File tree

6 files changed

+297
-18
lines changed

6 files changed

+297
-18
lines changed

cmd/gosec/main.go

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -171,19 +171,27 @@ func loadRules(include, exclude string) rules.RuleList {
171171
return rules.Generate(filters...)
172172
}
173173

174-
func saveOutput(filename, format, rootPath string, issues []*gosec.Issue, metrics *gosec.Metrics, errors map[string][]gosec.Error) error {
174+
func saveOutput(filename, format string, paths []string, issues []*gosec.Issue, metrics *gosec.Metrics, errors map[string][]gosec.Error) error {
175+
rootPaths := []string{}
176+
for _, path := range paths {
177+
rootPath, err := gosec.RootPath(path)
178+
if err != nil {
179+
return fmt.Errorf("failed to get the root path of the projects: %s", err)
180+
}
181+
rootPaths = append(rootPaths, rootPath)
182+
}
175183
if filename != "" {
176184
outfile, err := os.Create(filename)
177185
if err != nil {
178186
return err
179187
}
180188
defer outfile.Close()
181-
err = output.CreateReport(outfile, format, rootPath, issues, metrics, errors)
189+
err = output.CreateReport(outfile, format, rootPaths, issues, metrics, errors)
182190
if err != nil {
183191
return err
184192
}
185193
} else {
186-
err := output.CreateReport(os.Stdout, format, rootPath, issues, metrics, errors)
194+
err := output.CreateReport(os.Stdout, format, rootPaths, issues, metrics, errors)
187195
if err != nil {
188196
return err
189197
}
@@ -318,9 +326,8 @@ func main() {
318326
os.Exit(0)
319327
}
320328

321-
rootPath := packages[0]
322329
// Create output report
323-
if err := saveOutput(*flagOutput, *flagFormat, rootPath, issues, metrics, errors); err != nil {
330+
if err := saveOutput(*flagOutput, *flagFormat, flag.Args(), issues, metrics, errors); err != nil {
324331
logger.Fatal(err)
325332
}
326333

helpers.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,3 +387,11 @@ func PackagePaths(root string, exclude *regexp.Regexp) ([]string, error) {
387387
}
388388
return result, nil
389389
}
390+
391+
// RootPath returns the absolute root path of a scan
392+
func RootPath(root string) (string, error) {
393+
if strings.HasSuffix(root, "...") {
394+
root = root[0 : len(root)-3]
395+
}
396+
return filepath.Abs(root)
397+
}

helpers_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package gosec_test
33
import (
44
"io/ioutil"
55
"os"
6+
"path/filepath"
67
"regexp"
78

89
. "github.com/onsi/ginkgo"
@@ -53,4 +54,23 @@ var _ = Describe("Helpers", func() {
5354
Expect(paths).Should(BeEmpty())
5455
})
5556
})
57+
58+
Context("when getting the root path", func() {
59+
It("should return the absolute path from relative path", func() {
60+
base := "test"
61+
cwd, err := os.Getwd()
62+
Expect(err).ShouldNot(HaveOccurred())
63+
root, err := gosec.RootPath(base)
64+
Expect(err).ShouldNot(HaveOccurred())
65+
Expect(root).Should(Equal(filepath.Join(cwd, base)))
66+
})
67+
It("should retrun the absolute path from ellipsis path", func() {
68+
base := "test"
69+
cwd, err := os.Getwd()
70+
Expect(err).ShouldNot(HaveOccurred())
71+
root, err := gosec.RootPath(filepath.Join(base, "..."))
72+
Expect(err).ShouldNot(HaveOccurred())
73+
Expect(root).Should(Equal(filepath.Join(cwd, base)))
74+
})
75+
})
5676
})

output/formatter.go

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ type reportInfo struct {
7676

7777
// CreateReport generates a report based for the supplied issues and metrics given
7878
// the specified format. The formats currently accepted are: json, csv, html and text.
79-
func CreateReport(w io.Writer, format, rootPath string, issues []*gosec.Issue, metrics *gosec.Metrics, errors map[string][]gosec.Error) error {
79+
func CreateReport(w io.Writer, format string, rootPaths []string, issues []*gosec.Issue, metrics *gosec.Metrics, errors map[string][]gosec.Error) error {
8080
data := &reportInfo{
8181
Errors: errors,
8282
Issues: issues,
@@ -97,35 +97,58 @@ func CreateReport(w io.Writer, format, rootPath string, issues []*gosec.Issue, m
9797
case "text":
9898
err = reportFromPlaintextTemplate(w, text, data)
9999
case "sonarqube":
100-
err = reportSonarqube(rootPath, w, data)
100+
err = reportSonarqube(rootPaths, w, data)
101101
default:
102102
err = reportFromPlaintextTemplate(w, text, data)
103103
}
104104
return err
105105
}
106106

107-
func reportSonarqube(rootPath string, w io.Writer, data *reportInfo) error {
107+
func reportSonarqube(rootPaths []string, w io.Writer, data *reportInfo) error {
108+
si, err := convertToSonarIssues(rootPaths, data)
109+
if err != nil {
110+
return err
111+
}
112+
raw, err := json.MarshalIndent(si, "", "\t")
113+
if err != nil {
114+
return err
115+
}
116+
_, err = w.Write(raw)
117+
return err
118+
}
119+
120+
func convertToSonarIssues(rootPaths []string, data *reportInfo) (sonarIssues, error) {
108121
var si sonarIssues
109122
for _, issue := range data.Issues {
110-
lines := strings.Split(issue.Line, "-")
123+
var sonarFilePath string
124+
for _, rootPath := range rootPaths {
125+
if strings.HasPrefix(issue.File, rootPath) {
126+
sonarFilePath = strings.Replace(issue.File, rootPath+"/", "", 1)
127+
}
128+
}
129+
if sonarFilePath == "" {
130+
continue
131+
}
111132

133+
lines := strings.Split(issue.Line, "-")
112134
startLine, err := strconv.Atoi(lines[0])
113135
if err != nil {
114-
return err
136+
return si, err
115137
}
116138
endLine := startLine
117139
if len(lines) > 1 {
118140
endLine, err = strconv.Atoi(lines[1])
119141
if err != nil {
120-
return err
142+
return si, err
121143
}
122144
}
145+
123146
s := sonarIssue{
124147
EngineID: "gosec",
125148
RuleID: issue.RuleID,
126149
PrimaryLocation: location{
127150
Message: issue.What,
128-
FilePath: strings.Replace(issue.File, rootPath+"/", "", 1),
151+
FilePath: sonarFilePath,
129152
TextRange: textRange{StartLine: startLine, EndLine: endLine},
130153
},
131154
Type: "VULNERABILITY",
@@ -134,12 +157,7 @@ func reportSonarqube(rootPath string, w io.Writer, data *reportInfo) error {
134157
}
135158
si.SonarIssues = append(si.SonarIssues, s)
136159
}
137-
raw, err := json.MarshalIndent(si, "", "\t")
138-
if err != nil {
139-
return err
140-
}
141-
_, err = w.Write(raw)
142-
return err
160+
return si, nil
143161
}
144162

145163
func reportJSON(w io.Writer, data *reportInfo) error {

output/formatter_suite_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package output
2+
3+
import (
4+
. "github.com/onsi/ginkgo"
5+
. "github.com/onsi/gomega"
6+
7+
"testing"
8+
)
9+
10+
func TestRules(t *testing.T) {
11+
RegisterFailHandler(Fail)
12+
RunSpecs(t, "Formatters Suite")
13+
}

0 commit comments

Comments
 (0)