Skip to content

Commit d1467ac

Browse files
ccojocarCosmin Cojocar
authored andcommitted
Extend the code snippet included in the issue and refactored how the code snippet is printed
Signed-off-by: Cosmin Cojocar <cosmin.cojocar@gmx.ch>
1 parent 37d1af0 commit d1467ac

3 files changed

Lines changed: 62 additions & 24 deletions

File tree

issue.go

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,12 @@
1515
package gosec
1616

1717
import (
18+
"bufio"
19+
"bytes"
1820
"encoding/json"
1921
"fmt"
2022
"go/ast"
23+
"go/token"
2124
"os"
2225
"strconv"
2326
)
@@ -34,6 +37,10 @@ const (
3437
High
3538
)
3639

40+
// SnippetOffset defines the number of lines captured before
41+
// the beginning and after the end of a code snippet
42+
const SnippetOffset = 1
43+
3744
// Cwe id and url
3845
type Cwe struct {
3946
ID string
@@ -126,41 +133,53 @@ func (c Score) String() string {
126133

127134
func codeSnippet(file *os.File, start int64, end int64, n ast.Node) (string, error) {
128135
if n == nil {
129-
return "", fmt.Errorf("Invalid AST node provided")
136+
return "", fmt.Errorf("invalid AST node provided")
130137
}
131-
132-
size := (int)(end - start) // Go bug, os.File.Read should return int64 ...
133-
_, err := file.Seek(start, 0) // #nosec
134-
if err != nil {
135-
return "", fmt.Errorf("move to the beginning of file: %v", err)
138+
var pos int64
139+
var buf bytes.Buffer
140+
scanner := bufio.NewScanner(file)
141+
scanner.Split(bufio.ScanLines)
142+
for scanner.Scan() {
143+
pos++
144+
if pos > end {
145+
break
146+
} else if pos >= start && pos <= end {
147+
code := fmt.Sprintf("%d: %s\n", pos, scanner.Text())
148+
buf.WriteString(code)
149+
}
136150
}
151+
return buf.String(), nil
152+
}
137153

138-
buf := make([]byte, size)
139-
if nread, err := file.Read(buf); err != nil || nread != size {
140-
return "", fmt.Errorf("Unable to read code")
154+
func codeSnippetStartLine(node ast.Node, fobj *token.File) int64 {
155+
s := (int64)(fobj.Line(node.Pos()))
156+
if s-SnippetOffset > 0 {
157+
return s - SnippetOffset
141158
}
142-
return string(buf), nil
159+
return s
160+
}
161+
162+
func codeSnippetEndLine(node ast.Node, fobj *token.File) int64 {
163+
e := (int64)(fobj.Line(node.End()))
164+
return e + SnippetOffset
143165
}
144166

145167
// NewIssue creates a new Issue
146168
func NewIssue(ctx *Context, node ast.Node, ruleID, desc string, severity Score, confidence Score) *Issue {
147-
var code string
148169
fobj := ctx.FileSet.File(node.Pos())
149170
name := fobj.Name()
150-
151171
start, end := fobj.Line(node.Pos()), fobj.Line(node.End())
152172
line := strconv.Itoa(start)
153173
if start != end {
154174
line = fmt.Sprintf("%d-%d", start, end)
155175
}
156-
157176
col := strconv.Itoa(fobj.Position(node.Pos()).Column)
158177

159-
// #nosec
178+
var code string
160179
if file, err := os.Open(fobj.Name()); err == nil {
161-
defer file.Close()
162-
s := (int64)(fobj.Position(node.Pos()).Offset) // Go bug, should be int64
163-
e := (int64)(fobj.Position(node.End()).Offset) // Go bug, should be int64
180+
defer file.Close() // #nosec
181+
s := codeSnippetStartLine(node, fobj)
182+
e := codeSnippetEndLine(node, fobj)
164183
code, err = codeSnippet(file, s, e, node)
165184
if err != nil {
166185
code = err.Error()

output/formatter.go

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
package output
1616

1717
import (
18+
"bufio"
19+
"bytes"
1820
"encoding/csv"
1921
"encoding/json"
2022
"encoding/xml"
@@ -59,7 +61,7 @@ Golang errors in file: [{{ $filePath }}]:
5961
{{end}}
6062
{{ range $index, $issue := .Issues }}
6163
[{{ highlight $issue.FileLocation $issue.Severity }}] - {{ $issue.RuleID }} (CWE-{{ $issue.Cwe.ID }}): {{ $issue.What }} (Confidence: {{ $issue.Confidence}}, Severity: {{ $issue.Severity }})
62-
> {{ $issue.Code }}
64+
{{ printCode $issue }}
6365
6466
{{ end }}
6567
{{ notice "Summary:" }}
@@ -286,6 +288,7 @@ func plainTextFuncMap(enableColor bool) plainTemplate.FuncMap {
286288
"danger": color.Danger.Render,
287289
"notice": color.Notice.Render,
288290
"success": color.Success.Render,
291+
"printCode": printCodeSnippet,
289292
}
290293
}
291294

@@ -294,9 +297,10 @@ func plainTextFuncMap(enableColor bool) plainTemplate.FuncMap {
294297
"highlight": func(t string, s gosec.Score) string {
295298
return t
296299
},
297-
"danger": fmt.Sprint,
298-
"notice": fmt.Sprint,
299-
"success": fmt.Sprint,
300+
"danger": fmt.Sprint,
301+
"notice": fmt.Sprint,
302+
"success": fmt.Sprint,
303+
"printCode": printCodeSnippet,
300304
}
301305
}
302306

@@ -317,3 +321,18 @@ func highlight(t string, s gosec.Score) string {
317321
return defaultTheme.Sprint(t)
318322
}
319323
}
324+
325+
func printCodeSnippet(issue *gosec.Issue) string {
326+
scanner := bufio.NewScanner(strings.NewReader(issue.Code))
327+
var buf bytes.Buffer
328+
for scanner.Scan() {
329+
codeLine := scanner.Text()
330+
if strings.HasPrefix(codeLine, issue.Line) {
331+
codeLine = " > " + codeLine + "\n"
332+
} else {
333+
codeLine = " " + codeLine + "\n"
334+
}
335+
buf.WriteString(codeLine)
336+
}
337+
return buf.String()
338+
}

output/formatter_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ func createIssue(ruleID string, cwe gosec.Cwe) gosec.Issue {
2121
What: "test",
2222
Confidence: gosec.High,
2323
Severity: gosec.High,
24-
Code: "testcode",
24+
Code: "1: testcode",
2525
Cwe: cwe,
2626
}
2727
}
@@ -264,7 +264,7 @@ var _ = Describe("Formatter", func() {
264264
buf := new(bytes.Buffer)
265265
err := CreateReport(buf, "csv", false, []string{}, []*gosec.Issue{&issue}, &gosec.Metrics{}, error)
266266
Expect(err).ShouldNot(HaveOccurred())
267-
pattern := "/home/src/project/test.go,1,test,HIGH,HIGH,testcode,CWE-%s\n"
267+
pattern := "/home/src/project/test.go,1,test,HIGH,HIGH,1: testcode,CWE-%s\n"
268268
expect := fmt.Sprintf(pattern, cwe.ID)
269269
Expect(string(buf.String())).To(Equal(expect))
270270
}
@@ -278,7 +278,7 @@ var _ = Describe("Formatter", func() {
278278
buf := new(bytes.Buffer)
279279
err := CreateReport(buf, "xml", false, []string{}, []*gosec.Issue{&issue}, &gosec.Metrics{NumFiles: 0, NumLines: 0, NumNosec: 0, NumFound: 0}, error)
280280
Expect(err).ShouldNot(HaveOccurred())
281-
pattern := "Results:\n\n\n[/home/src/project/test.go:1] - %s (CWE-%s): test (Confidence: HIGH, Severity: HIGH)\n > testcode\n\n\nSummary:\n Files: 0\n Lines: 0\n Nosec: 0\n Issues: 0\n\n"
281+
pattern := "Results:\n\n\n[/home/src/project/test.go:1] - %s (CWE-%s): test (Confidence: HIGH, Severity: HIGH)\n > 1: testcode\n\n\n\nSummary:\n Files: 0\n Lines: 0\n Nosec: 0\n Issues: 0\n\n"
282282
expect := fmt.Sprintf(pattern, rule, cwe.ID)
283283
Expect(string(buf.String())).To(Equal(expect))
284284
}

0 commit comments

Comments
 (0)