Skip to content

Commit d1467ac

Browse files
ccojocarCosmin Cojocar
authored and
Cosmin Cojocar
committed
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

File tree

3 files changed

+62
-24
lines changed

3 files changed

+62
-24
lines changed

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)