github.com/DataDog/datadog-agent/pkg/security/secl@v0.55.0-devel.0.20240517055856-10c4965fea94/compiler/eval/eval.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 //go:generate operators -output eval_operators.go 7 8 // Package eval holds eval related files 9 package eval 10 11 import ( 12 "errors" 13 "fmt" 14 "reflect" 15 "regexp" 16 "strconv" 17 "strings" 18 19 "github.com/alecthomas/participle/lexer" 20 21 "github.com/DataDog/datadog-agent/pkg/security/secl/compiler/ast" 22 ) 23 24 // defines factor applied by specific operator 25 const ( 26 FunctionWeight = 5 27 InArrayWeight = 10 28 HandlerWeight = 50 29 RegexpWeight = 100 30 InPatternArrayWeight = 1000 31 IteratorWeight = 2000 32 ) 33 34 // BoolEvalFnc describe a eval function return a boolean 35 type BoolEvalFnc = func(ctx *Context) bool 36 37 func extractField(field string, state *State) (Field, Field, RegisterID, error) { 38 if state.regexpCache.arraySubscriptFindRE == nil { 39 state.regexpCache.arraySubscriptFindRE = regexp.MustCompile(`\[([^\]]*)\]`) 40 } 41 if state.regexpCache.arraySubscriptReplaceRE == nil { 42 state.regexpCache.arraySubscriptReplaceRE = regexp.MustCompile(`(.+)\[[^\]]+\](.*)`) 43 } 44 45 var regID RegisterID 46 ids := state.regexpCache.arraySubscriptFindRE.FindStringSubmatch(field) 47 48 switch len(ids) { 49 case 0: 50 return field, "", "", nil 51 case 2: 52 regID = ids[1] 53 default: 54 return "", "", "", fmt.Errorf("wrong register format for fields: %s", field) 55 } 56 57 resField := state.regexpCache.arraySubscriptReplaceRE.ReplaceAllString(field, `$1$2`) 58 itField := state.regexpCache.arraySubscriptReplaceRE.ReplaceAllString(field, `$1`) 59 60 return resField, itField, regID, nil 61 } 62 63 type ident struct { 64 Pos lexer.Position 65 Ident *string 66 } 67 68 func identToEvaluator(obj *ident, opts *Opts, state *State) (interface{}, lexer.Position, error) { 69 if accessor, ok := opts.Constants[*obj.Ident]; ok { 70 return accessor, obj.Pos, nil 71 } 72 73 if state.macros != nil { 74 if macro, ok := state.macros[*obj.Ident]; ok { 75 return macro.Value, obj.Pos, nil 76 } 77 } 78 79 field, itField, regID, err := extractField(*obj.Ident, state) 80 if err != nil { 81 return nil, obj.Pos, err 82 } 83 84 // transform extracted field to support legacy SECL fields 85 if opts.LegacyFields != nil { 86 if newField, ok := opts.LegacyFields[field]; ok { 87 field = newField 88 } 89 if newField, ok := opts.LegacyFields[field]; ok { 90 itField = newField 91 } 92 } 93 94 // extract iterator 95 var iterator Iterator 96 if itField != "" { 97 if iterator, err = state.model.GetIterator(itField); err != nil { 98 return nil, obj.Pos, err 99 } 100 } else { 101 // detect whether a iterator is along the path 102 var candidate string 103 for _, node := range strings.Split(field, ".") { 104 if candidate == "" { 105 candidate = node 106 } else { 107 candidate = candidate + "." + node 108 } 109 110 iterator, err = state.model.GetIterator(candidate) 111 if err == nil { 112 break 113 } 114 } 115 } 116 117 if iterator != nil { 118 // Force "_" register for now. 119 if regID != "" && regID != "_" { 120 return nil, obj.Pos, NewRegisterNameNotAllowed(obj.Pos, regID, errors.New("only `_` is supported")) 121 } 122 123 // regID not specified or `_` generate one 124 if regID == "" || regID == "_" { 125 regID = state.newAnonymousRegID() 126 } 127 128 if info, exists := state.registersInfo[regID]; exists { 129 if info.field != itField { 130 return nil, obj.Pos, NewRegisterMultipleFields(obj.Pos, regID, errors.New("used by multiple fields")) 131 } 132 133 info.subFields[field] = true 134 } else { 135 info = ®isterInfo{ 136 field: itField, 137 iterator: iterator, 138 subFields: map[Field]bool{ 139 field: true, 140 }, 141 } 142 state.registersInfo[regID] = info 143 } 144 } 145 146 accessor, err := state.model.GetEvaluator(field, regID) 147 if err != nil { 148 return nil, obj.Pos, err 149 } 150 151 state.UpdateFields(field) 152 153 return accessor, obj.Pos, nil 154 } 155 156 func arrayToEvaluator(array *ast.Array, opts *Opts, state *State) (interface{}, lexer.Position, error) { 157 if len(array.Numbers) != 0 { 158 var evaluator IntArrayEvaluator 159 evaluator.AppendValues(array.Numbers...) 160 return &evaluator, array.Pos, nil 161 } else if len(array.StringMembers) != 0 { 162 var evaluator StringValuesEvaluator 163 evaluator.AppendMembers(array.StringMembers...) 164 return &evaluator, array.Pos, nil 165 } else if array.Ident != nil { 166 if state.macros != nil { 167 if macro, ok := state.macros[*array.Ident]; ok { 168 return macro.Value, array.Pos, nil 169 } 170 } 171 172 // could be an iterator 173 return identToEvaluator(&ident{Pos: array.Pos, Ident: array.Ident}, opts, state) 174 } else if array.Variable != nil { 175 varName, ok := isVariableName(*array.Variable) 176 if !ok { 177 return nil, array.Pos, NewError(array.Pos, "invalid variable name '%s'", *array.Variable) 178 } 179 return evaluatorFromVariable(varName, array.Pos, opts) 180 } else if array.CIDR != nil { 181 var values CIDRValues 182 if err := values.AppendCIDR(*array.CIDR); err != nil { 183 return nil, array.Pos, NewError(array.Pos, "invalid CIDR '%s'", *array.CIDR) 184 } 185 186 evaluator := &CIDRValuesEvaluator{ 187 Value: values, 188 ValueType: IPNetValueType, 189 } 190 return evaluator, array.Pos, nil 191 } else if len(array.CIDRMembers) != 0 { 192 var values CIDRValues 193 for _, member := range array.CIDRMembers { 194 if member.CIDR != nil { 195 if err := values.AppendCIDR(*member.CIDR); err != nil { 196 return nil, array.Pos, NewError(array.Pos, "invalid CIDR '%s'", *member.CIDR) 197 } 198 } else if member.IP != nil { 199 if err := values.AppendIP(*member.IP); err != nil { 200 return nil, array.Pos, NewError(array.Pos, "invalid IP '%s'", *member.IP) 201 } 202 } 203 } 204 205 evaluator := &CIDRValuesEvaluator{ 206 Value: values, 207 ValueType: IPNetValueType, 208 } 209 return evaluator, array.Pos, nil 210 } 211 212 return nil, array.Pos, NewError(array.Pos, "unknown array element type") 213 } 214 215 func isVariableName(str string) (string, bool) { 216 if strings.HasPrefix(str, "${") && strings.HasSuffix(str, "}") { 217 return str[2 : len(str)-1], true 218 } 219 return "", false 220 } 221 222 func evaluatorFromVariable(varname string, pos lexer.Position, opts *Opts) (interface{}, lexer.Position, error) { 223 variable := opts.VariableStore.Get(varname) 224 if variable == nil { 225 return nil, pos, NewError(pos, "variable '%s' doesn't exist", varname) 226 } 227 228 return variable.GetEvaluator(), pos, nil 229 } 230 231 func stringEvaluatorFromVariable(str string, pos lexer.Position, opts *Opts) (interface{}, lexer.Position, error) { 232 var evaluators []*StringEvaluator 233 234 doLoc := func(sub string) error { 235 if varname, ok := isVariableName(sub); ok { 236 evaluator, pos, err := evaluatorFromVariable(varname, pos, opts) 237 if err != nil { 238 return err 239 } 240 241 switch evaluator := evaluator.(type) { 242 case *StringArrayEvaluator: 243 evaluators = append(evaluators, &StringEvaluator{ 244 EvalFnc: func(ctx *Context) string { 245 return strings.Join(evaluator.EvalFnc(ctx), ",") 246 }}) 247 case *IntArrayEvaluator: 248 evaluators = append(evaluators, &StringEvaluator{ 249 EvalFnc: func(ctx *Context) string { 250 var result string 251 for i, number := range evaluator.EvalFnc(ctx) { 252 if i != 0 { 253 result += "," 254 } 255 result += strconv.FormatInt(int64(number), 10) 256 } 257 return result 258 }}) 259 case *StringEvaluator: 260 evaluators = append(evaluators, evaluator) 261 case *IntEvaluator: 262 evaluators = append(evaluators, &StringEvaluator{ 263 EvalFnc: func(ctx *Context) string { 264 return strconv.FormatInt(int64(evaluator.EvalFnc(ctx)), 10) 265 }}) 266 default: 267 return NewError(pos, "variable type not supported '%s'", varname) 268 } 269 } else { 270 evaluators = append(evaluators, &StringEvaluator{Value: sub}) 271 } 272 273 return nil 274 } 275 276 var last int 277 for _, loc := range variableRegex.FindAllIndex([]byte(str), -1) { 278 if loc[0] > 0 { 279 if err := doLoc(str[last:loc[0]]); err != nil { 280 return nil, pos, err 281 } 282 } 283 if err := doLoc(str[loc[0]:loc[1]]); err != nil { 284 return nil, pos, err 285 } 286 last = loc[1] 287 } 288 if last < len(str) { 289 if err := doLoc(str[last:]); err != nil { 290 return nil, pos, err 291 } 292 } 293 294 return &StringEvaluator{ 295 Value: str, 296 ValueType: VariableValueType, 297 EvalFnc: func(ctx *Context) string { 298 var result string 299 for _, evaluator := range evaluators { 300 if evaluator.EvalFnc != nil { 301 result += evaluator.EvalFnc(ctx) 302 } else { 303 result += evaluator.Value 304 } 305 } 306 return result 307 }, 308 }, pos, nil 309 } 310 311 // StringEqualsWrapper makes use of operator overrides 312 func StringEqualsWrapper(a *StringEvaluator, b *StringEvaluator, state *State) (*BoolEvaluator, error) { 313 var evaluator *BoolEvaluator 314 var err error 315 316 if a.OpOverrides != nil && a.OpOverrides.StringEquals != nil { 317 evaluator, err = a.OpOverrides.StringEquals(a, b, state) 318 } else if b.OpOverrides != nil && b.OpOverrides.StringEquals != nil { 319 evaluator, err = b.OpOverrides.StringEquals(a, b, state) 320 } else { 321 evaluator, err = StringEquals(a, b, state) 322 } 323 if err != nil { 324 return nil, err 325 } 326 327 return evaluator, nil 328 } 329 330 // StringArrayContainsWrapper makes use of operator overrides 331 func StringArrayContainsWrapper(a *StringEvaluator, b *StringArrayEvaluator, state *State) (*BoolEvaluator, error) { 332 var evaluator *BoolEvaluator 333 var err error 334 335 if a.OpOverrides != nil && a.OpOverrides.StringArrayContains != nil { 336 evaluator, err = a.OpOverrides.StringArrayContains(a, b, state) 337 } else if b.OpOverrides != nil && b.OpOverrides.StringArrayContains != nil { 338 evaluator, err = b.OpOverrides.StringArrayContains(a, b, state) 339 } else { 340 evaluator, err = StringArrayContains(a, b, state) 341 } 342 if err != nil { 343 return nil, err 344 } 345 346 return evaluator, nil 347 } 348 349 // StringValuesContainsWrapper makes use of operator overrides 350 func StringValuesContainsWrapper(a *StringEvaluator, b *StringValuesEvaluator, state *State) (*BoolEvaluator, error) { 351 var evaluator *BoolEvaluator 352 var err error 353 354 if a.OpOverrides != nil && a.OpOverrides.StringValuesContains != nil { 355 evaluator, err = a.OpOverrides.StringValuesContains(a, b, state) 356 } else { 357 evaluator, err = StringValuesContains(a, b, state) 358 } 359 if err != nil { 360 return nil, err 361 } 362 363 return evaluator, nil 364 } 365 366 // StringArrayMatchesWrapper makes use of operator overrides 367 func StringArrayMatchesWrapper(a *StringArrayEvaluator, b *StringValuesEvaluator, state *State) (*BoolEvaluator, error) { 368 var evaluator *BoolEvaluator 369 var err error 370 371 if a.OpOverrides != nil && a.OpOverrides.StringArrayMatches != nil { 372 evaluator, err = a.OpOverrides.StringArrayMatches(a, b, state) 373 } else { 374 evaluator, err = StringArrayMatches(a, b, state) 375 } 376 if err != nil { 377 return nil, err 378 } 379 380 return evaluator, nil 381 } 382 383 func nodeToEvaluator(obj interface{}, opts *Opts, state *State) (interface{}, lexer.Position, error) { 384 var err error 385 var boolEvaluator *BoolEvaluator 386 var pos lexer.Position 387 var cmp, unary, next interface{} 388 389 switch obj := obj.(type) { 390 case *ast.BooleanExpression: 391 return nodeToEvaluator(obj.Expression, opts, state) 392 case *ast.Expression: 393 cmp, pos, err = nodeToEvaluator(obj.Comparison, opts, state) 394 if err != nil { 395 return nil, pos, err 396 } 397 398 if obj.Op != nil { 399 cmpBool, ok := cmp.(*BoolEvaluator) 400 if !ok { 401 return nil, obj.Pos, NewTypeError(obj.Pos, reflect.Bool) 402 } 403 404 next, pos, err = nodeToEvaluator(obj.Next, opts, state) 405 if err != nil { 406 return nil, pos, err 407 } 408 409 nextBool, ok := next.(*BoolEvaluator) 410 if !ok { 411 return nil, pos, NewTypeError(pos, reflect.Bool) 412 } 413 414 switch *obj.Op { 415 case "||", "or": 416 boolEvaluator, err = Or(cmpBool, nextBool, state) 417 if err != nil { 418 return nil, obj.Pos, err 419 } 420 return boolEvaluator, obj.Pos, nil 421 case "&&", "and": 422 boolEvaluator, err = And(cmpBool, nextBool, state) 423 if err != nil { 424 return nil, obj.Pos, err 425 } 426 return boolEvaluator, obj.Pos, nil 427 } 428 return nil, pos, NewOpUnknownError(obj.Pos, *obj.Op) 429 } 430 return cmp, obj.Pos, nil 431 case *ast.BitOperation: 432 unary, pos, err = nodeToEvaluator(obj.Unary, opts, state) 433 if err != nil { 434 return nil, pos, err 435 } 436 437 if obj.Op != nil { 438 bitInt, ok := unary.(*IntEvaluator) 439 if !ok { 440 return nil, obj.Pos, NewTypeError(obj.Pos, reflect.Int) 441 } 442 443 next, pos, err = nodeToEvaluator(obj.Next, opts, state) 444 if err != nil { 445 return nil, pos, err 446 } 447 448 nextInt, ok := next.(*IntEvaluator) 449 if !ok { 450 return nil, pos, NewTypeError(pos, reflect.Int) 451 } 452 453 switch *obj.Op { 454 case "&": 455 intEvaluator, err := IntAnd(bitInt, nextInt, state) 456 if err != nil { 457 return nil, pos, err 458 } 459 return intEvaluator, obj.Pos, nil 460 case "|": 461 IntEvaluator, err := IntOr(bitInt, nextInt, state) 462 if err != nil { 463 return nil, pos, err 464 } 465 return IntEvaluator, obj.Pos, nil 466 case "^": 467 IntEvaluator, err := IntXor(bitInt, nextInt, state) 468 if err != nil { 469 return nil, pos, err 470 } 471 return IntEvaluator, obj.Pos, nil 472 } 473 return nil, pos, NewOpUnknownError(obj.Pos, *obj.Op) 474 } 475 return unary, obj.Pos, nil 476 477 case *ast.ArithmeticOperation: 478 // Process the first operand 479 first, pos, err := nodeToEvaluator(obj.First, opts, state) 480 if err != nil { 481 return nil, pos, err 482 } 483 484 // If it's just one element (is a bitoperation: maybe a string, an int ....) 485 if len(obj.Rest) == 0 { 486 return first, obj.Pos, nil 487 } 488 489 // Else it's an operation, so it must be an int 490 currInt, ok := first.(*IntEvaluator) 491 if !ok { 492 return nil, obj.Pos, NewTypeError(obj.Pos, reflect.Int) 493 } 494 495 // Process the remaining operations and operands 496 for _, arithElem := range obj.Rest { 497 // Handle the operand 498 operand, pos, err := nodeToEvaluator(arithElem.Operand, opts, state) 499 if err != nil { 500 return nil, pos, err 501 } 502 operandInt, ok := operand.(*IntEvaluator) 503 if !ok { 504 return nil, pos, NewTypeError(pos, reflect.Int) 505 } 506 507 // Perform the operation on the current and next operands 508 switch arithElem.Op { 509 case "+": 510 currInt, err = IntPlus(currInt, operandInt, state) 511 if err != nil { 512 return nil, pos, err 513 } 514 515 case "-": 516 currInt, err = IntMinus(currInt, operandInt, state) 517 if err != nil { 518 return nil, pos, err 519 } 520 } 521 } 522 523 // Return the final result after processing all operations and operands 524 currInt.isFromArithmeticOperation = true 525 return currInt, obj.Pos, nil 526 527 case *ast.Comparison: 528 unary, pos, err = nodeToEvaluator(obj.ArithmeticOperation, opts, state) 529 if err != nil { 530 return nil, pos, err 531 } 532 533 if obj.ArrayComparison != nil { 534 next, pos, err = nodeToEvaluator(obj.ArrayComparison, opts, state) 535 if err != nil { 536 return nil, pos, err 537 } 538 539 switch unary := unary.(type) { 540 case *BoolEvaluator: 541 switch nextBool := next.(type) { 542 case *BoolArrayEvaluator: 543 boolEvaluator, err = ArrayBoolContains(unary, nextBool, state) 544 if err != nil { 545 return nil, pos, err 546 } 547 if *obj.ArrayComparison.Op == "notin" { 548 return Not(boolEvaluator, state), obj.Pos, nil 549 } 550 return boolEvaluator, obj.Pos, nil 551 default: 552 return nil, pos, NewArrayTypeError(pos, reflect.Array, reflect.Bool) 553 } 554 case *StringEvaluator: 555 switch nextString := next.(type) { 556 case *StringArrayEvaluator: 557 boolEvaluator, err = StringArrayContainsWrapper(unary, nextString, state) 558 if err != nil { 559 return nil, pos, err 560 } 561 case *StringValuesEvaluator: 562 boolEvaluator, err = StringValuesContainsWrapper(unary, nextString, state) 563 if err != nil { 564 return nil, pos, err 565 } 566 default: 567 return nil, pos, NewArrayTypeError(pos, reflect.Array, reflect.String) 568 } 569 if *obj.ArrayComparison.Op == "notin" { 570 return Not(boolEvaluator, state), obj.Pos, nil 571 } 572 return boolEvaluator, obj.Pos, nil 573 case *StringValuesEvaluator: 574 switch nextStringArray := next.(type) { 575 case *StringArrayEvaluator: 576 boolEvaluator, err = StringArrayMatchesWrapper(nextStringArray, unary, state) 577 if err != nil { 578 return nil, pos, err 579 } 580 if *obj.ArrayComparison.Op == "notin" { 581 return Not(boolEvaluator, state), obj.Pos, nil 582 } 583 return boolEvaluator, obj.Pos, nil 584 default: 585 return nil, pos, NewArrayTypeError(pos, reflect.Array, reflect.String) 586 } 587 case *StringArrayEvaluator: 588 switch nextStringArray := next.(type) { 589 case *StringValuesEvaluator: 590 boolEvaluator, err = StringArrayMatchesWrapper(unary, nextStringArray, state) 591 if err != nil { 592 return nil, pos, err 593 } 594 if *obj.ArrayComparison.Op == "notin" { 595 return Not(boolEvaluator, state), obj.Pos, nil 596 } 597 return boolEvaluator, obj.Pos, nil 598 default: 599 return nil, pos, NewArrayTypeError(pos, reflect.Array, reflect.String) 600 } 601 case *IntEvaluator: 602 switch nextInt := next.(type) { 603 case *IntArrayEvaluator: 604 boolEvaluator, err = IntArrayEquals(unary, nextInt, state) 605 if err != nil { 606 return nil, pos, err 607 } 608 if *obj.ArrayComparison.Op == "notin" { 609 return Not(boolEvaluator, state), obj.Pos, nil 610 } 611 return boolEvaluator, obj.Pos, nil 612 default: 613 return nil, pos, NewArrayTypeError(pos, reflect.Array, reflect.Int) 614 } 615 case *IntArrayEvaluator: 616 switch nextIntArray := next.(type) { 617 case *IntArrayEvaluator: 618 boolEvaluator, err = IntArrayMatches(unary, nextIntArray, state) 619 if err != nil { 620 return nil, pos, err 621 } 622 if *obj.ArrayComparison.Op == "notin" { 623 return Not(boolEvaluator, state), obj.Pos, nil 624 } 625 return boolEvaluator, obj.Pos, nil 626 default: 627 return nil, pos, NewArrayTypeError(pos, reflect.Array, reflect.Int) 628 } 629 case *CIDREvaluator: 630 switch nextCIDR := next.(type) { 631 case *CIDREvaluator: 632 nextIP, ok := next.(*CIDREvaluator) 633 if !ok { 634 return nil, pos, NewTypeError(pos, reflect.TypeOf(CIDREvaluator{}).Kind()) 635 } 636 637 boolEvaluator, err = CIDREquals(unary, nextIP, state) 638 if err != nil { 639 return nil, obj.Pos, err 640 } 641 switch *obj.ArrayComparison.Op { 642 case "in", "allin": 643 return boolEvaluator, obj.Pos, nil 644 case "notin": 645 return Not(boolEvaluator, state), obj.Pos, nil 646 } 647 return nil, pos, NewOpUnknownError(obj.Pos, *obj.ArrayComparison.Op) 648 case *CIDRValuesEvaluator: 649 switch *obj.ArrayComparison.Op { 650 case "in", "allin": 651 boolEvaluator, err = CIDRValuesContains(unary, nextCIDR, state) 652 if err != nil { 653 return nil, pos, err 654 } 655 return boolEvaluator, obj.Pos, nil 656 case "notin": 657 boolEvaluator, err = CIDRValuesContains(unary, nextCIDR, state) 658 if err != nil { 659 return nil, pos, err 660 } 661 return Not(boolEvaluator, state), obj.Pos, nil 662 } 663 return nil, pos, NewOpUnknownError(obj.Pos, *obj.ArrayComparison.Op) 664 case *CIDRArrayEvaluator: 665 switch *obj.ArrayComparison.Op { 666 case "in", "allin": 667 boolEvaluator, err = CIDRArrayContains(unary, nextCIDR, state) 668 if err != nil { 669 return nil, pos, err 670 } 671 return boolEvaluator, obj.Pos, nil 672 case "notin": 673 boolEvaluator, err = CIDRArrayContains(unary, nextCIDR, state) 674 if err != nil { 675 return nil, pos, err 676 } 677 return Not(boolEvaluator, state), obj.Pos, nil 678 } 679 return nil, pos, NewOpUnknownError(obj.Pos, *obj.ArrayComparison.Op) 680 default: 681 return nil, pos, NewCIDRTypeError(pos, reflect.Array, next) 682 } 683 case *CIDRArrayEvaluator: 684 switch nextCIDR := next.(type) { 685 case *CIDRValuesEvaluator: 686 switch *obj.ArrayComparison.Op { 687 case "in": 688 boolEvaluator, err = CIDRArrayMatches(unary, nextCIDR, state) 689 if err != nil { 690 return nil, pos, err 691 } 692 return boolEvaluator, obj.Pos, nil 693 case "allin": 694 boolEvaluator, err = CIDRArrayMatchesAll(unary, nextCIDR, state) 695 if err != nil { 696 return nil, pos, err 697 } 698 return boolEvaluator, obj.Pos, nil 699 case "notin": 700 boolEvaluator, err = CIDRArrayMatches(unary, nextCIDR, state) 701 if err != nil { 702 return nil, pos, err 703 } 704 return Not(boolEvaluator, state), obj.Pos, nil 705 } 706 return nil, pos, NewOpUnknownError(obj.Pos, *obj.ArrayComparison.Op) 707 default: 708 return nil, pos, NewCIDRTypeError(pos, reflect.Array, next) 709 } 710 case *CIDRValuesEvaluator: 711 switch nextCIDR := next.(type) { 712 case *CIDREvaluator: 713 switch *obj.ArrayComparison.Op { 714 case "in", "allin": 715 boolEvaluator, err = CIDRValuesContains(nextCIDR, unary, state) 716 if err != nil { 717 return nil, obj.Pos, err 718 } 719 return boolEvaluator, obj.Pos, nil 720 case "notin": 721 boolEvaluator, err = CIDRValuesContains(nextCIDR, unary, state) 722 if err != nil { 723 return nil, obj.Pos, err 724 } 725 return Not(boolEvaluator, state), obj.Pos, nil 726 } 727 return nil, pos, NewOpUnknownError(obj.Pos, *obj.ArrayComparison.Op) 728 case *CIDRArrayEvaluator: 729 switch *obj.ArrayComparison.Op { 730 case "allin": 731 boolEvaluator, err = CIDRArrayMatchesAll(nextCIDR, unary, state) 732 if err != nil { 733 return nil, obj.Pos, err 734 } 735 return boolEvaluator, obj.Pos, nil 736 case "in": 737 boolEvaluator, err = CIDRArrayMatches(nextCIDR, unary, state) 738 if err != nil { 739 return nil, pos, err 740 } 741 return boolEvaluator, obj.Pos, nil 742 case "notin": 743 boolEvaluator, err = CIDRArrayMatches(nextCIDR, unary, state) 744 if err != nil { 745 return nil, pos, err 746 } 747 return Not(boolEvaluator, state), obj.Pos, nil 748 } 749 return nil, pos, NewOpUnknownError(obj.Pos, *obj.ArrayComparison.Op) 750 default: 751 return nil, pos, NewCIDRTypeError(pos, reflect.Array, next) 752 } 753 default: 754 return nil, pos, NewTypeError(pos, reflect.Array) 755 } 756 } else if obj.ScalarComparison != nil { 757 next, pos, err = nodeToEvaluator(obj.ScalarComparison, opts, state) 758 if err != nil { 759 return nil, pos, err 760 } 761 762 switch unary := unary.(type) { 763 case *BoolEvaluator: 764 nextBool, ok := next.(*BoolEvaluator) 765 if !ok { 766 return nil, pos, NewTypeError(pos, reflect.Bool) 767 } 768 769 switch *obj.ScalarComparison.Op { 770 case "!=": 771 boolEvaluator, err = BoolEquals(unary, nextBool, state) 772 if err != nil { 773 return nil, pos, err 774 } 775 return Not(boolEvaluator, state), obj.Pos, nil 776 case "==": 777 boolEvaluator, err = BoolEquals(unary, nextBool, state) 778 if err != nil { 779 return nil, pos, err 780 } 781 return boolEvaluator, obj.Pos, nil 782 } 783 return nil, pos, NewOpUnknownError(obj.Pos, *obj.ScalarComparison.Op) 784 case *BoolArrayEvaluator: 785 nextBool, ok := next.(*BoolEvaluator) 786 if !ok { 787 return nil, pos, NewTypeError(pos, reflect.Bool) 788 } 789 790 switch *obj.ScalarComparison.Op { 791 case "!=": 792 boolEvaluator, err = BoolArrayEquals(nextBool, unary, state) 793 if err != nil { 794 return nil, pos, err 795 } 796 return Not(boolEvaluator, state), obj.Pos, nil 797 case "==": 798 boolEvaluator, err = BoolArrayEquals(nextBool, unary, state) 799 if err != nil { 800 return nil, pos, err 801 } 802 return boolEvaluator, obj.Pos, nil 803 } 804 return nil, pos, NewOpUnknownError(obj.Pos, *obj.ScalarComparison.Op) 805 case *StringEvaluator: 806 nextString, ok := next.(*StringEvaluator) 807 if !ok { 808 return nil, pos, NewTypeError(pos, reflect.String) 809 } 810 811 switch *obj.ScalarComparison.Op { 812 case "!=": 813 boolEvaluator, err = StringEqualsWrapper(unary, nextString, state) 814 if err != nil { 815 return nil, obj.Pos, err 816 } 817 return Not(boolEvaluator, state), obj.Pos, nil 818 case "!~": 819 if nextString.EvalFnc != nil { 820 return nil, obj.Pos, &ErrNonStaticPattern{Field: nextString.Field} 821 } 822 823 // force pattern if needed 824 if nextString.ValueType == ScalarValueType { 825 nextString.ValueType = PatternValueType 826 } 827 828 boolEvaluator, err = StringEqualsWrapper(unary, nextString, state) 829 if err != nil { 830 return nil, obj.Pos, err 831 } 832 return Not(boolEvaluator, state), obj.Pos, nil 833 case "==": 834 boolEvaluator, err = StringEqualsWrapper(unary, nextString, state) 835 if err != nil { 836 return nil, obj.Pos, err 837 } 838 return boolEvaluator, obj.Pos, nil 839 case "=~": 840 if nextString.EvalFnc != nil { 841 return nil, obj.Pos, &ErrNonStaticPattern{Field: nextString.Field} 842 } 843 844 // force pattern if needed 845 if nextString.ValueType == ScalarValueType { 846 nextString.ValueType = PatternValueType 847 } 848 849 boolEvaluator, err = StringEqualsWrapper(unary, nextString, state) 850 if err != nil { 851 return nil, obj.Pos, err 852 } 853 return boolEvaluator, obj.Pos, nil 854 } 855 return nil, pos, NewOpUnknownError(obj.Pos, *obj.ScalarComparison.Op) 856 case *CIDREvaluator: 857 switch nextIP := next.(type) { 858 case *CIDREvaluator: 859 switch *obj.ScalarComparison.Op { 860 case "!=": 861 boolEvaluator, err = CIDREquals(unary, nextIP, state) 862 if err != nil { 863 return nil, obj.Pos, err 864 } 865 return Not(boolEvaluator, state), obj.Pos, nil 866 case "==": 867 boolEvaluator, err = CIDREquals(unary, nextIP, state) 868 if err != nil { 869 return nil, obj.Pos, err 870 } 871 return boolEvaluator, obj.Pos, nil 872 } 873 return nil, pos, NewOpUnknownError(obj.Pos, *obj.ScalarComparison.Op) 874 } 875 case *StringArrayEvaluator: 876 nextString, ok := next.(*StringEvaluator) 877 if !ok { 878 return nil, pos, NewTypeError(pos, reflect.String) 879 } 880 881 switch *obj.ScalarComparison.Op { 882 case "!=": 883 boolEvaluator, err = StringArrayContainsWrapper(nextString, unary, state) 884 if err != nil { 885 return nil, obj.Pos, err 886 } 887 return Not(boolEvaluator, state), obj.Pos, nil 888 case "==": 889 boolEvaluator, err = StringArrayContainsWrapper(nextString, unary, state) 890 if err != nil { 891 return nil, obj.Pos, err 892 } 893 return boolEvaluator, obj.Pos, nil 894 case "!~": 895 if nextString.EvalFnc != nil { 896 return nil, obj.Pos, &ErrNonStaticPattern{Field: nextString.Field} 897 } 898 899 // force pattern if needed 900 if nextString.ValueType == ScalarValueType { 901 nextString.ValueType = PatternValueType 902 } 903 904 boolEvaluator, err = StringArrayContainsWrapper(nextString, unary, state) 905 if err != nil { 906 return nil, obj.Pos, err 907 } 908 return Not(boolEvaluator, state), obj.Pos, nil 909 case "=~": 910 if nextString.EvalFnc != nil { 911 return nil, obj.Pos, &ErrNonStaticPattern{Field: nextString.Field} 912 } 913 914 // force pattern if needed 915 if nextString.ValueType == ScalarValueType { 916 nextString.ValueType = PatternValueType 917 } 918 919 boolEvaluator, err = StringArrayContainsWrapper(nextString, unary, state) 920 if err != nil { 921 return nil, obj.Pos, err 922 } 923 return boolEvaluator, obj.Pos, nil 924 } 925 case *IntEvaluator: 926 switch nextInt := next.(type) { 927 case *IntEvaluator: 928 if nextInt.isDuration { 929 if unary.isFromArithmeticOperation { 930 switch *obj.ScalarComparison.Op { 931 case "<": 932 boolEvaluator, err = DurationLesserThanArithmeticOperation(unary, nextInt, state) 933 if err != nil { 934 return nil, obj.Pos, err 935 } 936 return boolEvaluator, obj.Pos, nil 937 case "<=": 938 boolEvaluator, err = DurationLesserOrEqualThanArithmeticOperation(unary, nextInt, state) 939 if err != nil { 940 return nil, obj.Pos, err 941 } 942 return boolEvaluator, obj.Pos, nil 943 case ">": 944 boolEvaluator, err = DurationGreaterThanArithmeticOperation(unary, nextInt, state) 945 if err != nil { 946 return nil, obj.Pos, err 947 } 948 return boolEvaluator, obj.Pos, nil 949 case ">=": 950 boolEvaluator, err = DurationGreaterOrEqualThanArithmeticOperation(unary, nextInt, state) 951 if err != nil { 952 return nil, obj.Pos, err 953 } 954 return boolEvaluator, obj.Pos, nil 955 case "==": 956 boolEvaluator, err = DurationEqualArithmeticOperation(unary, nextInt, state) 957 if err != nil { 958 return nil, obj.Pos, err 959 } 960 return boolEvaluator, obj.Pos, nil 961 } 962 963 } else { 964 switch *obj.ScalarComparison.Op { 965 case "<": 966 boolEvaluator, err = DurationLesserThan(unary, nextInt, state) 967 if err != nil { 968 return nil, obj.Pos, err 969 } 970 return boolEvaluator, obj.Pos, nil 971 case "<=": 972 boolEvaluator, err = DurationLesserOrEqualThan(unary, nextInt, state) 973 if err != nil { 974 return nil, obj.Pos, err 975 } 976 return boolEvaluator, obj.Pos, nil 977 case ">": 978 boolEvaluator, err = DurationGreaterThan(unary, nextInt, state) 979 if err != nil { 980 return nil, obj.Pos, err 981 } 982 return boolEvaluator, obj.Pos, nil 983 case ">=": 984 boolEvaluator, err = DurationGreaterOrEqualThan(unary, nextInt, state) 985 if err != nil { 986 return nil, obj.Pos, err 987 } 988 return boolEvaluator, obj.Pos, nil 989 case "==": 990 boolEvaluator, err = DurationEqual(unary, nextInt, state) 991 if err != nil { 992 return nil, obj.Pos, err 993 } 994 return boolEvaluator, obj.Pos, nil 995 } 996 } 997 } else { 998 switch *obj.ScalarComparison.Op { 999 case "<": 1000 boolEvaluator, err = LesserThan(unary, nextInt, state) 1001 if err != nil { 1002 return nil, obj.Pos, err 1003 } 1004 return boolEvaluator, obj.Pos, nil 1005 case "<=": 1006 boolEvaluator, err = LesserOrEqualThan(unary, nextInt, state) 1007 if err != nil { 1008 return nil, obj.Pos, err 1009 } 1010 return boolEvaluator, obj.Pos, nil 1011 case ">": 1012 boolEvaluator, err = GreaterThan(unary, nextInt, state) 1013 if err != nil { 1014 return nil, obj.Pos, err 1015 } 1016 return boolEvaluator, obj.Pos, nil 1017 case ">=": 1018 boolEvaluator, err = GreaterOrEqualThan(unary, nextInt, state) 1019 if err != nil { 1020 return nil, obj.Pos, err 1021 } 1022 return boolEvaluator, obj.Pos, nil 1023 case "!=": 1024 boolEvaluator, err = IntEquals(unary, nextInt, state) 1025 if err != nil { 1026 return nil, obj.Pos, err 1027 } 1028 1029 return Not(boolEvaluator, state), obj.Pos, nil 1030 case "==": 1031 boolEvaluator, err = IntEquals(unary, nextInt, state) 1032 if err != nil { 1033 return nil, obj.Pos, err 1034 } 1035 return boolEvaluator, obj.Pos, nil 1036 default: 1037 return nil, pos, NewOpUnknownError(obj.Pos, *obj.ScalarComparison.Op) 1038 } 1039 } 1040 case *IntArrayEvaluator: 1041 nextIntArray := next.(*IntArrayEvaluator) 1042 1043 switch *obj.ScalarComparison.Op { 1044 case "<": 1045 boolEvaluator, err = IntArrayLesserThan(unary, nextIntArray, state) 1046 if err != nil { 1047 return nil, obj.Pos, err 1048 } 1049 return boolEvaluator, obj.Pos, nil 1050 case "<=": 1051 boolEvaluator, err = IntArrayLesserOrEqualThan(unary, nextIntArray, state) 1052 if err != nil { 1053 return nil, obj.Pos, err 1054 } 1055 return boolEvaluator, obj.Pos, nil 1056 case ">": 1057 boolEvaluator, err = IntArrayGreaterThan(unary, nextIntArray, state) 1058 if err != nil { 1059 return nil, obj.Pos, err 1060 } 1061 return boolEvaluator, obj.Pos, nil 1062 case ">=": 1063 boolEvaluator, err = IntArrayGreaterOrEqualThan(unary, nextIntArray, state) 1064 if err != nil { 1065 return nil, obj.Pos, err 1066 } 1067 return boolEvaluator, obj.Pos, nil 1068 case "!=": 1069 boolEvaluator, err = IntArrayEquals(unary, nextIntArray, state) 1070 if err != nil { 1071 return nil, obj.Pos, err 1072 } 1073 return Not(boolEvaluator, state), obj.Pos, nil 1074 case "==": 1075 boolEvaluator, err = IntArrayEquals(unary, nextIntArray, state) 1076 if err != nil { 1077 return nil, obj.Pos, err 1078 } 1079 return boolEvaluator, obj.Pos, nil 1080 default: 1081 return nil, pos, NewOpUnknownError(obj.Pos, *obj.ScalarComparison.Op) 1082 } 1083 } 1084 return nil, pos, NewTypeError(pos, reflect.Int) 1085 case *IntArrayEvaluator: 1086 nextInt, ok := next.(*IntEvaluator) 1087 if !ok { 1088 return nil, pos, NewTypeError(pos, reflect.Int) 1089 } 1090 1091 if nextInt.isDuration { 1092 switch *obj.ScalarComparison.Op { 1093 case "<": 1094 boolEvaluator, err = DurationArrayLesserThan(nextInt, unary, state) 1095 if err != nil { 1096 return nil, obj.Pos, err 1097 } 1098 return boolEvaluator, obj.Pos, nil 1099 case "<=": 1100 boolEvaluator, err = DurationArrayLesserOrEqualThan(nextInt, unary, state) 1101 if err != nil { 1102 return nil, obj.Pos, err 1103 } 1104 return boolEvaluator, obj.Pos, nil 1105 case ">": 1106 boolEvaluator, err = DurationArrayGreaterThan(nextInt, unary, state) 1107 if err != nil { 1108 return nil, obj.Pos, err 1109 } 1110 return boolEvaluator, obj.Pos, nil 1111 case ">=": 1112 boolEvaluator, err = DurationArrayGreaterOrEqualThan(nextInt, unary, state) 1113 if err != nil { 1114 return nil, obj.Pos, err 1115 } 1116 return boolEvaluator, obj.Pos, nil 1117 } 1118 } else { 1119 switch *obj.ScalarComparison.Op { 1120 case "<": 1121 boolEvaluator, err = IntArrayGreaterThan(nextInt, unary, state) 1122 if err != nil { 1123 return nil, obj.Pos, err 1124 } 1125 return boolEvaluator, obj.Pos, nil 1126 case "<=": 1127 boolEvaluator, err = IntArrayGreaterOrEqualThan(nextInt, unary, state) 1128 if err != nil { 1129 return nil, obj.Pos, err 1130 } 1131 return boolEvaluator, obj.Pos, nil 1132 case ">": 1133 boolEvaluator, err = IntArrayLesserThan(nextInt, unary, state) 1134 if err != nil { 1135 return nil, obj.Pos, err 1136 } 1137 return boolEvaluator, obj.Pos, nil 1138 case ">=": 1139 boolEvaluator, err = IntArrayLesserOrEqualThan(nextInt, unary, state) 1140 if err != nil { 1141 return nil, obj.Pos, err 1142 } 1143 return boolEvaluator, obj.Pos, nil 1144 case "!=": 1145 boolEvaluator, err = IntArrayEquals(nextInt, unary, state) 1146 if err != nil { 1147 return nil, obj.Pos, err 1148 } 1149 return Not(boolEvaluator, state), obj.Pos, nil 1150 case "==": 1151 boolEvaluator, err = IntArrayEquals(nextInt, unary, state) 1152 if err != nil { 1153 return nil, obj.Pos, err 1154 } 1155 return boolEvaluator, obj.Pos, nil 1156 } 1157 return nil, pos, NewOpUnknownError(obj.Pos, *obj.ScalarComparison.Op) 1158 } 1159 } 1160 } else { 1161 return unary, pos, nil 1162 } 1163 1164 case *ast.ArrayComparison: 1165 return nodeToEvaluator(obj.Array, opts, state) 1166 1167 case *ast.ScalarComparison: 1168 return nodeToEvaluator(obj.Next, opts, state) 1169 1170 case *ast.Unary: 1171 if obj.Op != nil { 1172 unary, pos, err = nodeToEvaluator(obj.Unary, opts, state) 1173 if err != nil { 1174 return nil, pos, err 1175 } 1176 1177 switch *obj.Op { 1178 case "!", "not": 1179 unaryBool, ok := unary.(*BoolEvaluator) 1180 if !ok { 1181 return nil, pos, NewTypeError(pos, reflect.Bool) 1182 } 1183 1184 return Not(unaryBool, state), obj.Pos, nil 1185 case "-": 1186 unaryInt, ok := unary.(*IntEvaluator) 1187 if !ok { 1188 return nil, pos, NewTypeError(pos, reflect.Int) 1189 } 1190 1191 return Minus(unaryInt, state), pos, nil 1192 case "^": 1193 unaryInt, ok := unary.(*IntEvaluator) 1194 if !ok { 1195 return nil, pos, NewTypeError(pos, reflect.Int) 1196 } 1197 1198 return IntNot(unaryInt, state), pos, nil 1199 } 1200 return nil, pos, NewOpUnknownError(obj.Pos, *obj.Op) 1201 } 1202 1203 return nodeToEvaluator(obj.Primary, opts, state) 1204 case *ast.Primary: 1205 switch { 1206 case obj.Ident != nil: 1207 return identToEvaluator(&ident{Pos: obj.Pos, Ident: obj.Ident}, opts, state) 1208 case obj.Number != nil: 1209 return &IntEvaluator{ 1210 Value: *obj.Number, 1211 }, obj.Pos, nil 1212 case obj.Variable != nil: 1213 varname, ok := isVariableName(*obj.Variable) 1214 if !ok { 1215 return nil, obj.Pos, NewError(obj.Pos, "internal variable error '%s'", varname) 1216 } 1217 1218 return evaluatorFromVariable(varname, obj.Pos, opts) 1219 case obj.Duration != nil: 1220 return &IntEvaluator{ 1221 Value: *obj.Duration, 1222 isDuration: true, 1223 }, obj.Pos, nil 1224 case obj.String != nil: 1225 str := *obj.String 1226 1227 // contains variables 1228 if len(variableRegex.FindAllIndex([]byte(str), -1)) > 0 { 1229 return stringEvaluatorFromVariable(str, obj.Pos, opts) 1230 } 1231 1232 return &StringEvaluator{ 1233 Value: str, 1234 ValueType: ScalarValueType, 1235 }, obj.Pos, nil 1236 case obj.Pattern != nil: 1237 evaluator := &StringEvaluator{ 1238 Value: *obj.Pattern, 1239 ValueType: PatternValueType, 1240 } 1241 return evaluator, obj.Pos, nil 1242 case obj.Regexp != nil: 1243 evaluator := &StringEvaluator{ 1244 Value: *obj.Regexp, 1245 ValueType: RegexpValueType, 1246 } 1247 return evaluator, obj.Pos, nil 1248 case obj.IP != nil: 1249 ipnet, err := ParseCIDR(*obj.IP) 1250 if err != nil { 1251 return nil, obj.Pos, NewError(obj.Pos, "invalid IP '%s'", *obj.IP) 1252 } 1253 1254 evaluator := &CIDREvaluator{ 1255 Value: *ipnet, 1256 ValueType: IPNetValueType, 1257 } 1258 return evaluator, obj.Pos, nil 1259 case obj.CIDR != nil: 1260 ipnet, err := ParseCIDR(*obj.CIDR) 1261 if err != nil { 1262 return nil, obj.Pos, NewError(obj.Pos, "invalid CIDR '%s'", *obj.CIDR) 1263 } 1264 1265 evaluator := &CIDREvaluator{ 1266 Value: *ipnet, 1267 ValueType: IPNetValueType, 1268 } 1269 return evaluator, obj.Pos, nil 1270 case obj.SubExpression != nil: 1271 return nodeToEvaluator(obj.SubExpression, opts, state) 1272 default: 1273 return nil, obj.Pos, NewError(obj.Pos, "unknown primary '%s'", reflect.TypeOf(obj)) 1274 } 1275 case *ast.Array: 1276 return arrayToEvaluator(obj, opts, state) 1277 } 1278 1279 return nil, lexer.Position{}, NewError(lexer.Position{}, "unknown entity '%s'", reflect.TypeOf(obj)) 1280 }