mirror of
https://github.com/securego/gosec.git
synced 2024-12-25 20:15:54 +00:00
Append the package load errors to analyser's errors
Signed-off-by: Cosmin Cojocar <cosmin.cojocar@gmx.ch>
This commit is contained in:
parent
aac9b00845
commit
3e69a8c8a2
3 changed files with 68 additions and 24 deletions
30
analyzer.go
30
analyzer.go
|
@ -107,7 +107,7 @@ func (gosec *Analyzer) Process(buildTags []string, packagePaths ...string) error
|
||||||
for _, pkgPath := range packagePaths {
|
for _, pkgPath := range packagePaths {
|
||||||
pkgs, err := gosec.load(pkgPath, config)
|
pkgs, err := gosec.load(pkgPath, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("loading pkg dir %q: %v", pkgPath, err)
|
gosec.AppendError(pkgPath, err)
|
||||||
}
|
}
|
||||||
for _, pkg := range pkgs {
|
for _, pkg := range pkgs {
|
||||||
if pkg.Name != "" {
|
if pkg.Name != "" {
|
||||||
|
@ -124,10 +124,14 @@ func (gosec *Analyzer) Process(buildTags []string, packagePaths ...string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gosec *Analyzer) pkgConfig(buildTags []string) *packages.Config {
|
func (gosec *Analyzer) pkgConfig(buildTags []string) *packages.Config {
|
||||||
tagsFlag := "-tags=" + strings.Join(buildTags, " ")
|
flags := []string{}
|
||||||
|
if len(buildTags) > 0 {
|
||||||
|
tagsFlag := "-tags=" + strings.Join(buildTags, " ")
|
||||||
|
flags = append(flags, tagsFlag)
|
||||||
|
}
|
||||||
return &packages.Config{
|
return &packages.Config{
|
||||||
Mode: packages.LoadSyntax,
|
Mode: packages.LoadSyntax,
|
||||||
BuildFlags: []string{tagsFlag},
|
BuildFlags: flags,
|
||||||
Tests: gosec.tests,
|
Tests: gosec.tests,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -142,7 +146,7 @@ func (gosec *Analyzer) load(pkgPath string, conf *packages.Config) ([]*packages.
|
||||||
gosec.logger.Println("Import directory:", abspath)
|
gosec.logger.Println("Import directory:", abspath)
|
||||||
basePackage, err := build.Default.ImportDir(pkgPath, build.ImportComment)
|
basePackage, err := build.Default.ImportDir(pkgPath, build.ImportComment)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []*packages.Package{}, err
|
return []*packages.Package{}, fmt.Errorf("importing dir %q: %v", pkgPath, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var packageFiles []string
|
var packageFiles []string
|
||||||
|
@ -161,7 +165,7 @@ func (gosec *Analyzer) load(pkgPath string, conf *packages.Config) ([]*packages.
|
||||||
|
|
||||||
pkgs, err := packages.Load(conf, packageFiles...)
|
pkgs, err := packages.Load(conf, packageFiles...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []*packages.Package{}, err
|
return []*packages.Package{}, fmt.Errorf("loading files from package %q: %v", pkgPath, err)
|
||||||
}
|
}
|
||||||
return pkgs, nil
|
return pkgs, nil
|
||||||
}
|
}
|
||||||
|
@ -218,6 +222,22 @@ func (gosec *Analyzer) ParseErrors(pkg *packages.Package) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AppendError appends an error to the file errors
|
||||||
|
func (gosec *Analyzer) AppendError(file string, err error) {
|
||||||
|
// Do not report the error for empty packages (e.g. files excluded from build with a tag
|
||||||
|
r := regexp.MustCompile(`no buildable Go source files in`)
|
||||||
|
if r.MatchString(err.Error()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
errors := []Error{}
|
||||||
|
if ferrs, ok := gosec.errors[file]; ok {
|
||||||
|
errors = ferrs
|
||||||
|
}
|
||||||
|
ferr := NewError(0, 0, err.Error())
|
||||||
|
errors = append(errors, *ferr)
|
||||||
|
gosec.errors[file] = errors
|
||||||
|
}
|
||||||
|
|
||||||
// ignore a node (and sub-tree) if it is tagged with a "#nosec" comment
|
// ignore a node (and sub-tree) if it is tagged with a "#nosec" comment
|
||||||
func (gosec *Analyzer) ignore(n ast.Node) ([]string, bool) {
|
func (gosec *Analyzer) ignore(n ast.Node) ([]string, bool) {
|
||||||
if groups, ok := gosec.context.Comments[n]; ok && !gosec.ignoreNosec {
|
if groups, ok := gosec.context.Comments[n]; ok && !gosec.ignoreNosec {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package gosec_test
|
package gosec_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
@ -30,17 +31,18 @@ var _ = Describe("Analyzer", func() {
|
||||||
|
|
||||||
Context("when processing a package", func() {
|
Context("when processing a package", func() {
|
||||||
|
|
||||||
It("should return an error if the package contains no Go files", func() {
|
It("should not report an error if the package contains no Go files", func() {
|
||||||
analyzer.LoadRules(rules.Generate().Builders())
|
analyzer.LoadRules(rules.Generate().Builders())
|
||||||
dir, err := ioutil.TempDir("", "empty")
|
dir, err := ioutil.TempDir("", "empty")
|
||||||
defer os.RemoveAll(dir)
|
defer os.RemoveAll(dir)
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
Expect(err).ShouldNot(HaveOccurred())
|
||||||
err = analyzer.Process(buildTags, dir)
|
err = analyzer.Process(buildTags, dir)
|
||||||
Expect(err).Should(HaveOccurred())
|
Expect(err).ShouldNot(HaveOccurred())
|
||||||
Expect(err.Error()).Should(MatchRegexp("no buildable Go source files"))
|
_, _, errors := analyzer.Report()
|
||||||
|
Expect(len(errors)).To(Equal(0))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should return an error if the package fails to build", func() {
|
It("should report an error if the package fails to build", func() {
|
||||||
analyzer.LoadRules(rules.Generate().Builders())
|
analyzer.LoadRules(rules.Generate().Builders())
|
||||||
pkg := testutils.NewTestPackage()
|
pkg := testutils.NewTestPackage()
|
||||||
defer pkg.Close()
|
defer pkg.Close()
|
||||||
|
@ -48,9 +50,12 @@ var _ = Describe("Analyzer", func() {
|
||||||
err := pkg.Build()
|
err := pkg.Build()
|
||||||
Expect(err).Should(HaveOccurred())
|
Expect(err).Should(HaveOccurred())
|
||||||
err = analyzer.Process(buildTags, pkg.Path)
|
err = analyzer.Process(buildTags, pkg.Path)
|
||||||
Expect(err).Should(HaveOccurred())
|
Expect(err).ShouldNot(HaveOccurred())
|
||||||
Expect(err.Error()).Should(MatchRegexp(`expected 'package'`))
|
_, _, errors := analyzer.Report()
|
||||||
|
Expect(len(errors)).To(Equal(1))
|
||||||
|
for _, ferr := range errors {
|
||||||
|
Expect(len(ferr)).To(Equal(1))
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should be able to analyze multiple Go files", func() {
|
It("should be able to analyze multiple Go files", func() {
|
||||||
|
@ -216,9 +221,9 @@ var _ = Describe("Analyzer", func() {
|
||||||
pkg := testutils.NewTestPackage()
|
pkg := testutils.NewTestPackage()
|
||||||
defer pkg.Close()
|
defer pkg.Close()
|
||||||
pkg.AddFile("tags.go", source)
|
pkg.AddFile("tags.go", source)
|
||||||
buildTags = append(buildTags, "test")
|
tags := []string{"tag"}
|
||||||
err := analyzer.Process(buildTags, pkg.Path)
|
err := analyzer.Process(tags, pkg.Path)
|
||||||
Expect(err).Should(HaveOccurred())
|
Expect(err).ShouldNot(HaveOccurred())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should process an empty package with test file", func() {
|
It("should process an empty package with test file", func() {
|
||||||
|
@ -236,14 +241,6 @@ var _ = Describe("Analyzer", func() {
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
Expect(err).ShouldNot(HaveOccurred())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should report an error when the package is empty", func() {
|
|
||||||
analyzer.LoadRules(rules.Generate().Builders())
|
|
||||||
pkg := testutils.NewTestPackage()
|
|
||||||
defer pkg.Close()
|
|
||||||
err := analyzer.Process(buildTags, pkg.Path)
|
|
||||||
Expect(err).Should(HaveOccurred())
|
|
||||||
})
|
|
||||||
|
|
||||||
It("should be possible to overwrite nosec comments, and report issues", func() {
|
It("should be possible to overwrite nosec comments, and report issues", func() {
|
||||||
// Rule for MD5 weak crypto usage
|
// Rule for MD5 weak crypto usage
|
||||||
sample := testutils.SampleCodeG401[0]
|
sample := testutils.SampleCodeG401[0]
|
||||||
|
@ -416,4 +413,31 @@ var _ = Describe("Analyzer", func() {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Context("when appending errors", func() {
|
||||||
|
It("should skip error for non-buildable packages", func() {
|
||||||
|
analyzer.AppendError("test", errors.New(`loading file from package "pkg/test": no buildable Go source files in pkg/test`))
|
||||||
|
_, _, errors := analyzer.Report()
|
||||||
|
Expect(len(errors)).To(Equal(0))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should add a new error", func() {
|
||||||
|
pkg := &packages.Package{
|
||||||
|
Errors: []packages.Error{
|
||||||
|
packages.Error{
|
||||||
|
Pos: "file:1:2",
|
||||||
|
Msg: "build error",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
err := analyzer.ParseErrors(pkg)
|
||||||
|
Expect(err).ShouldNot(HaveOccurred())
|
||||||
|
analyzer.AppendError("file", errors.New("file build error"))
|
||||||
|
_, _, errors := analyzer.Report()
|
||||||
|
Expect(len(errors)).To(Equal(1))
|
||||||
|
for _, ferr := range errors {
|
||||||
|
Expect(len(ferr)).To(Equal(2))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -1135,7 +1135,7 @@ func main() {
|
||||||
}`}, 1}}
|
}`}, 1}}
|
||||||
// SampleCode601 - Go build tags
|
// SampleCode601 - Go build tags
|
||||||
SampleCode601 = []CodeSample{{[]string{`
|
SampleCode601 = []CodeSample{{[]string{`
|
||||||
// +build test
|
// +build tag
|
||||||
|
|
||||||
package main
|
package main
|
||||||
func main() {
|
func main() {
|
||||||
|
|
Loading…
Reference in a new issue