Skip to content

Commit 3e69a8c

Browse files
ccojocarCosmin Cojocar
authored andcommitted
Append the package load errors to analyser's errors
Signed-off-by: Cosmin Cojocar <[email protected]>
1 parent aac9b00 commit 3e69a8c

File tree

3 files changed

+68
-24
lines changed

3 files changed

+68
-24
lines changed

analyzer.go

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ func (gosec *Analyzer) Process(buildTags []string, packagePaths ...string) error
107107
for _, pkgPath := range packagePaths {
108108
pkgs, err := gosec.load(pkgPath, config)
109109
if err != nil {
110-
return fmt.Errorf("loading pkg dir %q: %v", pkgPath, err)
110+
gosec.AppendError(pkgPath, err)
111111
}
112112
for _, pkg := range pkgs {
113113
if pkg.Name != "" {
@@ -124,10 +124,14 @@ func (gosec *Analyzer) Process(buildTags []string, packagePaths ...string) error
124124
}
125125

126126
func (gosec *Analyzer) pkgConfig(buildTags []string) *packages.Config {
127-
tagsFlag := "-tags=" + strings.Join(buildTags, " ")
127+
flags := []string{}
128+
if len(buildTags) > 0 {
129+
tagsFlag := "-tags=" + strings.Join(buildTags, " ")
130+
flags = append(flags, tagsFlag)
131+
}
128132
return &packages.Config{
129133
Mode: packages.LoadSyntax,
130-
BuildFlags: []string{tagsFlag},
134+
BuildFlags: flags,
131135
Tests: gosec.tests,
132136
}
133137
}
@@ -142,7 +146,7 @@ func (gosec *Analyzer) load(pkgPath string, conf *packages.Config) ([]*packages.
142146
gosec.logger.Println("Import directory:", abspath)
143147
basePackage, err := build.Default.ImportDir(pkgPath, build.ImportComment)
144148
if err != nil {
145-
return []*packages.Package{}, err
149+
return []*packages.Package{}, fmt.Errorf("importing dir %q: %v", pkgPath, err)
146150
}
147151

148152
var packageFiles []string
@@ -161,7 +165,7 @@ func (gosec *Analyzer) load(pkgPath string, conf *packages.Config) ([]*packages.
161165

162166
pkgs, err := packages.Load(conf, packageFiles...)
163167
if err != nil {
164-
return []*packages.Package{}, err
168+
return []*packages.Package{}, fmt.Errorf("loading files from package %q: %v", pkgPath, err)
165169
}
166170
return pkgs, nil
167171
}
@@ -218,6 +222,22 @@ func (gosec *Analyzer) ParseErrors(pkg *packages.Package) error {
218222
return nil
219223
}
220224

225+
// AppendError appends an error to the file errors
226+
func (gosec *Analyzer) AppendError(file string, err error) {
227+
// Do not report the error for empty packages (e.g. files excluded from build with a tag
228+
r := regexp.MustCompile(`no buildable Go source files in`)
229+
if r.MatchString(err.Error()) {
230+
return
231+
}
232+
errors := []Error{}
233+
if ferrs, ok := gosec.errors[file]; ok {
234+
errors = ferrs
235+
}
236+
ferr := NewError(0, 0, err.Error())
237+
errors = append(errors, *ferr)
238+
gosec.errors[file] = errors
239+
}
240+
221241
// ignore a node (and sub-tree) if it is tagged with a "#nosec" comment
222242
func (gosec *Analyzer) ignore(n ast.Node) ([]string, bool) {
223243
if groups, ok := gosec.context.Comments[n]; ok && !gosec.ignoreNosec {

analyzer_test.go

Lines changed: 42 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package gosec_test
22

33
import (
4+
"errors"
45
"io/ioutil"
56
"log"
67
"os"
@@ -30,27 +31,31 @@ var _ = Describe("Analyzer", func() {
3031

3132
Context("when processing a package", func() {
3233

33-
It("should return an error if the package contains no Go files", func() {
34+
It("should not report an error if the package contains no Go files", func() {
3435
analyzer.LoadRules(rules.Generate().Builders())
3536
dir, err := ioutil.TempDir("", "empty")
3637
defer os.RemoveAll(dir)
3738
Expect(err).ShouldNot(HaveOccurred())
3839
err = analyzer.Process(buildTags, dir)
39-
Expect(err).Should(HaveOccurred())
40-
Expect(err.Error()).Should(MatchRegexp("no buildable Go source files"))
40+
Expect(err).ShouldNot(HaveOccurred())
41+
_, _, errors := analyzer.Report()
42+
Expect(len(errors)).To(Equal(0))
4143
})
4244

43-
It("should return an error if the package fails to build", func() {
45+
It("should report an error if the package fails to build", func() {
4446
analyzer.LoadRules(rules.Generate().Builders())
4547
pkg := testutils.NewTestPackage()
4648
defer pkg.Close()
4749
pkg.AddFile("wonky.go", `func main(){ println("forgot the package")}`)
4850
err := pkg.Build()
4951
Expect(err).Should(HaveOccurred())
5052
err = analyzer.Process(buildTags, pkg.Path)
51-
Expect(err).Should(HaveOccurred())
52-
Expect(err.Error()).Should(MatchRegexp(`expected 'package'`))
53-
53+
Expect(err).ShouldNot(HaveOccurred())
54+
_, _, errors := analyzer.Report()
55+
Expect(len(errors)).To(Equal(1))
56+
for _, ferr := range errors {
57+
Expect(len(ferr)).To(Equal(1))
58+
}
5459
})
5560

5661
It("should be able to analyze multiple Go files", func() {
@@ -216,9 +221,9 @@ var _ = Describe("Analyzer", func() {
216221
pkg := testutils.NewTestPackage()
217222
defer pkg.Close()
218223
pkg.AddFile("tags.go", source)
219-
buildTags = append(buildTags, "test")
220-
err := analyzer.Process(buildTags, pkg.Path)
221-
Expect(err).Should(HaveOccurred())
224+
tags := []string{"tag"}
225+
err := analyzer.Process(tags, pkg.Path)
226+
Expect(err).ShouldNot(HaveOccurred())
222227
})
223228

224229
It("should process an empty package with test file", func() {
@@ -236,14 +241,6 @@ var _ = Describe("Analyzer", func() {
236241
Expect(err).ShouldNot(HaveOccurred())
237242
})
238243

239-
It("should report an error when the package is empty", func() {
240-
analyzer.LoadRules(rules.Generate().Builders())
241-
pkg := testutils.NewTestPackage()
242-
defer pkg.Close()
243-
err := analyzer.Process(buildTags, pkg.Path)
244-
Expect(err).Should(HaveOccurred())
245-
})
246-
247244
It("should be possible to overwrite nosec comments, and report issues", func() {
248245
// Rule for MD5 weak crypto usage
249246
sample := testutils.SampleCodeG401[0]
@@ -416,4 +413,31 @@ var _ = Describe("Analyzer", func() {
416413
}
417414
})
418415
})
416+
417+
Context("when appending errors", func() {
418+
It("should skip error for non-buildable packages", func() {
419+
analyzer.AppendError("test", errors.New(`loading file from package "pkg/test": no buildable Go source files in pkg/test`))
420+
_, _, errors := analyzer.Report()
421+
Expect(len(errors)).To(Equal(0))
422+
})
423+
424+
It("should add a new error", func() {
425+
pkg := &packages.Package{
426+
Errors: []packages.Error{
427+
packages.Error{
428+
Pos: "file:1:2",
429+
Msg: "build error",
430+
},
431+
},
432+
}
433+
err := analyzer.ParseErrors(pkg)
434+
Expect(err).ShouldNot(HaveOccurred())
435+
analyzer.AppendError("file", errors.New("file build error"))
436+
_, _, errors := analyzer.Report()
437+
Expect(len(errors)).To(Equal(1))
438+
for _, ferr := range errors {
439+
Expect(len(ferr)).To(Equal(2))
440+
}
441+
})
442+
})
419443
})

testutils/source.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1135,7 +1135,7 @@ func main() {
11351135
}`}, 1}}
11361136
// SampleCode601 - Go build tags
11371137
SampleCode601 = []CodeSample{{[]string{`
1138-
// +build test
1138+
// +build tag
11391139
11401140
package main
11411141
func main() {

0 commit comments

Comments
 (0)