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 }