diff --git a/go.mod b/go.mod index b4f101252..b9ccb25ae 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/cloudflare/circl v1.6.2 github.com/dustin/go-humanize v1.0.1 github.com/go-chi/chi/v5 v5.2.4 - github.com/google/cel-go v0.26.1 + github.com/google/cel-go v0.27.0 github.com/google/uuid v1.6.0 github.com/klauspost/compress v1.18.2 github.com/klauspost/cpuid/v2 v2.3.0 @@ -49,13 +49,13 @@ require ( ) require ( - cel.dev/expr v0.24.0 // indirect + cel.dev/expr v0.25.1 // indirect cloud.google.com/go/auth v0.18.1 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect cloud.google.com/go/compute/metadata v0.9.0 // indirect dario.cat/mergo v1.0.2 // indirect filippo.io/bigmod v0.1.0 // indirect - github.com/antlr4-go/antlr/v4 v4.13.0 // indirect + github.com/antlr4-go/antlr/v4 v4.13.1 // indirect github.com/ccoveille/go-safecast/v2 v2.0.0 // indirect github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/coreos/go-oidc/v3 v3.17.0 // indirect diff --git a/go.sum b/go.sum index 1fac2e8bb..fd3f68e54 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY= cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= +cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4= +cel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4= cloud.google.com/go v0.123.0 h1:2NAUJwPR47q+E35uaJeYoNhuNEM9kM8SjgRgdeOJUSE= cloud.google.com/go v0.123.0/go.mod h1:xBoMV08QcqUGuPW65Qfm1o9Y4zKZBpGS+7bImXLTAZU= cloud.google.com/go/auth v0.18.1 h1:IwTEx92GFUo2pJ6Qea0EU3zYvKnTAeRCODxfA/G5UWs= @@ -48,6 +50,8 @@ github.com/alecthomas/repr v0.5.2 h1:SU73FTI9D1P5UNtvseffFSGmdNci/O6RsqzeXJtP0Qs github.com/alecthomas/repr v0.5.2/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI= github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g= +github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ= +github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/aryann/difflib v0.0.0-20210328193216-ff5ff6dc229b h1:uUXgbcPDK3KpW29o4iy7GtuappbWT0l5NaMo9H9pJDw= github.com/aryann/difflib v0.0.0-20210328193216-ff5ff6dc229b/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= @@ -168,6 +172,8 @@ github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= github.com/google/cel-go v0.26.1 h1:iPbVVEdkhTX++hpe3lzSk7D3G3QSYqLGoHOcEio+UXQ= github.com/google/cel-go v0.26.1/go.mod h1:A9O8OU9rdvrK5MQyrqfIxo1a0u4g3sF8KB6PUIaryMM= +github.com/google/cel-go v0.27.0 h1:e7ih85+4qVrBuqQWTW4FKSqZYokVuc3HnhH5keboFTo= +github.com/google/cel-go v0.27.0/go.mod h1:tTJ11FWqnhw5KKpnWpvW9CJC3Y9GK4EIS0WXnBbebzw= github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg= github.com/google/certificate-transparency-go v1.1.8-0.20240110162603-74a5dd331745 h1:heyoXNxkRT155x4jTAiSv5BVSVkueifPUm+Q8LUXMRo= github.com/google/certificate-transparency-go v1.1.8-0.20240110162603-74a5dd331745/go.mod h1:zN0wUQgV9LjwLZeFHnrAbQi8hzMVvEWePyk+MhPOk7k= diff --git a/modules/caddyhttp/celmatcher.go b/modules/caddyhttp/celmatcher.go index 66a60b817..b67cb9e92 100644 --- a/modules/caddyhttp/celmatcher.go +++ b/modules/caddyhttp/celmatcher.go @@ -665,12 +665,29 @@ func celMatcherJSONMacroExpander(funcName string) parser.MacroExpander { // map literals containing heterogeneous values, in this case string and list // of string. func CELValueToMapStrList(data ref.Val) (map[string][]string, error) { + // Prefer map[string]any, but newer cel-go versions may return map[any]any mapStrType := reflect.TypeFor[map[string]any]() mapStrRaw, err := data.ConvertToNative(mapStrType) + var mapStrIface map[string]any if err != nil { - return nil, err + // Try map[any]any and convert keys to strings + mapAnyType := reflect.TypeFor[map[any]any]() + mapAnyRaw, err2 := data.ConvertToNative(mapAnyType) + if err2 != nil { + return nil, err + } + mapAnyIface := mapAnyRaw.(map[any]any) + mapStrIface = make(map[string]any, len(mapAnyIface)) + for k, v := range mapAnyIface { + ks, ok := k.(string) + if !ok { + return nil, fmt.Errorf("unsupported map key type in header match: %T", k) + } + mapStrIface[ks] = v + } + } else { + mapStrIface = mapStrRaw.(map[string]any) } - mapStrIface := mapStrRaw.(map[string]any) mapStrListStr := make(map[string][]string, len(mapStrIface)) for k, v := range mapStrIface { switch val := v.(type) { @@ -685,13 +702,26 @@ func CELValueToMapStrList(data ref.Val) (map[string][]string, error) { for i, elem := range val { strVal, ok := elem.(types.String) if !ok { - return nil, fmt.Errorf("unsupported value type in header match: %T", val) + return nil, fmt.Errorf("unsupported value type in matcher input: %T", val) } convVals[i] = string(strVal) } mapStrListStr[k] = convVals + case []any: + convVals := make([]string, len(val)) + for i, elem := range val { + switch e := elem.(type) { + case string: + convVals[i] = e + case types.String: + convVals[i] = string(e) + default: + return nil, fmt.Errorf("unsupported element type in matcher input list: %T", elem) + } + } + mapStrListStr[k] = convVals default: - return nil, fmt.Errorf("unsupported value type in header match: %T", val) + return nil, fmt.Errorf("unsupported value type in matcher input: %T", val) } } return mapStrListStr, nil