Skip to content

Commit 6a41fb9

Browse files
authored
Fix #714 (#733)
1 parent c95e9c2 commit 6a41fb9

File tree

2 files changed

+12
-132
lines changed

2 files changed

+12
-132
lines changed

rules/bad_defer.go

+4-41
Original file line numberDiff line numberDiff line change
@@ -38,54 +38,17 @@ func contains(methods []string, method string) bool {
3838
func (r *badDefer) Match(n ast.Node, c *gosec.Context) (*gosec.Issue, error) {
3939
if deferStmt, ok := n.(*ast.DeferStmt); ok {
4040
for _, deferTyp := range r.types {
41-
if issue := r.checkChild(n, c, deferStmt.Call, deferTyp); issue != nil {
42-
return issue, nil
43-
}
44-
if issue := r.checkFunction(n, c, deferStmt, deferTyp); issue != nil {
45-
return issue, nil
41+
if typ, method, err := gosec.GetCallInfo(deferStmt.Call, c); err == nil {
42+
if normalize(typ) == deferTyp.typ && contains(deferTyp.methods, method) {
43+
return gosec.NewIssue(c, n, r.ID(), fmt.Sprintf(r.What, method, typ), r.Severity, r.Confidence), nil
44+
}
4645
}
4746
}
4847
}
4948

5049
return nil, nil
5150
}
5251

53-
func (r *badDefer) checkChild(n ast.Node, c *gosec.Context, callExp *ast.CallExpr, deferTyp deferType) *gosec.Issue {
54-
if typ, method, err := gosec.GetCallInfo(callExp, c); err == nil {
55-
if normalize(typ) == deferTyp.typ && contains(deferTyp.methods, method) {
56-
return gosec.NewIssue(c, n, r.ID(), fmt.Sprintf(r.What, method, typ), r.Severity, r.Confidence)
57-
}
58-
}
59-
return nil
60-
}
61-
62-
func (r *badDefer) checkFunction(n ast.Node, c *gosec.Context, deferStmt *ast.DeferStmt, deferTyp deferType) *gosec.Issue {
63-
if anonFunc, isAnonFunc := deferStmt.Call.Fun.(*ast.FuncLit); isAnonFunc {
64-
for _, subElem := range anonFunc.Body.List {
65-
if issue := r.checkStmt(n, c, subElem, deferTyp); issue != nil {
66-
return issue
67-
}
68-
}
69-
}
70-
return nil
71-
}
72-
73-
func (r *badDefer) checkStmt(n ast.Node, c *gosec.Context, subElem ast.Stmt, deferTyp deferType) *gosec.Issue {
74-
switch stmt := subElem.(type) {
75-
case *ast.AssignStmt:
76-
for _, rh := range stmt.Rhs {
77-
if e, isCallExp := rh.(*ast.CallExpr); isCallExp {
78-
return r.checkChild(n, c, e, deferTyp)
79-
}
80-
}
81-
case *ast.IfStmt:
82-
if s, is := stmt.Init.(*ast.AssignStmt); is {
83-
return r.checkStmt(n, c, s, deferTyp)
84-
}
85-
}
86-
return nil
87-
}
88-
8952
// NewDeferredClosing detects unsafe defer of error returning methods
9053
func NewDeferredClosing(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
9154
return &badDefer{

testutils/source.go

+8-91
Original file line numberDiff line numberDiff line change
@@ -2192,120 +2192,37 @@ func main() {
21922192
// SampleCodeG307 - Unsafe defer of os.Close
21932193
SampleCodeG307 = []CodeSample{
21942194
{[]string{`package main
2195-
21962195
import (
2196+
"bufio"
21972197
"fmt"
21982198
"io/ioutil"
21992199
"os"
22002200
)
2201-
22022201
func check(e error) {
22032202
if e != nil {
22042203
panic(e)
22052204
}
22062205
}
2207-
22082206
func main() {
2209-
22102207
d1 := []byte("hello\ngo\n")
22112208
err := ioutil.WriteFile("/tmp/dat1", d1, 0744)
22122209
check(err)
2213-
22142210
allowed := ioutil.WriteFile("/tmp/dat1", d1, 0600)
22152211
check(allowed)
2216-
22172212
f, err := os.Create("/tmp/dat2")
22182213
check(err)
2219-
22202214
defer f.Close()
2221-
2222-
d2 := []byte{115, 111, 109, 101, 10}
2223-
n2, err := f.Write(d2)
2224-
2225-
defer check(err)
2226-
fmt.Printf("wrote %d bytes\n", n2)
2227-
2228-
}`}, 1, gosec.NewConfig()},
2229-
{[]string{`package main
2230-
2231-
import (
2232-
"fmt"
2233-
"io/ioutil"
2234-
"log"
2235-
"os"
2236-
)
2237-
2238-
func check(e error) {
2239-
if e != nil {
2240-
panic(e)
2241-
}
2242-
}
2243-
2244-
func main() {
2245-
2246-
d1 := []byte("hello\ngo\n")
2247-
err := ioutil.WriteFile("/tmp/dat1", d1, 0744)
2248-
check(err)
2249-
2250-
allowed := ioutil.WriteFile("/tmp/dat1", d1, 0600)
2251-
check(allowed)
2252-
2253-
f, err := os.Create("/tmp/dat2")
2254-
check(err)
2255-
2256-
defer func() {
2257-
if err := f.Close(); err != nil {
2258-
log.Println(err)
2259-
}
2260-
}()
2261-
22622215
d2 := []byte{115, 111, 109, 101, 10}
22632216
n2, err := f.Write(d2)
2264-
22652217
defer check(err)
22662218
fmt.Printf("wrote %d bytes\n", n2)
2267-
2268-
}`}, 1, gosec.NewConfig()},
2269-
{[]string{`package main
2270-
2271-
import (
2272-
"fmt"
2273-
"io/ioutil"
2274-
"log"
2275-
"os"
2276-
)
2277-
2278-
func check(e error) {
2279-
if e != nil {
2280-
panic(e)
2281-
}
2282-
}
2283-
2284-
func main() {
2285-
2286-
d1 := []byte("hello\ngo\n")
2287-
err := ioutil.WriteFile("/tmp/dat1", d1, 0744)
2288-
check(err)
2289-
2290-
allowed := ioutil.WriteFile("/tmp/dat1", d1, 0600)
2291-
check(allowed)
2292-
2293-
f, err := os.Create("/tmp/dat2")
2294-
check(err)
2295-
2296-
defer func() {
2297-
err := f.Close()
2298-
if err != nil {
2299-
log.Println(err)
2300-
}
2301-
}()
2302-
2303-
d2 := []byte{115, 111, 109, 101, 10}
2304-
n2, err := f.Write(d2)
2305-
2306-
defer check(err)
2307-
fmt.Printf("wrote %d bytes\n", n2)
2308-
2219+
n3, err := f.WriteString("writes\n")
2220+
fmt.Printf("wrote %d bytes\n", n3)
2221+
f.Sync()
2222+
w := bufio.NewWriter(f)
2223+
n4, err := w.WriteString("buffered\n")
2224+
fmt.Printf("wrote %d bytes\n", n4)
2225+
w.Flush()
23092226
}`}, 1, gosec.NewConfig()},
23102227
}
23112228

0 commit comments

Comments
 (0)