diff --git a/.builder-image-version.txt b/.builder-image-version.txt index 4e036596..be5b4c7b 100644 --- a/.builder-image-version.txt +++ b/.builder-image-version.txt @@ -1 +1 @@ -1.1.19 +1.1.20 diff --git a/.github/workflows/pr-lint.yml b/.github/workflows/pr-lint.yml index 3ce2ff3b..5948ca99 100644 --- a/.github/workflows/pr-lint.yml +++ b/.github/workflows/pr-lint.yml @@ -21,7 +21,7 @@ jobs: if: github.event_name != 'pull_request' || !github.event.pull_request.draft runs-on: ubuntu-latest container: - image: ghcr.io/sovereigncloudstack/cso-builder:1.1.19 + image: ghcr.io/sovereigncloudstack/cso-builder:1.1.20 credentials: username: ${{ github.actor }} password: ${{ secrets.github_token }} diff --git a/.github/workflows/schedule-scan-image.yml b/.github/workflows/schedule-scan-image.yml index d41f1fb1..a84565ac 100644 --- a/.github/workflows/schedule-scan-image.yml +++ b/.github/workflows/schedule-scan-image.yml @@ -9,7 +9,7 @@ jobs: name: Trivy runs-on: ubuntu-latest container: - image: ghcr.io/sovereigncloudstack/cso-builder:1.1.19 + image: ghcr.io/sovereigncloudstack/cso-builder:1.1.20 credentials: username: ${{ github.actor }} password: ${{ secrets.github_token }} diff --git a/go.mod b/go.mod index c92508b1..a8946bf0 100644 --- a/go.mod +++ b/go.mod @@ -5,12 +5,12 @@ go 1.21 require ( github.com/go-logr/logr v1.4.2 github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 - github.com/google/cel-go v0.19.0 + github.com/google/cel-go v0.20.1 github.com/google/go-github/v52 v52.0.0 github.com/onsi/ginkgo/v2 v2.19.0 github.com/onsi/gomega v1.33.1 github.com/stretchr/testify v1.9.0 - golang.org/x/mod v0.18.0 + golang.org/x/mod v0.19.0 golang.org/x/oauth2 v0.21.0 k8s.io/api v0.29.3 k8s.io/apimachinery v0.29.3 diff --git a/go.sum b/go.sum index 3711b3d5..0520500d 100644 --- a/go.sum +++ b/go.sum @@ -90,8 +90,8 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/cel-go v0.19.0 h1:vVgaZoHPBDd1lXCYGQOh5A06L4EtuIfmqQ/qnSXSKiU= -github.com/google/cel-go v0.19.0/go.mod h1:kWcIzTsPX0zmQ+H3TirHstLLf9ep5QTsZBN9u4dOYLg= +github.com/google/cel-go v0.20.1 h1:nDx9r8S3L4pE61eDdt8igGj8rf5kjYR3ILxWIpWNi84= +github.com/google/cel-go v0.20.1/go.mod h1:kWcIzTsPX0zmQ+H3TirHstLLf9ep5QTsZBN9u4dOYLg= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -233,8 +233,8 @@ golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvx golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= -golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= +golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= diff --git a/vendor/github.com/google/cel-go/cel/BUILD.bazel b/vendor/github.com/google/cel-go/cel/BUILD.bazel index 33da2162..6e2fc073 100644 --- a/vendor/github.com/google/cel-go/cel/BUILD.bazel +++ b/vendor/github.com/google/cel-go/cel/BUILD.bazel @@ -77,6 +77,7 @@ go_test( "//common/types:go_default_library", "//common/types/ref:go_default_library", "//common/types/traits:go_default_library", + "//ext:go_default_library", "//test:go_default_library", "//test/proto2pb:go_default_library", "//test/proto3pb:go_default_library", diff --git a/vendor/github.com/google/cel-go/cel/inlining.go b/vendor/github.com/google/cel-go/cel/inlining.go index 8c8335d3..78d5bea6 100644 --- a/vendor/github.com/google/cel-go/cel/inlining.go +++ b/vendor/github.com/google/cel-go/cel/inlining.go @@ -88,7 +88,7 @@ func (opt *inliningOptimizer) Optimize(ctx *OptimizerContext, a *ast.AST) *ast.A if len(matches) == 1 || !isBindable(matches, inlineVar.Expr(), inlineVar.Type()) { for _, match := range matches { // Copy the inlined AST expr and source info. - copyExpr := copyASTAndMetadata(ctx, inlineVar.def) + copyExpr := ctx.CopyASTAndMetadata(inlineVar.def) opt.inlineExpr(ctx, match, copyExpr, inlineVar.Type()) } continue @@ -121,26 +121,15 @@ func (opt *inliningOptimizer) Optimize(ctx *OptimizerContext, a *ast.AST) *ast.A } // Copy the inlined AST expr and source info. - copyExpr := copyASTAndMetadata(ctx, inlineVar.def) + copyExpr := ctx.CopyASTAndMetadata(inlineVar.def) // Update the least common ancestor by inserting a cel.bind() call to the alias. inlined, bindMacro := ctx.NewBindMacro(lca.ID(), inlineVar.Alias(), copyExpr, lca) opt.inlineExpr(ctx, lca, inlined, inlineVar.Type()) - ctx.sourceInfo.SetMacroCall(lca.ID(), bindMacro) + ctx.SetMacroCall(lca.ID(), bindMacro) } return a } -// copyASTAndMetadata copies the input AST and propagates the macro metadata into the AST being -// optimized. -func copyASTAndMetadata(ctx *OptimizerContext, a *ast.AST) ast.Expr { - copyExpr, copyInfo := ctx.CopyAST(a) - // Add in the macro calls from the inlined AST - for id, call := range copyInfo.MacroCalls() { - ctx.sourceInfo.SetMacroCall(id, call) - } - return copyExpr -} - // inlineExpr replaces the current expression with the inlined one, unless the location of the inlining // happens within a presence test, e.g. has(a.b.c) -> inline alpha for a.b.c in which case an attempt is // made to determine whether the inlined value can be presence or existence tested. @@ -168,11 +157,11 @@ func (opt *inliningOptimizer) rewritePresenceExpr(ctx *OptimizerContext, prev, i if inlined.Kind() == ast.SelectKind { presenceTest, hasMacro := ctx.NewHasMacro(prev.ID(), inlined) ctx.UpdateExpr(prev, presenceTest) - ctx.sourceInfo.SetMacroCall(prev.ID(), hasMacro) + ctx.SetMacroCall(prev.ID(), hasMacro) return } - ctx.sourceInfo.ClearMacroCall(prev.ID()) + ctx.ClearMacroCall(prev.ID()) if inlinedType.IsAssignableType(NullType) { ctx.UpdateExpr(prev, ctx.NewCall(operators.NotEquals, @@ -201,8 +190,7 @@ func (opt *inliningOptimizer) rewritePresenceExpr(ctx *OptimizerContext, prev, i // in most cases. func isBindable(matches []ast.NavigableExpr, inlined ast.Expr, inlinedType *Type) bool { if inlinedType.IsAssignableType(NullType) || - inlinedType.HasTrait(traits.SizerType) || - inlinedType.HasTrait(traits.FieldTesterType) { + inlinedType.HasTrait(traits.SizerType) { return true } for _, m := range matches { diff --git a/vendor/github.com/google/cel-go/cel/optimizer.go b/vendor/github.com/google/cel-go/cel/optimizer.go index 99aeeb81..f26df462 100644 --- a/vendor/github.com/google/cel-go/cel/optimizer.go +++ b/vendor/github.com/google/cel-go/cel/optimizer.go @@ -212,6 +212,12 @@ type optimizerExprFactory struct { sourceInfo *ast.SourceInfo } +// NewAST creates an AST from the current expression using the tracked source info which +// is modified and managed by the OptimizerContext. +func (opt *optimizerExprFactory) NewAST(expr ast.Expr) *ast.AST { + return ast.NewAST(expr, opt.sourceInfo) +} + // CopyAST creates a renumbered copy of `Expr` and `SourceInfo` values of the input AST, where the // renumbering uses the same scheme as the core optimizer logic ensuring there are no collisions // between copies. @@ -226,6 +232,27 @@ func (opt *optimizerExprFactory) CopyAST(a *ast.AST) (ast.Expr, *ast.SourceInfo) return copyExpr, copyInfo } +// CopyASTAndMetadata copies the input AST and propagates the macro metadata into the AST being +// optimized. +func (opt *optimizerExprFactory) CopyASTAndMetadata(a *ast.AST) ast.Expr { + copyExpr, copyInfo := opt.CopyAST(a) + for macroID, call := range copyInfo.MacroCalls() { + opt.SetMacroCall(macroID, call) + } + return copyExpr +} + +// ClearMacroCall clears the macro at the given expression id. +func (opt *optimizerExprFactory) ClearMacroCall(id int64) { + opt.sourceInfo.ClearMacroCall(id) +} + +// SetMacroCall sets the macro call metadata for the given macro id within the tracked source info +// metadata. +func (opt *optimizerExprFactory) SetMacroCall(id int64, expr ast.Expr) { + opt.sourceInfo.SetMacroCall(id, expr) +} + // NewBindMacro creates an AST expression representing the expanded bind() macro, and a macro expression // representing the unexpanded call signature to be inserted into the source info macro call metadata. func (opt *optimizerExprFactory) NewBindMacro(macroID int64, varName string, varInit, remaining ast.Expr) (astExpr, macroExpr ast.Expr) { @@ -239,7 +266,7 @@ func (opt *optimizerExprFactory) NewBindMacro(macroID int64, varName string, var return id }) if call, exists := opt.sourceInfo.GetMacroCall(macroID); exists { - opt.sourceInfo.SetMacroCall(remainingID, opt.fac.CopyExpr(call)) + opt.SetMacroCall(remainingID, opt.fac.CopyExpr(call)) } astExpr = opt.fac.NewComprehension(macroID, diff --git a/vendor/github.com/google/cel-go/checker/cost.go b/vendor/github.com/google/cel-go/checker/cost.go index 3470d0a3..04244694 100644 --- a/vendor/github.com/google/cel-go/checker/cost.go +++ b/vendor/github.com/google/cel-go/checker/cost.go @@ -506,6 +506,9 @@ func (c *coster) costComprehension(e ast.Expr) CostEstimate { c.iterRanges.pop(comp.IterVar()) sum = sum.Add(c.cost(comp.Result())) rangeCnt := c.sizeEstimate(c.newAstNode(comp.IterRange())) + + c.computedSizes[e.ID()] = rangeCnt + rangeCost := rangeCnt.MultiplyByCost(stepCost.Add(loopCost)) sum = sum.Add(rangeCost) diff --git a/vendor/github.com/google/cel-go/common/ast/BUILD.bazel b/vendor/github.com/google/cel-go/common/ast/BUILD.bazel index c92a0f17..5c40c378 100644 --- a/vendor/github.com/google/cel-go/common/ast/BUILD.bazel +++ b/vendor/github.com/google/cel-go/common/ast/BUILD.bazel @@ -1,14 +1,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") package( - default_visibility = [ - "//cel:__subpackages__", - "//checker:__subpackages__", - "//common:__subpackages__", - "//ext:__subpackages__", - "//interpreter:__subpackages__", - "//parser:__subpackages__", - ], + default_visibility = ["//visibility:public"], licenses = ["notice"], # Apache 2.0 ) @@ -58,4 +51,4 @@ go_test( "@org_golang_google_protobuf//proto:go_default_library", "@org_golang_google_protobuf//encoding/prototext:go_default_library", ], -) \ No newline at end of file +) diff --git a/vendor/github.com/google/cel-go/common/types/int.go b/vendor/github.com/google/cel-go/common/types/int.go index 940772ae..0ae9507c 100644 --- a/vendor/github.com/google/cel-go/common/types/int.go +++ b/vendor/github.com/google/cel-go/common/types/int.go @@ -90,6 +90,18 @@ func (i Int) ConvertToNative(typeDesc reflect.Type) (any, error) { return nil, err } return reflect.ValueOf(v).Convert(typeDesc).Interface(), nil + case reflect.Int8: + v, err := int64ToInt8Checked(int64(i)) + if err != nil { + return nil, err + } + return reflect.ValueOf(v).Convert(typeDesc).Interface(), nil + case reflect.Int16: + v, err := int64ToInt16Checked(int64(i)) + if err != nil { + return nil, err + } + return reflect.ValueOf(v).Convert(typeDesc).Interface(), nil case reflect.Int64: return reflect.ValueOf(i).Convert(typeDesc).Interface(), nil case reflect.Ptr: diff --git a/vendor/github.com/google/cel-go/common/types/list.go b/vendor/github.com/google/cel-go/common/types/list.go index d4932b4a..06f48dde 100644 --- a/vendor/github.com/google/cel-go/common/types/list.go +++ b/vendor/github.com/google/cel-go/common/types/list.go @@ -190,7 +190,13 @@ func (l *baseList) ConvertToNative(typeDesc reflect.Type) (any, error) { // Allow the element ConvertToNative() function to determine whether conversion is possible. otherElemType := typeDesc.Elem() elemCount := l.size - nativeList := reflect.MakeSlice(typeDesc, elemCount, elemCount) + var nativeList reflect.Value + if typeDesc.Kind() == reflect.Array { + nativeList = reflect.New(reflect.ArrayOf(elemCount, typeDesc)).Elem().Index(0) + } else { + nativeList = reflect.MakeSlice(typeDesc, elemCount, elemCount) + + } for i := 0; i < elemCount; i++ { elem := l.NativeToValue(l.get(i)) nativeElemVal, err := elem.ConvertToNative(otherElemType) diff --git a/vendor/github.com/google/cel-go/common/types/overflow.go b/vendor/github.com/google/cel-go/common/types/overflow.go index c68a9218..dcb66ef5 100644 --- a/vendor/github.com/google/cel-go/common/types/overflow.go +++ b/vendor/github.com/google/cel-go/common/types/overflow.go @@ -326,6 +326,26 @@ func int64ToUint64Checked(v int64) (uint64, error) { return uint64(v), nil } +// int64ToInt8Checked converts an int64 to an int8 value. +// +// If the conversion fails due to overflow the error return value will be non-nil. +func int64ToInt8Checked(v int64) (int8, error) { + if v < math.MinInt8 || v > math.MaxInt8 { + return 0, errIntOverflow + } + return int8(v), nil +} + +// int64ToInt16Checked converts an int64 to an int16 value. +// +// If the conversion fails due to overflow the error return value will be non-nil. +func int64ToInt16Checked(v int64) (int16, error) { + if v < math.MinInt16 || v > math.MaxInt16 { + return 0, errIntOverflow + } + return int16(v), nil +} + // int64ToInt32Checked converts an int64 to an int32 value. // // If the conversion fails due to overflow the error return value will be non-nil. @@ -336,6 +356,26 @@ func int64ToInt32Checked(v int64) (int32, error) { return int32(v), nil } +// uint64ToUint8Checked converts a uint64 to a uint8 value. +// +// If the conversion fails due to overflow the error return value will be non-nil. +func uint64ToUint8Checked(v uint64) (uint8, error) { + if v > math.MaxUint8 { + return 0, errUintOverflow + } + return uint8(v), nil +} + +// uint64ToUint16Checked converts a uint64 to a uint16 value. +// +// If the conversion fails due to overflow the error return value will be non-nil. +func uint64ToUint16Checked(v uint64) (uint16, error) { + if v > math.MaxUint16 { + return 0, errUintOverflow + } + return uint16(v), nil +} + // uint64ToUint32Checked converts a uint64 to a uint32 value. // // If the conversion fails due to overflow the error return value will be non-nil. diff --git a/vendor/github.com/google/cel-go/common/types/provider.go b/vendor/github.com/google/cel-go/common/types/provider.go index 5157cd1f..c5ff05fd 100644 --- a/vendor/github.com/google/cel-go/common/types/provider.go +++ b/vendor/github.com/google/cel-go/common/types/provider.go @@ -590,12 +590,33 @@ func nativeToValue(a Adapter, value any) (ref.Val, bool) { return NewDynamicMap(a, v), true // type aliases of primitive types cannot be asserted as that type, but rather need // to be downcast to int32 before being converted to a CEL representation. + case reflect.Bool: + boolTupe := reflect.TypeOf(false) + return Bool(refValue.Convert(boolTupe).Interface().(bool)), true + case reflect.Int: + intType := reflect.TypeOf(int(0)) + return Int(refValue.Convert(intType).Interface().(int)), true + case reflect.Int8: + intType := reflect.TypeOf(int8(0)) + return Int(refValue.Convert(intType).Interface().(int8)), true + case reflect.Int16: + intType := reflect.TypeOf(int16(0)) + return Int(refValue.Convert(intType).Interface().(int16)), true case reflect.Int32: intType := reflect.TypeOf(int32(0)) return Int(refValue.Convert(intType).Interface().(int32)), true case reflect.Int64: intType := reflect.TypeOf(int64(0)) return Int(refValue.Convert(intType).Interface().(int64)), true + case reflect.Uint: + uintType := reflect.TypeOf(uint(0)) + return Uint(refValue.Convert(uintType).Interface().(uint)), true + case reflect.Uint8: + uintType := reflect.TypeOf(uint8(0)) + return Uint(refValue.Convert(uintType).Interface().(uint8)), true + case reflect.Uint16: + uintType := reflect.TypeOf(uint16(0)) + return Uint(refValue.Convert(uintType).Interface().(uint16)), true case reflect.Uint32: uintType := reflect.TypeOf(uint32(0)) return Uint(refValue.Convert(uintType).Interface().(uint32)), true @@ -608,6 +629,9 @@ func nativeToValue(a Adapter, value any) (ref.Val, bool) { case reflect.Float64: doubleType := reflect.TypeOf(float64(0)) return Double(refValue.Convert(doubleType).Interface().(float64)), true + case reflect.String: + stringType := reflect.TypeOf("") + return String(refValue.Convert(stringType).Interface().(string)), true } } return nil, false diff --git a/vendor/github.com/google/cel-go/common/types/string.go b/vendor/github.com/google/cel-go/common/types/string.go index a2990b26..3a93743f 100644 --- a/vendor/github.com/google/cel-go/common/types/string.go +++ b/vendor/github.com/google/cel-go/common/types/string.go @@ -66,10 +66,7 @@ func (s String) Compare(other ref.Val) ref.Val { func (s String) ConvertToNative(typeDesc reflect.Type) (any, error) { switch typeDesc.Kind() { case reflect.String: - if reflect.TypeOf(s).AssignableTo(typeDesc) { - return s, nil - } - return s.Value(), nil + return reflect.ValueOf(s).Convert(typeDesc).Interface(), nil case reflect.Ptr: switch typeDesc { case anyValueType: diff --git a/vendor/github.com/google/cel-go/common/types/uint.go b/vendor/github.com/google/cel-go/common/types/uint.go index 3257f9ad..6d74f30d 100644 --- a/vendor/github.com/google/cel-go/common/types/uint.go +++ b/vendor/github.com/google/cel-go/common/types/uint.go @@ -80,6 +80,18 @@ func (i Uint) ConvertToNative(typeDesc reflect.Type) (any, error) { return 0, err } return reflect.ValueOf(v).Convert(typeDesc).Interface(), nil + case reflect.Uint8: + v, err := uint64ToUint8Checked(uint64(i)) + if err != nil { + return 0, err + } + return reflect.ValueOf(v).Convert(typeDesc).Interface(), nil + case reflect.Uint16: + v, err := uint64ToUint16Checked(uint64(i)) + if err != nil { + return 0, err + } + return reflect.ValueOf(v).Convert(typeDesc).Interface(), nil case reflect.Uint64: return reflect.ValueOf(i).Convert(typeDesc).Interface(), nil case reflect.Ptr: diff --git a/vendor/github.com/google/cel-go/interpreter/attributes.go b/vendor/github.com/google/cel-go/interpreter/attributes.go index ca97bdfc..0098750d 100644 --- a/vendor/github.com/google/cel-go/interpreter/attributes.go +++ b/vendor/github.com/google/cel-go/interpreter/attributes.go @@ -287,6 +287,9 @@ func (a *absoluteAttribute) Resolve(vars Activation) (any, error) { // determine whether the type is unknown before returning. obj, found := vars.ResolveName(nm) if found { + if celErr, ok := obj.(*types.Err); ok { + return nil, celErr.Unwrap() + } obj, isOpt, err := applyQualifiers(vars, obj, a.qualifiers) if err != nil { return nil, err diff --git a/vendor/golang.org/x/mod/module/module.go b/vendor/golang.org/x/mod/module/module.go index cac1a899..2a364b22 100644 --- a/vendor/golang.org/x/mod/module/module.go +++ b/vendor/golang.org/x/mod/module/module.go @@ -506,7 +506,6 @@ var badWindowsNames = []string{ "PRN", "AUX", "NUL", - "COM0", "COM1", "COM2", "COM3", @@ -516,7 +515,6 @@ var badWindowsNames = []string{ "COM7", "COM8", "COM9", - "LPT0", "LPT1", "LPT2", "LPT3", diff --git a/vendor/modules.txt b/vendor/modules.txt index e4dc1863..6def0cf5 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -115,7 +115,7 @@ github.com/golang/protobuf/ptypes github.com/golang/protobuf/ptypes/any github.com/golang/protobuf/ptypes/duration github.com/golang/protobuf/ptypes/timestamp -# github.com/google/cel-go v0.19.0 +# github.com/google/cel-go v0.20.1 ## explicit; go 1.18 github.com/google/cel-go/cel github.com/google/cel-go/checker @@ -322,7 +322,7 @@ golang.org/x/crypto/sha3 golang.org/x/exp/constraints golang.org/x/exp/maps golang.org/x/exp/slices -# golang.org/x/mod v0.18.0 +# golang.org/x/mod v0.19.0 ## explicit; go 1.18 golang.org/x/mod/internal/lazyregexp golang.org/x/mod/modfile