gosec/call_list_test.go

174 lines
4.6 KiB
Go
Raw Normal View History

package gosec_test
import (
"go/ast"
2022-01-03 17:11:35 +00:00
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/securego/gosec/v2"
"github.com/securego/gosec/v2/testutils"
)
var _ = Describe("Call List", func() {
var calls gosec.CallList
BeforeEach(func() {
calls = gosec.NewCallList()
})
It("should not return any matches when empty", func() {
Expect(calls.Contains("foo", "bar")).Should(BeFalse())
})
It("should be possible to add a single call", func() {
Expect(calls).Should(BeEmpty())
calls.Add("foo", "bar")
Expect(calls).Should(HaveLen(1))
expected := make(map[string]bool)
expected["bar"] = true
actual := map[string]bool(calls["foo"])
Expect(actual).Should(Equal(expected))
})
It("should be possible to add multiple calls at once", func() {
Expect(calls).Should(BeEmpty())
calls.AddAll("fmt", "Sprint", "Sprintf", "Printf", "Println")
expected := map[string]bool{
"Sprint": true,
"Sprintf": true,
"Printf": true,
"Println": true,
}
actual := map[string]bool(calls["fmt"])
Expect(actual).Should(Equal(expected))
})
It("should be possible to add pointer call", func() {
Expect(calls).Should(BeEmpty())
calls.Add("*bytes.Buffer", "WriteString")
actual := calls.ContainsPointer("*bytes.Buffer", "WriteString")
Expect(actual).Should(BeTrue())
})
It("should be possible to check pointer call", func() {
Expect(calls).Should(BeEmpty())
calls.Add("bytes.Buffer", "WriteString")
actual := calls.ContainsPointer("*bytes.Buffer", "WriteString")
Expect(actual).Should(BeTrue())
})
It("should not return a match if none are present", func() {
calls.Add("ioutil", "Copy")
Expect(calls.Contains("fmt", "Println")).Should(BeFalse())
})
It("should match a call based on selector and ident", func() {
calls.Add("ioutil", "Copy")
Expect(calls.Contains("ioutil", "Copy")).Should(BeTrue())
})
It("should match a package call expression", func() {
// Create file to be scanned
pkg := testutils.NewTestPackage()
defer pkg.Close()
pkg.AddFile("md5.go", testutils.SampleCodeG401[0].Code[0])
ctx := pkg.CreateContext("md5.go")
// Search for md5.New()
calls.Add("crypto/md5", "New")
// Stub out visitor and count number of matched call expr
matched := 0
v := testutils.NewMockVisitor()
v.Context = ctx
v.Callback = func(n ast.Node, ctx *gosec.Context) bool {
if _, ok := n.(*ast.CallExpr); ok && calls.ContainsPkgCallExpr(n, ctx, false) != nil {
matched++
}
return true
}
ast.Walk(v, ctx.Root)
Expect(matched).Should(Equal(1))
})
It("should match a package call expression", func() {
// Create file to be scanned
pkg := testutils.NewTestPackage()
defer pkg.Close()
pkg.AddFile("cipher.go", testutils.SampleCodeG405[0].Code[0])
ctx := pkg.CreateContext("cipher.go")
// Search for des.NewCipher()
calls.Add("crypto/des", "NewCipher")
// Stub out visitor and count number of matched call expr
matched := 0
v := testutils.NewMockVisitor()
v.Context = ctx
v.Callback = func(n ast.Node, ctx *gosec.Context) bool {
if _, ok := n.(*ast.CallExpr); ok && calls.ContainsPkgCallExpr(n, ctx, false) != nil {
matched++
}
return true
}
ast.Walk(v, ctx.Root)
Expect(matched).Should(Equal(1))
})
It("should match a package call expression", func() {
// Create file to be scanned
pkg := testutils.NewTestPackage()
defer pkg.Close()
pkg.AddFile("md4.go", testutils.SampleCodeG406[0].Code[0])
ctx := pkg.CreateContext("md4.go")
// Search for md4.New()
calls.Add("golang.org/x/crypto/md4", "New")
// Stub out visitor and count number of matched call expr
matched := 0
v := testutils.NewMockVisitor()
v.Context = ctx
v.Callback = func(n ast.Node, ctx *gosec.Context) bool {
if _, ok := n.(*ast.CallExpr); ok && calls.ContainsPkgCallExpr(n, ctx, false) != nil {
matched++
}
return true
}
ast.Walk(v, ctx.Root)
Expect(matched).Should(Equal(1))
})
It("should match a call expression", func() {
// Create file to be scanned
pkg := testutils.NewTestPackage()
defer pkg.Close()
pkg.AddFile("main.go", testutils.SampleCodeG104[6].Code[0])
ctx := pkg.CreateContext("main.go")
calls.Add("bytes.Buffer", "WriteString")
calls.Add("strings.Builder", "WriteString")
calls.Add("io.Pipe", "CloseWithError")
calls.Add("fmt", "Fprintln")
// Stub out visitor and count number of matched call expr
matched := 0
v := testutils.NewMockVisitor()
v.Context = ctx
v.Callback = func(n ast.Node, ctx *gosec.Context) bool {
if _, ok := n.(*ast.CallExpr); ok && calls.ContainsCallExpr(n, ctx) != nil {
matched++
}
return true
}
ast.Walk(v, ctx.Root)
Expect(matched).Should(Equal(5))
})
})