Upgrade dependent version: github.com/open-policy-agent/opa (#5315)
Upgrade dependent version: github.com/open-policy-agent/opa v0.18.0 -> v0.45.0 Signed-off-by: hongzhouzi <hongzhouzi@kubesphere.io> Signed-off-by: hongzhouzi <hongzhouzi@kubesphere.io>
This commit is contained in:
257
vendor/github.com/open-policy-agent/opa/topdown/strings.go
generated
vendored
257
vendor/github.com/open-policy-agent/opa/topdown/strings.go
generated
vendored
@@ -5,14 +5,113 @@
|
||||
package topdown
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/tchap/go-patricia/v2/patricia"
|
||||
|
||||
"github.com/open-policy-agent/opa/ast"
|
||||
"github.com/open-policy-agent/opa/topdown/builtins"
|
||||
)
|
||||
|
||||
func builtinAnyPrefixMatch(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
a, b := operands[0].Value, operands[1].Value
|
||||
|
||||
var strs []string
|
||||
switch a := a.(type) {
|
||||
case ast.String:
|
||||
strs = []string{string(a)}
|
||||
case *ast.Array, ast.Set:
|
||||
var err error
|
||||
strs, err = builtins.StringSliceOperand(a, 1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
return builtins.NewOperandTypeErr(1, a, "string", "set", "array")
|
||||
}
|
||||
|
||||
var prefixes []string
|
||||
switch b := b.(type) {
|
||||
case ast.String:
|
||||
prefixes = []string{string(b)}
|
||||
case *ast.Array, ast.Set:
|
||||
var err error
|
||||
prefixes, err = builtins.StringSliceOperand(b, 2)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
return builtins.NewOperandTypeErr(2, b, "string", "set", "array")
|
||||
}
|
||||
|
||||
return iter(ast.BooleanTerm(anyStartsWithAny(strs, prefixes)))
|
||||
}
|
||||
|
||||
func builtinAnySuffixMatch(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
a, b := operands[0].Value, operands[1].Value
|
||||
|
||||
var strsReversed []string
|
||||
switch a := a.(type) {
|
||||
case ast.String:
|
||||
strsReversed = []string{reverseString(string(a))}
|
||||
case *ast.Array, ast.Set:
|
||||
strs, err := builtins.StringSliceOperand(a, 1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
strsReversed = make([]string, len(strs))
|
||||
for i := range strs {
|
||||
strsReversed[i] = reverseString(strs[i])
|
||||
}
|
||||
default:
|
||||
return builtins.NewOperandTypeErr(1, a, "string", "set", "array")
|
||||
}
|
||||
|
||||
var suffixesReversed []string
|
||||
switch b := b.(type) {
|
||||
case ast.String:
|
||||
suffixesReversed = []string{reverseString(string(b))}
|
||||
case *ast.Array, ast.Set:
|
||||
suffixes, err := builtins.StringSliceOperand(b, 2)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
suffixesReversed = make([]string, len(suffixes))
|
||||
for i := range suffixes {
|
||||
suffixesReversed[i] = reverseString(suffixes[i])
|
||||
}
|
||||
default:
|
||||
return builtins.NewOperandTypeErr(2, b, "string", "set", "array")
|
||||
}
|
||||
|
||||
return iter(ast.BooleanTerm(anyStartsWithAny(strsReversed, suffixesReversed)))
|
||||
}
|
||||
|
||||
func anyStartsWithAny(strs []string, prefixes []string) bool {
|
||||
if len(strs) == 0 || len(prefixes) == 0 {
|
||||
return false
|
||||
}
|
||||
if len(strs) == 1 && len(prefixes) == 1 {
|
||||
return strings.HasPrefix(strs[0], prefixes[0])
|
||||
}
|
||||
|
||||
trie := patricia.NewTrie()
|
||||
for i := 0; i < len(strs); i++ {
|
||||
trie.Insert([]byte(strs[i]), true)
|
||||
}
|
||||
|
||||
for i := 0; i < len(prefixes); i++ {
|
||||
if trie.MatchSubtree([]byte(prefixes[i])) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func builtinFormatInt(a, b ast.Value) (ast.Value, error) {
|
||||
|
||||
input, err := builtins.NumberOperand(a, 1)
|
||||
@@ -55,13 +154,17 @@ func builtinConcat(a, b ast.Value) (ast.Value, error) {
|
||||
strs := []string{}
|
||||
|
||||
switch b := b.(type) {
|
||||
case ast.Array:
|
||||
for i := range b {
|
||||
s, ok := b[i].Value.(ast.String)
|
||||
case *ast.Array:
|
||||
err := b.Iter(func(x *ast.Term) error {
|
||||
s, ok := x.Value.(ast.String)
|
||||
if !ok {
|
||||
return nil, builtins.NewOperandElementErr(2, b, b[i].Value, "string")
|
||||
return builtins.NewOperandElementErr(2, b, x.Value, "string")
|
||||
}
|
||||
strs = append(strs, string(s))
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case ast.Set:
|
||||
err := b.Iter(func(x *ast.Term) error {
|
||||
@@ -82,6 +185,18 @@ func builtinConcat(a, b ast.Value) (ast.Value, error) {
|
||||
return ast.String(strings.Join(strs, string(join))), nil
|
||||
}
|
||||
|
||||
func runesEqual(a, b []rune) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
for i, v := range a {
|
||||
if v != b[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func builtinIndexOf(a, b ast.Value) (ast.Value, error) {
|
||||
base, err := builtins.StringOperand(a, 1)
|
||||
if err != nil {
|
||||
@@ -92,9 +207,57 @@ func builtinIndexOf(a, b ast.Value) (ast.Value, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(string(search)) == 0 {
|
||||
return nil, fmt.Errorf("empty search character")
|
||||
}
|
||||
|
||||
index := strings.Index(string(base), string(search))
|
||||
return ast.IntNumberTerm(index).Value, nil
|
||||
baseRunes := []rune(string(base))
|
||||
searchRunes := []rune(string(search))
|
||||
searchLen := len(searchRunes)
|
||||
|
||||
for i, r := range baseRunes {
|
||||
if len(baseRunes) >= i+searchLen {
|
||||
if r == searchRunes[0] && runesEqual(baseRunes[i:i+searchLen], searchRunes) {
|
||||
return ast.IntNumberTerm(i).Value, nil
|
||||
}
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return ast.IntNumberTerm(-1).Value, nil
|
||||
}
|
||||
|
||||
func builtinIndexOfN(a, b ast.Value) (ast.Value, error) {
|
||||
base, err := builtins.StringOperand(a, 1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
search, err := builtins.StringOperand(b, 2)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(string(search)) == 0 {
|
||||
return nil, fmt.Errorf("empty search character")
|
||||
}
|
||||
|
||||
baseRunes := []rune(string(base))
|
||||
searchRunes := []rune(string(search))
|
||||
searchLen := len(searchRunes)
|
||||
|
||||
var arr []*ast.Term
|
||||
for i, r := range baseRunes {
|
||||
if len(baseRunes) >= i+searchLen {
|
||||
if r == searchRunes[0] && runesEqual(baseRunes[i:i+searchLen], searchRunes) {
|
||||
arr = append(arr, ast.IntNumberTerm(i))
|
||||
}
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return ast.NewArray(arr...), nil
|
||||
}
|
||||
|
||||
func builtinSubstring(a, b, c ast.Value) (ast.Value, error) {
|
||||
@@ -103,11 +266,12 @@ func builtinSubstring(a, b, c ast.Value) (ast.Value, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
runes := []rune(base)
|
||||
|
||||
startIndex, err := builtins.IntOperand(b, 2)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if startIndex >= len(base) {
|
||||
} else if startIndex >= len(runes) {
|
||||
return ast.String(""), nil
|
||||
} else if startIndex < 0 {
|
||||
return nil, fmt.Errorf("negative offset")
|
||||
@@ -120,13 +284,13 @@ func builtinSubstring(a, b, c ast.Value) (ast.Value, error) {
|
||||
|
||||
var s ast.String
|
||||
if length < 0 {
|
||||
s = ast.String(base[startIndex:])
|
||||
s = ast.String(runes[startIndex:])
|
||||
} else {
|
||||
upto := startIndex + length
|
||||
if len(base) < upto {
|
||||
upto = len(base)
|
||||
if len(runes) < upto {
|
||||
upto = len(runes)
|
||||
}
|
||||
s = ast.String(base[startIndex:upto])
|
||||
s = ast.String(runes[startIndex:upto])
|
||||
}
|
||||
|
||||
return s, nil
|
||||
@@ -202,11 +366,11 @@ func builtinSplit(a, b ast.Value) (ast.Value, error) {
|
||||
return nil, err
|
||||
}
|
||||
elems := strings.Split(string(s), string(d))
|
||||
arr := make(ast.Array, len(elems))
|
||||
for i := range arr {
|
||||
arr := make([]*ast.Term, len(elems))
|
||||
for i := range elems {
|
||||
arr[i] = ast.StringTerm(elems[i])
|
||||
}
|
||||
return arr, nil
|
||||
return ast.NewArray(arr...), nil
|
||||
}
|
||||
|
||||
func builtinReplace(a, b, c ast.Value) (ast.Value, error) {
|
||||
@@ -229,27 +393,33 @@ func builtinReplace(a, b, c ast.Value) (ast.Value, error) {
|
||||
}
|
||||
|
||||
func builtinReplaceN(a, b ast.Value) (ast.Value, error) {
|
||||
asJSON, err := ast.JSON(a)
|
||||
patterns, err := builtins.ObjectOperand(a, 1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
oldnewObj, ok := asJSON.(map[string]interface{})
|
||||
if !ok {
|
||||
return nil, builtins.NewOperandTypeErr(1, a, "object")
|
||||
}
|
||||
keys := patterns.Keys()
|
||||
sort.Slice(keys, func(i, j int) bool { return ast.Compare(keys[i].Value, keys[j].Value) < 0 })
|
||||
|
||||
s, err := builtins.StringOperand(b, 2)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var oldnewArr []string
|
||||
for k, v := range oldnewObj {
|
||||
strVal, ok := v.(string)
|
||||
oldnewArr := make([]string, 0, len(keys)*2)
|
||||
for _, k := range keys {
|
||||
keyVal, ok := k.Value.(ast.String)
|
||||
if !ok {
|
||||
return nil, errors.New("non-string value found in pattern object")
|
||||
return nil, builtins.NewOperandErr(1, "non-string key found in pattern object")
|
||||
}
|
||||
oldnewArr = append(oldnewArr, k, strVal)
|
||||
val := patterns.Get(k) // cannot be nil
|
||||
strVal, ok := val.Value.(ast.String)
|
||||
if !ok {
|
||||
return nil, builtins.NewOperandErr(1, "non-string value found in pattern object")
|
||||
}
|
||||
oldnewArr = append(oldnewArr, string(keyVal), string(strVal))
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
r := strings.NewReplacer(oldnewArr...)
|
||||
@@ -343,18 +513,20 @@ func builtinSprintf(a, b ast.Value) (ast.Value, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
astArr, ok := b.(ast.Array)
|
||||
astArr, ok := b.(*ast.Array)
|
||||
if !ok {
|
||||
return nil, builtins.NewOperandTypeErr(2, b, "array")
|
||||
}
|
||||
|
||||
args := make([]interface{}, len(astArr))
|
||||
args := make([]interface{}, astArr.Len())
|
||||
|
||||
for i := range astArr {
|
||||
switch v := astArr[i].Value.(type) {
|
||||
for i := range args {
|
||||
switch v := astArr.Elem(i).Value.(type) {
|
||||
case ast.Number:
|
||||
if n, ok := v.Int(); ok {
|
||||
args[i] = n
|
||||
} else if b, ok := new(big.Int).SetString(v.String(), 10); ok {
|
||||
args[i] = b
|
||||
} else if f, ok := v.Float64(); ok {
|
||||
args[i] = f
|
||||
} else {
|
||||
@@ -363,17 +535,39 @@ func builtinSprintf(a, b ast.Value) (ast.Value, error) {
|
||||
case ast.String:
|
||||
args[i] = string(v)
|
||||
default:
|
||||
args[i] = astArr[i].String()
|
||||
args[i] = astArr.Elem(i).String()
|
||||
}
|
||||
}
|
||||
|
||||
return ast.String(fmt.Sprintf(string(s), args...)), nil
|
||||
}
|
||||
|
||||
func builtinReverse(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
s, err := builtins.StringOperand(operands[0].Value, 1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return iter(ast.StringTerm(reverseString(string(s))))
|
||||
}
|
||||
|
||||
func reverseString(str string) string {
|
||||
sRunes := []rune(string(str))
|
||||
length := len(sRunes)
|
||||
reversedRunes := make([]rune, length)
|
||||
|
||||
for index, r := range sRunes {
|
||||
reversedRunes[length-index-1] = r
|
||||
}
|
||||
|
||||
return string(reversedRunes)
|
||||
}
|
||||
|
||||
func init() {
|
||||
RegisterFunctionalBuiltin2(ast.FormatInt.Name, builtinFormatInt)
|
||||
RegisterFunctionalBuiltin2(ast.Concat.Name, builtinConcat)
|
||||
RegisterFunctionalBuiltin2(ast.IndexOf.Name, builtinIndexOf)
|
||||
RegisterFunctionalBuiltin2(ast.IndexOfN.Name, builtinIndexOfN)
|
||||
RegisterFunctionalBuiltin3(ast.Substring.Name, builtinSubstring)
|
||||
RegisterFunctionalBuiltin2(ast.Contains.Name, builtinContains)
|
||||
RegisterFunctionalBuiltin2(ast.StartsWith.Name, builtinStartsWith)
|
||||
@@ -390,4 +584,7 @@ func init() {
|
||||
RegisterFunctionalBuiltin2(ast.TrimSuffix.Name, builtinTrimSuffix)
|
||||
RegisterFunctionalBuiltin1(ast.TrimSpace.Name, builtinTrimSpace)
|
||||
RegisterFunctionalBuiltin2(ast.Sprintf.Name, builtinSprintf)
|
||||
RegisterBuiltinFunc(ast.AnyPrefixMatch.Name, builtinAnyPrefixMatch)
|
||||
RegisterBuiltinFunc(ast.AnySuffixMatch.Name, builtinAnySuffixMatch)
|
||||
RegisterBuiltinFunc(ast.StringReverse.Name, builtinReverse)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user