From 6938f7060a57067a1f57cd85e7da55047ee4a404 Mon Sep 17 00:00:00 2001 From: Jim Liu Date: Fri, 15 May 2026 21:40:04 +0800 Subject: [PATCH 1/4] Refactor error position parsing to support path with colons --- analyzer.go | 27 ++++++++++++++++----------- analyzer_test.go | 20 ++++++++++++++++++++ 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/analyzer.go b/analyzer.go index e6fc4bcf84..c9ee053bd2 100644 --- a/analyzer.go +++ b/analyzer.go @@ -29,6 +29,7 @@ import ( "path" "path/filepath" "reflect" + "regexp" "runtime/debug" "strconv" "strings" @@ -761,20 +762,24 @@ func ParseErrors(pkg *packages.Package) (map[string][]Error, error) { return nil, nil } errs := make(map[string][]Error) + var posRegexp = regexp.MustCompile(`^(.*?)(?::(\w+))?(?::(\w+))?$`) for _, pkgErr := range pkg.Errors { - parts := strings.Split(pkgErr.Pos, ":") - file := parts[0] + matches := posRegexp.FindStringSubmatch(pkgErr.Pos) + file := pkgErr.Pos var err error - var line int - if len(parts) > 1 { - if line, err = strconv.Atoi(parts[1]); err != nil { - return nil, fmt.Errorf("parsing line: %w", err) + var line, column int + if len(matches) > 0 { + file = matches[1] + file = strings.TrimSuffix(file, ":") + if matches[2] != "" { + if line, err = strconv.Atoi(matches[2]); err != nil { + return nil, fmt.Errorf("parsing line: %w", err) + } } - } - var column int - if len(parts) > 2 { - if column, err = strconv.Atoi(parts[2]); err != nil { - return nil, fmt.Errorf("parsing column: %w", err) + if matches[3] != "" { + if column, err = strconv.Atoi(matches[3]); err != nil { + return nil, fmt.Errorf("parsing column: %w", err) + } } } msg := strings.TrimSpace(pkgErr.Msg) diff --git a/analyzer_test.go b/analyzer_test.go index a905b7f717..24cc076873 100644 --- a/analyzer_test.go +++ b/analyzer_test.go @@ -1803,6 +1803,26 @@ func main() { Expect(err).Should(HaveOccurred()) }) + It("should properly parse the errors with colons in path", func() { + pkg := &packages.Package{ + Errors: []packages.Error{ + { + Pos: "C:\\file:1:2", + Msg: "build error", + }, + }, + } + errors, err := gosec.ParseErrors(pkg) + Expect(err).ShouldNot(HaveOccurred()) + Expect(errors).To(HaveLen(1)) + for _, ferr := range errors { + Expect(ferr).To(HaveLen(1)) + Expect(ferr[0].Line).To(Equal(1)) + Expect(ferr[0].Column).To(Equal(2)) + Expect(ferr[0].Err).Should(MatchRegexp(`build error`)) + } + }) + It("should append error to the same file", func() { pkg := &packages.Package{ Errors: []packages.Error{ From 9a8ae2826d10c9c9672364372eb908a5e03d0659 Mon Sep 17 00:00:00 2001 From: Jim Liu Date: Sat, 16 May 2026 01:38:40 +0800 Subject: [PATCH 2/4] Add additional unit test for paths with colons --- analyzer_test.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/analyzer_test.go b/analyzer_test.go index 24cc076873..7bbca685ec 100644 --- a/analyzer_test.go +++ b/analyzer_test.go @@ -85,12 +85,17 @@ var _ = Describe("Analyzer", func() { func bar(){ println("package has two files!") }`) + pkg.AddFile("foo:bar.go", ` + package main + func fooBar(){ + println("package has another file!") + }`) err := pkg.Build() Expect(err).ShouldNot(HaveOccurred()) err = analyzer.Process(buildTags, pkg.Path) Expect(err).ShouldNot(HaveOccurred()) _, metrics, _ := analyzer.Report() - Expect(metrics.NumFiles).To(Equal(2)) + Expect(metrics.NumFiles).To(Equal(3)) }) It("should be able to analyze multiple Go files concurrently", func() { @@ -1810,11 +1815,15 @@ func main() { Pos: "C:\\file:1:2", Msg: "build error", }, + { + Pos: "file:100:1:2", + Msg: "build error", + }, }, } errors, err := gosec.ParseErrors(pkg) Expect(err).ShouldNot(HaveOccurred()) - Expect(errors).To(HaveLen(1)) + Expect(errors).To(HaveLen(2)) for _, ferr := range errors { Expect(ferr).To(HaveLen(1)) Expect(ferr[0].Line).To(Equal(1)) From d8b34b75171ad88ac892cf1b1a4eca4bcb84ab1f Mon Sep 17 00:00:00 2001 From: Jim Liu Date: Wed, 20 May 2026 11:35:44 +0800 Subject: [PATCH 3/4] Fix lint warnings. --- analyzer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/analyzer.go b/analyzer.go index c9ee053bd2..253b5809f1 100644 --- a/analyzer.go +++ b/analyzer.go @@ -762,7 +762,7 @@ func ParseErrors(pkg *packages.Package) (map[string][]Error, error) { return nil, nil } errs := make(map[string][]Error) - var posRegexp = regexp.MustCompile(`^(.*?)(?::(\w+))?(?::(\w+))?$`) + posRegexp := regexp.MustCompile(`^(.*?)(?::(\w+))?(?::(\w+))?$`) for _, pkgErr := range pkg.Errors { matches := posRegexp.FindStringSubmatch(pkgErr.Pos) file := pkgErr.Pos From de90330f33fb549b7ac8fa6d9468ce70cf3c1d23 Mon Sep 17 00:00:00 2001 From: Jim Liu Date: Thu, 21 May 2026 01:15:04 +0800 Subject: [PATCH 4/4] Add length check to protect against potential API change of FindStringSubmatch() --- analyzer.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/analyzer.go b/analyzer.go index 253b5809f1..0276cff8c6 100644 --- a/analyzer.go +++ b/analyzer.go @@ -771,12 +771,12 @@ func ParseErrors(pkg *packages.Package) (map[string][]Error, error) { if len(matches) > 0 { file = matches[1] file = strings.TrimSuffix(file, ":") - if matches[2] != "" { + if len(matches) > 2 && matches[2] != "" { if line, err = strconv.Atoi(matches[2]); err != nil { return nil, fmt.Errorf("parsing line: %w", err) } } - if matches[3] != "" { + if len(matches) > 3 && matches[3] != "" { if column, err = strconv.Atoi(matches[3]); err != nil { return nil, fmt.Errorf("parsing column: %w", err) }