diff --git a/go.sum b/go.sum index 3a38c4f..7d3c7c1 100644 --- a/go.sum +++ b/go.sum @@ -46,6 +46,7 @@ golang.org/x/crypto v0.0.0-20190907121410-71b5226ff739/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190909091759-094676da4a83 h1:mgAKeshyNqWKdENOnQsg+8dRTwZFIwFaO3HNl52sweA= golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392 h1:ACG4HJsFiNMf47Y4PeRoebLNy/2lXT9EtprMuTFWt1M= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -58,6 +59,7 @@ golang.org/x/net v0.0.0-20190909003024-a7b16738d86b/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190912160710-24e19bdeb0f2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190916140828-c8589233b77d/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190921015927-1a5e07d1ff72/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478 h1:l5EDrHhldLYb3ZRHDUhXF7Om7MvYXnkV9/iQNo1lX6g= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -75,6 +77,7 @@ golang.org/x/sys v0.0.0-20190910064555-bbd175535a8b/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190911201528-7ad0cfa0b7b5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190913121621-c3b328c6e5a7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190922100055-0a153f010e69 h1:rOhMmluY6kLMhdnrivzec6lLgaVbMHMn2ISQXJeJ5EM= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/resolve_test.go b/resolve_test.go index 15c49d2..9892d52 100644 --- a/resolve_test.go +++ b/resolve_test.go @@ -13,7 +13,6 @@ var _ = Describe("Resolve ast node to concrete value", func() { Context("when attempting to resolve an ast node", func() { It("should successfully resolve basic literal", func() { var basicLiteral *ast.BasicLit - pkg := testutils.NewTestPackage() defer pkg.Close() pkg.AddFile("foo.go", `package main; const foo = "bar"; func main(){}`) @@ -52,6 +51,47 @@ var _ = Describe("Resolve ast node to concrete value", func() { Expect(gosec.TryResolve(ident, ctx)).Should(BeTrue()) }) + It("should successfully resolve variable identifier", func() { + var ident *ast.Ident + pkg := testutils.NewTestPackage() + defer pkg.Close() + pkg.AddFile("foo.go", `package main; import "fmt"; func main(){ x := "test"; y := x; fmt.Println(y) }`) + ctx := pkg.CreateContext("foo.go") + v := testutils.NewMockVisitor() + v.Callback = func(n ast.Node, ctx *gosec.Context) bool { + if node, ok := n.(*ast.Ident); ok && node.Name == "y" { + ident = node + return false + } + return true + } + v.Context = ctx + ast.Walk(v, ctx.Root) + Expect(ident).ShouldNot(BeNil()) + Expect(gosec.TryResolve(ident, ctx)).Should(BeTrue()) + }) + + It("should successfully not resolve variable identifier with no declaration", func() { + var ident *ast.Ident + pkg := testutils.NewTestPackage() + defer pkg.Close() + pkg.AddFile("foo.go", `package main; import "fmt"; func main(){ x := "test"; y := x; fmt.Println(y) }`) + ctx := pkg.CreateContext("foo.go") + v := testutils.NewMockVisitor() + v.Callback = func(n ast.Node, ctx *gosec.Context) bool { + if node, ok := n.(*ast.Ident); ok && node.Name == "y" { + ident = node + return false + } + return true + } + v.Context = ctx + ast.Walk(v, ctx.Root) + Expect(ident).ShouldNot(BeNil()) + ident.Obj.Decl = nil + Expect(gosec.TryResolve(ident, ctx)).Should(BeFalse()) + }) + It("should successfully resolve assign statement", func() { var assign *ast.AssignStmt pkg := testutils.NewTestPackage() @@ -73,6 +113,50 @@ var _ = Describe("Resolve ast node to concrete value", func() { Expect(gosec.TryResolve(assign, ctx)).Should(BeTrue()) }) + It("should successfully not resolve assign statement without rhs", func() { + var assign *ast.AssignStmt + pkg := testutils.NewTestPackage() + defer pkg.Close() + pkg.AddFile("foo.go", `package main; const x = "bar"; func main(){ y := x; println(y) }`) + ctx := pkg.CreateContext("foo.go") + v := testutils.NewMockVisitor() + v.Callback = func(n ast.Node, ctx *gosec.Context) bool { + if node, ok := n.(*ast.AssignStmt); ok { + if id, ok := node.Lhs[0].(*ast.Ident); ok && id.Name == "y" { + assign = node + } + } + return true + } + v.Context = ctx + ast.Walk(v, ctx.Root) + Expect(assign).ShouldNot(BeNil()) + assign.Rhs = []ast.Expr{} + Expect(gosec.TryResolve(assign, ctx)).Should(BeFalse()) + }) + + It("should successfully not resolve assign statement with unsolvable rhs", func() { + var assign *ast.AssignStmt + pkg := testutils.NewTestPackage() + defer pkg.Close() + pkg.AddFile("foo.go", `package main; const x = "bar"; func main(){ y := x; println(y) }`) + ctx := pkg.CreateContext("foo.go") + v := testutils.NewMockVisitor() + v.Callback = func(n ast.Node, ctx *gosec.Context) bool { + if node, ok := n.(*ast.AssignStmt); ok { + if id, ok := node.Lhs[0].(*ast.Ident); ok && id.Name == "y" { + assign = node + } + } + return true + } + v.Context = ctx + ast.Walk(v, ctx.Root) + Expect(assign).ShouldNot(BeNil()) + assign.Rhs = []ast.Expr{&ast.CallExpr{}} + Expect(gosec.TryResolve(assign, ctx)).Should(BeFalse()) + }) + It("should successfully resolve a binary statement", func() { var target *ast.BinaryExpr pkg := testutils.NewTestPackage() @@ -112,6 +196,49 @@ var _ = Describe("Resolve ast node to concrete value", func() { Expect(value).ShouldNot(BeNil()) Expect(gosec.TryResolve(value, ctx)).Should(BeTrue()) }) + It("should successfully not resolve value spec without values", func() { + var value *ast.ValueSpec + pkg := testutils.NewTestPackage() + defer pkg.Close() + pkg.AddFile("foo.go", `package main; const x = "bar"; func main(){ var y string = x; println(y) }`) + ctx := pkg.CreateContext("foo.go") + v := testutils.NewMockVisitor() + v.Callback = func(n ast.Node, ctx *gosec.Context) bool { + if node, ok := n.(*ast.ValueSpec); ok { + if len(node.Names) == 1 && node.Names[0].Name == "y" { + value = node + } + } + return true + } + v.Context = ctx + ast.Walk(v, ctx.Root) + Expect(value).ShouldNot(BeNil()) + value.Values = []ast.Expr{} + Expect(gosec.TryResolve(value, ctx)).Should(BeFalse()) + }) + + It("should successfully not resolve value spec with unsolvable value", func() { + var value *ast.ValueSpec + pkg := testutils.NewTestPackage() + defer pkg.Close() + pkg.AddFile("foo.go", `package main; const x = "bar"; func main(){ var y string = x; println(y) }`) + ctx := pkg.CreateContext("foo.go") + v := testutils.NewMockVisitor() + v.Callback = func(n ast.Node, ctx *gosec.Context) bool { + if node, ok := n.(*ast.ValueSpec); ok { + if len(node.Names) == 1 && node.Names[0].Name == "y" { + value = node + } + } + return true + } + v.Context = ctx + ast.Walk(v, ctx.Root) + Expect(value).ShouldNot(BeNil()) + value.Values = []ast.Expr{&ast.CallExpr{}} + Expect(gosec.TryResolve(value, ctx)).Should(BeFalse()) + }) It("should successfully resolve composite literal", func() { var value *ast.CompositeLit @@ -131,5 +258,84 @@ var _ = Describe("Resolve ast node to concrete value", func() { Expect(value).ShouldNot(BeNil()) Expect(gosec.TryResolve(value, ctx)).Should(BeTrue()) }) + + It("should successfully not resolve composite literal without elst", func() { + var value *ast.CompositeLit + pkg := testutils.NewTestPackage() + defer pkg.Close() + pkg.AddFile("foo.go", `package main; func main(){ y := []string{"value1", "value2"}; println(y) }`) + ctx := pkg.CreateContext("foo.go") + v := testutils.NewMockVisitor() + v.Callback = func(n ast.Node, ctx *gosec.Context) bool { + if node, ok := n.(*ast.CompositeLit); ok { + value = node + } + return true + } + v.Context = ctx + ast.Walk(v, ctx.Root) + Expect(value).ShouldNot(BeNil()) + value.Elts = []ast.Expr{} + Expect(gosec.TryResolve(value, ctx)).Should(BeFalse()) + }) + + It("should successfully not resolve composite literal with unsolvable elst", func() { + var value *ast.CompositeLit + pkg := testutils.NewTestPackage() + defer pkg.Close() + pkg.AddFile("foo.go", `package main; func main(){ y := []string{"value1", "value2"}; println(y) }`) + ctx := pkg.CreateContext("foo.go") + v := testutils.NewMockVisitor() + v.Callback = func(n ast.Node, ctx *gosec.Context) bool { + if node, ok := n.(*ast.CompositeLit); ok { + value = node + } + return true + } + v.Context = ctx + ast.Walk(v, ctx.Root) + Expect(value).ShouldNot(BeNil()) + value.Elts = []ast.Expr{&ast.CallExpr{}} + Expect(gosec.TryResolve(value, ctx)).Should(BeFalse()) + }) + + It("should successfully not resolve call expressions", func() { + var value *ast.CallExpr + pkg := testutils.NewTestPackage() + defer pkg.Close() + pkg.AddFile("foo.go", `package main; func main(){ y := []string{"value1", "value2"}; println(y) }`) + ctx := pkg.CreateContext("foo.go") + v := testutils.NewMockVisitor() + v.Callback = func(n ast.Node, ctx *gosec.Context) bool { + if node, ok := n.(*ast.CallExpr); ok { + value = node + } + return true + } + v.Context = ctx + ast.Walk(v, ctx.Root) + Expect(value).ShouldNot(BeNil()) + Expect(gosec.TryResolve(value, ctx)).Should(BeFalse()) + }) + + It("should successfully not resolve call expressions", func() { + var value *ast.ImportSpec + pkg := testutils.NewTestPackage() + defer pkg.Close() + pkg.AddFile("foo.go", `package main; import "fmt"; func main(){ y := []string{"value1", "value2"}; fmt.Println(y) }`) + ctx := pkg.CreateContext("foo.go") + v := testutils.NewMockVisitor() + v.Callback = func(n ast.Node, ctx *gosec.Context) bool { + if node, ok := n.(*ast.ImportSpec); ok { + value = node + } + return true + } + v.Context = ctx + ast.Walk(v, ctx.Root) + Expect(value).ShouldNot(BeNil()) + Expect(gosec.TryResolve(value, ctx)).Should(BeFalse()) + }) + }) })