github.com/DataDog/datadog-agent/pkg/security/secl@v0.55.0-devel.0.20240517055856-10c4965fea94/compiler/eval/state.go (about)

     1  // Unless explicitly stated otherwise all files in this repository are licensed
     2  // under the Apache License Version 2.0.
     3  // This product includes software developed at Datadog (https://www.datadoghq.com/).
     4  // Copyright 2016-present Datadog, Inc.
     5  
     6  // Package eval holds eval related files
     7  package eval
     8  
     9  import (
    10  	"fmt"
    11  	"regexp"
    12  )
    13  
    14  type registerInfo struct {
    15  	iterator  Iterator
    16  	field     Field
    17  	subFields map[Field]bool
    18  }
    19  
    20  // StateRegexpCache is used to cache regexps used in the rule compilation process
    21  type StateRegexpCache struct {
    22  	arraySubscriptFindRE    *regexp.Regexp
    23  	arraySubscriptReplaceRE *regexp.Regexp
    24  }
    25  
    26  // State defines the current state of the rule compilation
    27  type State struct {
    28  	model           Model
    29  	field           Field
    30  	events          map[EventType]bool
    31  	fieldValues     map[Field][]FieldValue
    32  	macros          map[MacroID]*MacroEvaluator
    33  	registersInfo   map[RegisterID]*registerInfo
    34  	registerCounter int
    35  	regexpCache     StateRegexpCache
    36  }
    37  
    38  func (s *State) newAnonymousRegID() string {
    39  	id := s.registerCounter
    40  	s.registerCounter++
    41  	// @ is not a valid register name from the parser, this guarantees unicity
    42  	return fmt.Sprintf("@anon_%d", id)
    43  }
    44  
    45  // UpdateFields updates the fields used in the rule
    46  func (s *State) UpdateFields(field Field) {
    47  	if _, ok := s.fieldValues[field]; !ok {
    48  		s.fieldValues[field] = []FieldValue{}
    49  	}
    50  }
    51  
    52  // UpdateFieldValues updates the field values
    53  func (s *State) UpdateFieldValues(field Field, value FieldValue) error {
    54  	values, ok := s.fieldValues[field]
    55  	if !ok {
    56  		values = []FieldValue{}
    57  	}
    58  	for _, v := range values {
    59  		// compare only comparable
    60  		switch v.Value.(type) {
    61  		case int, uint, int64, uint64, string:
    62  			if v == value {
    63  				return nil
    64  			}
    65  		}
    66  	}
    67  
    68  	values = append(values, value)
    69  	s.fieldValues[field] = values
    70  	return s.model.ValidateField(field, value)
    71  }
    72  
    73  // NewState returns a new State
    74  func NewState(model Model, field Field, macros map[MacroID]*MacroEvaluator) *State {
    75  	if macros == nil {
    76  		macros = make(map[MacroID]*MacroEvaluator)
    77  	}
    78  	return &State{
    79  		field:         field,
    80  		macros:        macros,
    81  		model:         model,
    82  		events:        make(map[EventType]bool),
    83  		fieldValues:   make(map[Field][]FieldValue),
    84  		registersInfo: make(map[RegisterID]*registerInfo),
    85  	}
    86  }