github.com/khulnasoft-lab/defsec@v1.0.5-0.20230827010352-5e9f46893d95/pkg/types/string.go (about)

     1  package types
     2  
     3  import (
     4  	"encoding/json"
     5  	"strings"
     6  )
     7  
     8  type StringEqualityOption int
     9  
    10  const (
    11  	IgnoreCase StringEqualityOption = iota
    12  	IsPallindrome
    13  	IgnoreWhitespace
    14  )
    15  
    16  func String(str string, m Metadata) StringValue {
    17  	return StringValue{
    18  		value:         str,
    19  		BaseAttribute: BaseAttribute{metadata: m},
    20  	}
    21  }
    22  func StringDefault(value string, m Metadata) StringValue {
    23  	b := String(value, m)
    24  	b.BaseAttribute.metadata.isDefault = true
    25  	return b
    26  }
    27  
    28  func StringUnresolvable(m Metadata) StringValue {
    29  	b := String("", m)
    30  	b.BaseAttribute.metadata.isUnresolvable = true
    31  	return b
    32  }
    33  
    34  func StringExplicit(value string, m Metadata) StringValue {
    35  	b := String(value, m)
    36  	b.BaseAttribute.metadata.isExplicit = true
    37  	return b
    38  }
    39  
    40  type StringValueList []StringValue
    41  
    42  type StringValue struct {
    43  	BaseAttribute
    44  	value string
    45  }
    46  
    47  func (l StringValueList) AsStrings() (output []string) {
    48  	for _, item := range l {
    49  		output = append(output, item.Value())
    50  	}
    51  	return output
    52  }
    53  
    54  type stringCheckFunc func(string, string) bool
    55  
    56  func (b StringValue) MarshalJSON() ([]byte, error) {
    57  	return json.Marshal(map[string]interface{}{
    58  		"value":    b.value,
    59  		"metadata": b.metadata,
    60  	})
    61  }
    62  
    63  func (b *StringValue) UnmarshalJSON(data []byte) error {
    64  	var keys map[string]interface{}
    65  	if err := json.Unmarshal(data, &keys); err != nil {
    66  		return err
    67  	}
    68  	if keys["value"] != nil {
    69  		b.value = keys["value"].(string)
    70  	}
    71  	if keys["metadata"] != nil {
    72  		raw, err := json.Marshal(keys["metadata"])
    73  		if err != nil {
    74  			return err
    75  		}
    76  		var m Metadata
    77  		if err := json.Unmarshal(raw, &m); err != nil {
    78  			return err
    79  		}
    80  		b.metadata = m
    81  	}
    82  	return nil
    83  }
    84  
    85  func (s StringValue) ToRego() interface{} {
    86  	m := s.metadata.ToRego().(map[string]interface{})
    87  	m["value"] = s.Value()
    88  	return m
    89  }
    90  
    91  func (s StringValue) IsOneOf(values ...string) bool {
    92  	if s.metadata.isUnresolvable {
    93  		return false
    94  	}
    95  	for _, value := range values {
    96  		if value == s.value {
    97  			return true
    98  		}
    99  	}
   100  	return false
   101  }
   102  
   103  func (s StringValue) GetMetadata() Metadata {
   104  	return s.metadata
   105  }
   106  
   107  func (s StringValue) Value() string {
   108  	return s.value
   109  }
   110  
   111  func (b StringValue) GetRawValue() interface{} {
   112  	return b.value
   113  }
   114  
   115  func (s StringValue) IsEmpty() bool {
   116  	if s.metadata.isUnresolvable {
   117  		return false
   118  	}
   119  	return s.value == ""
   120  }
   121  
   122  func (s StringValue) IsNotEmpty() bool {
   123  	if s.metadata.isUnresolvable {
   124  		return false
   125  	}
   126  	return s.value != ""
   127  }
   128  
   129  func (s StringValue) EqualTo(value string, equalityOptions ...StringEqualityOption) bool {
   130  	if s.metadata.isUnresolvable {
   131  		return false
   132  	}
   133  
   134  	return s.executePredicate(value, func(a, b string) bool { return a == b }, equalityOptions...)
   135  }
   136  
   137  func (s StringValue) NotEqualTo(value string, equalityOptions ...StringEqualityOption) bool {
   138  	if s.metadata.isUnresolvable {
   139  		return false
   140  	}
   141  
   142  	return !s.EqualTo(value, equalityOptions...)
   143  }
   144  
   145  func (s StringValue) StartsWith(prefix string, equalityOptions ...StringEqualityOption) bool {
   146  	if s.metadata.isUnresolvable {
   147  		return false
   148  	}
   149  
   150  	return s.executePredicate(prefix, strings.HasPrefix, equalityOptions...)
   151  }
   152  
   153  func (s StringValue) EndsWith(suffix string, equalityOptions ...StringEqualityOption) bool {
   154  	if s.metadata.isUnresolvable {
   155  		return false
   156  	}
   157  	return s.executePredicate(suffix, strings.HasSuffix, equalityOptions...)
   158  }
   159  
   160  func (s StringValue) Contains(value string, equalityOptions ...StringEqualityOption) bool {
   161  	if s.metadata.isUnresolvable {
   162  		return false
   163  	}
   164  	return s.executePredicate(value, strings.Contains, equalityOptions...)
   165  }
   166  
   167  func (s StringValue) executePredicate(value string, fn stringCheckFunc, equalityOptions ...StringEqualityOption) bool {
   168  	subjectString := s.value
   169  	searchString := value
   170  
   171  	for _, eqOpt := range equalityOptions {
   172  		switch eqOpt {
   173  		case IgnoreCase:
   174  			subjectString = strings.ToLower(subjectString)
   175  			searchString = strings.ToLower(searchString)
   176  		case IsPallindrome:
   177  			var result string
   178  			for _, v := range subjectString {
   179  				result = string(v) + result
   180  			}
   181  			subjectString = result
   182  		case IgnoreWhitespace:
   183  			subjectString = strings.ReplaceAll(subjectString, " ", "")
   184  			searchString = strings.ReplaceAll(searchString, " ", "")
   185  		}
   186  	}
   187  
   188  	return fn(subjectString, searchString)
   189  }