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  }