From c1970ff5c96345bcf21c8d0042dacdb9c434a55e Mon Sep 17 00:00:00 2001 From: Cosmin Cojocar Date: Fri, 4 Oct 2019 13:07:53 +0200 Subject: [PATCH] Handle the ValueSpec when trying to resolve an AST tree node Signed-off-by: Cosmin Cojocar --- resolve.go | 31 +++++++++++++++++++++++-------- resolve_test.go | 22 ++++++++++++++++++++-- 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/resolve.go b/resolve.go index 3c20dd3..9030133 100644 --- a/resolve.go +++ b/resolve.go @@ -14,10 +14,11 @@ package gosec -import "go/ast" +import ( + "go/ast" +) func resolveIdent(n *ast.Ident, c *Context) bool { - if n.Obj == nil || n.Obj.Kind != ast.Var { return true } @@ -27,7 +28,22 @@ func resolveIdent(n *ast.Ident, c *Context) bool { return false } +func resolveValueSpec(n *ast.ValueSpec, c *Context) bool { + if len(n.Values) == 0 { + return false + } + for _, value := range n.Values { + if !TryResolve(value, c) { + return false + } + } + return true +} + func resolveAssign(n *ast.AssignStmt, c *Context) bool { + if len(n.Rhs) == 0 { + return false + } for _, arg := range n.Rhs { if !TryResolve(arg, c) { return false @@ -37,6 +53,9 @@ func resolveAssign(n *ast.AssignStmt, c *Context) bool { } func resolveCompLit(n *ast.CompositeLit, c *Context) bool { + if len(n.Elts) == 0 { + return false + } for _, arg := range n.Elts { if !TryResolve(arg, c) { return false @@ -61,22 +80,18 @@ func TryResolve(n ast.Node, c *Context) bool { switch node := n.(type) { case *ast.BasicLit: return true - case *ast.CompositeLit: return resolveCompLit(node, c) - case *ast.Ident: return resolveIdent(node, c) - + case *ast.ValueSpec: + return resolveValueSpec(node, c) case *ast.AssignStmt: return resolveAssign(node, c) - case *ast.CallExpr: return resolveCallExpr(node, c) - case *ast.BinaryExpr: return resolveBinExpr(node, c) } - return false } diff --git a/resolve_test.go b/resolve_test.go index afc0316..233f49b 100644 --- a/resolve_test.go +++ b/resolve_test.go @@ -91,8 +91,26 @@ var _ = Describe("Resolve ast node to concrete value", func() { Expect(target).ShouldNot(BeNil()) Expect(gosec.TryResolve(target, ctx)).Should(BeTrue()) }) - - // TODO: It should resolve call expressions + It("should successfully resolve value spec", 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()) + Expect(gosec.TryResolve(value, ctx)).Should(BeTrue()) + }) })