github.com/khulnasoft-lab/defsec@v1.0.5-0.20230827010352-5e9f46893d95/pkg/scanners/azure/expressions/node.go (about) 1 package expressions 2 3 import ( 4 "github.com/khulnasoft-lab/defsec/pkg/scanners/azure/functions" 5 ) 6 7 type Node interface { 8 Evaluate(deploymentProvider functions.DeploymentData) interface{} 9 } 10 11 type expressionValue struct { 12 val interface{} 13 } 14 15 func (e expressionValue) Evaluate(deploymentProvider functions.DeploymentData) interface{} { 16 if f, ok := e.val.(expression); ok { 17 return f.Evaluate(deploymentProvider) 18 } 19 return e.val 20 } 21 22 type expression struct { 23 name string 24 args []Node 25 } 26 27 func (f expression) Evaluate(deploymentProvider functions.DeploymentData) interface{} { 28 args := make([]interface{}, len(f.args)) 29 for i, arg := range f.args { 30 args[i] = arg.Evaluate(deploymentProvider) 31 } 32 33 return functions.Evaluate(deploymentProvider, f.name, args...) 34 } 35 36 func NewExpressionTree(code string) (Node, error) { 37 tokens, err := lex(code) 38 if err != nil { 39 return nil, err 40 } 41 42 // create a walker for the nodes 43 tw := newTokenWalker(tokens) 44 45 // generate the root function 46 return newFunctionNode(tw), nil 47 } 48 49 func newFunctionNode(tw *tokenWalker) Node { 50 funcNode := &expression{ 51 name: tw.pop().Data.(string), 52 } 53 54 for tw.hasNext() { 55 token := tw.pop() 56 if token == nil { 57 break 58 } 59 60 switch token.Type { 61 case TokenCloseParen: 62 return funcNode 63 case TokenName: 64 if tw.peek().Type == TokenOpenParen { 65 // this is a function, unwind 1 66 tw.unPop() 67 funcNode.args = append(funcNode.args, newFunctionNode(tw)) 68 } 69 case TokenLiteralString, TokenLiteralInteger, TokenLiteralFloat: 70 funcNode.args = append(funcNode.args, expressionValue{token.Data}) 71 } 72 73 } 74 return funcNode 75 }