Skip to content

Commit

Permalink
Merge pull request securego#328 from ccojocar/fix-sonarqute-report
Browse files Browse the repository at this point in the history
Fix the file path in the Sonarqube report and also add support for multiple root folders
  • Loading branch information
ccojocar authored Jun 25, 2019
2 parents 04dc713 + 020479a commit 36a82ea
Show file tree
Hide file tree
Showing 6 changed files with 297 additions and 18 deletions.
17 changes: 12 additions & 5 deletions cmd/gosec/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,19 +171,27 @@ func loadRules(include, exclude string) rules.RuleList {
return rules.Generate(filters...)
}

func saveOutput(filename, format, rootPath string, issues []*gosec.Issue, metrics *gosec.Metrics, errors map[string][]gosec.Error) error {
func saveOutput(filename, format string, paths []string, issues []*gosec.Issue, metrics *gosec.Metrics, errors map[string][]gosec.Error) error {
rootPaths := []string{}
for _, path := range paths {
rootPath, err := gosec.RootPath(path)
if err != nil {
return fmt.Errorf("failed to get the root path of the projects: %s", err)
}
rootPaths = append(rootPaths, rootPath)
}
if filename != "" {
outfile, err := os.Create(filename)
if err != nil {
return err
}
defer outfile.Close()
err = output.CreateReport(outfile, format, rootPath, issues, metrics, errors)
err = output.CreateReport(outfile, format, rootPaths, issues, metrics, errors)
if err != nil {
return err
}
} else {
err := output.CreateReport(os.Stdout, format, rootPath, issues, metrics, errors)
err := output.CreateReport(os.Stdout, format, rootPaths, issues, metrics, errors)
if err != nil {
return err
}
Expand Down Expand Up @@ -318,9 +326,8 @@ func main() {
os.Exit(0)
}

rootPath := packages[0]
// Create output report
if err := saveOutput(*flagOutput, *flagFormat, rootPath, issues, metrics, errors); err != nil {
if err := saveOutput(*flagOutput, *flagFormat, flag.Args(), issues, metrics, errors); err != nil {
logger.Fatal(err)
}

Expand Down
8 changes: 8 additions & 0 deletions helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -387,3 +387,11 @@ func PackagePaths(root string, exclude *regexp.Regexp) ([]string, error) {
}
return result, nil
}

// RootPath returns the absolute root path of a scan
func RootPath(root string) (string, error) {
if strings.HasSuffix(root, "...") {
root = root[0 : len(root)-3]
}
return filepath.Abs(root)
}
20 changes: 20 additions & 0 deletions helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package gosec_test
import (
"io/ioutil"
"os"
"path/filepath"
"regexp"

. "github.com/onsi/ginkgo"
Expand Down Expand Up @@ -53,4 +54,23 @@ var _ = Describe("Helpers", func() {
Expect(paths).Should(BeEmpty())
})
})

Context("when getting the root path", func() {
It("should return the absolute path from relative path", func() {
base := "test"
cwd, err := os.Getwd()
Expect(err).ShouldNot(HaveOccurred())
root, err := gosec.RootPath(base)
Expect(err).ShouldNot(HaveOccurred())
Expect(root).Should(Equal(filepath.Join(cwd, base)))
})
It("should retrun the absolute path from ellipsis path", func() {
base := "test"
cwd, err := os.Getwd()
Expect(err).ShouldNot(HaveOccurred())
root, err := gosec.RootPath(filepath.Join(base, "..."))
Expect(err).ShouldNot(HaveOccurred())
Expect(root).Should(Equal(filepath.Join(cwd, base)))
})
})
})
44 changes: 31 additions & 13 deletions output/formatter.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ type reportInfo struct {

// CreateReport generates a report based for the supplied issues and metrics given
// the specified format. The formats currently accepted are: json, csv, html and text.
func CreateReport(w io.Writer, format, rootPath string, issues []*gosec.Issue, metrics *gosec.Metrics, errors map[string][]gosec.Error) error {
func CreateReport(w io.Writer, format string, rootPaths []string, issues []*gosec.Issue, metrics *gosec.Metrics, errors map[string][]gosec.Error) error {
data := &reportInfo{
Errors: errors,
Issues: issues,
Expand All @@ -97,35 +97,58 @@ func CreateReport(w io.Writer, format, rootPath string, issues []*gosec.Issue, m
case "text":
err = reportFromPlaintextTemplate(w, text, data)
case "sonarqube":
err = reportSonarqube(rootPath, w, data)
err = reportSonarqube(rootPaths, w, data)
default:
err = reportFromPlaintextTemplate(w, text, data)
}
return err
}

func reportSonarqube(rootPath string, w io.Writer, data *reportInfo) error {
func reportSonarqube(rootPaths []string, w io.Writer, data *reportInfo) error {
si, err := convertToSonarIssues(rootPaths, data)
if err != nil {
return err
}
raw, err := json.MarshalIndent(si, "", "\t")
if err != nil {
return err
}
_, err = w.Write(raw)
return err
}

func convertToSonarIssues(rootPaths []string, data *reportInfo) (sonarIssues, error) {
var si sonarIssues
for _, issue := range data.Issues {
lines := strings.Split(issue.Line, "-")
var sonarFilePath string
for _, rootPath := range rootPaths {
if strings.HasPrefix(issue.File, rootPath) {
sonarFilePath = strings.Replace(issue.File, rootPath+"/", "", 1)
}
}
if sonarFilePath == "" {
continue
}

lines := strings.Split(issue.Line, "-")
startLine, err := strconv.Atoi(lines[0])
if err != nil {
return err
return si, err
}
endLine := startLine
if len(lines) > 1 {
endLine, err = strconv.Atoi(lines[1])
if err != nil {
return err
return si, err
}
}

s := sonarIssue{
EngineID: "gosec",
RuleID: issue.RuleID,
PrimaryLocation: location{
Message: issue.What,
FilePath: strings.Replace(issue.File, rootPath+"/", "", 1),
FilePath: sonarFilePath,
TextRange: textRange{StartLine: startLine, EndLine: endLine},
},
Type: "VULNERABILITY",
Expand All @@ -134,12 +157,7 @@ func reportSonarqube(rootPath string, w io.Writer, data *reportInfo) error {
}
si.SonarIssues = append(si.SonarIssues, s)
}
raw, err := json.MarshalIndent(si, "", "\t")
if err != nil {
return err
}
_, err = w.Write(raw)
return err
return si, nil
}

func reportJSON(w io.Writer, data *reportInfo) error {
Expand Down
13 changes: 13 additions & 0 deletions output/formatter_suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package output

import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"

"testing"
)

func TestRules(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Formatters Suite")
}
Loading

0 comments on commit 36a82ea

Please sign in to comment.