build(deps): bump github.com/open-policy-agent/opa from 1.5.1 to 1.6.0
Bumps [github.com/open-policy-agent/opa](https://github.com/open-policy-agent/opa) from 1.5.1 to 1.6.0. - [Release notes](https://github.com/open-policy-agent/opa/releases) - [Changelog](https://github.com/open-policy-agent/opa/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-policy-agent/opa/compare/v1.5.1...v1.6.0) --- updated-dependencies: - dependency-name: github.com/open-policy-agent/opa dependency-version: 1.6.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
@@ -62,7 +62,7 @@ require (
|
||||
github.com/onsi/ginkgo v1.16.5
|
||||
github.com/onsi/ginkgo/v2 v2.23.4
|
||||
github.com/onsi/gomega v1.37.0
|
||||
github.com/open-policy-agent/opa v1.5.1
|
||||
github.com/open-policy-agent/opa v1.6.0
|
||||
github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20250603072916-fa601fb14450
|
||||
github.com/opencloud-eu/reva/v2 v2.34.0
|
||||
github.com/orcaman/concurrent-map v1.0.0
|
||||
@@ -308,7 +308,7 @@ require (
|
||||
github.com/tinylib/msgp v1.3.0 // indirect
|
||||
github.com/toorop/go-dkim v0.0.0-20201103131630-e1cd1a0a5208 // indirect
|
||||
github.com/trustelem/zxcvbn v1.0.1 // indirect
|
||||
github.com/vektah/gqlparser/v2 v2.5.26 // indirect
|
||||
github.com/vektah/gqlparser/v2 v2.5.28 // indirect
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
||||
github.com/wk8/go-ordered-map v1.0.0 // indirect
|
||||
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
||||
|
||||
@@ -200,8 +200,6 @@ github.com/c-bata/go-prompt v0.2.5/go.mod h1:vFnjEGDIIA/Lib7giyE4E9c50Lvl8j0S+7F
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||
github.com/cenkalti/backoff/v4 v4.1.0/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/cenkalti/backoff/v5 v5.0.2 h1:rIfFVxEf1QsI7E1ZHfp/B4DF/6QBAUhmgkxc0H7Zss8=
|
||||
github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
@@ -864,8 +862,8 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y=
|
||||
github.com/onsi/gomega v1.37.0/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0=
|
||||
github.com/open-policy-agent/opa v1.5.1 h1:LTxxBJusMVjfs67W4FoRcnMfXADIGFMzpqnfk6D08Cg=
|
||||
github.com/open-policy-agent/opa v1.5.1/go.mod h1:bYbS7u+uhTI+cxHQIpzvr5hxX0hV7urWtY+38ZtjMgk=
|
||||
github.com/open-policy-agent/opa v1.6.0 h1:/S/cnNQJ2MUMNzizHPbisTWBHowmLkPrugY5jjkPlRQ=
|
||||
github.com/open-policy-agent/opa v1.6.0/go.mod h1:zFmw4P+W62+CWGYRDDswfVYSCnPo6oYaktQnfIaRFC4=
|
||||
github.com/opencloud-eu/go-micro-plugins/v4/store/nats-js-kv v0.0.0-20250512152754-23325793059a h1:Sakl76blJAaM6NxylVkgSzktjo2dS504iDotEFJsh3M=
|
||||
github.com/opencloud-eu/go-micro-plugins/v4/store/nats-js-kv v0.0.0-20250512152754-23325793059a/go.mod h1:pjcozWijkNPbEtX5SIQaxEW/h8VAVZYTLx+70bmB3LY=
|
||||
github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20250603072916-fa601fb14450 h1:QWn9G2f1R/EbyZSbkjtd9jqNq9X0NIphmmD4KYLNZtA=
|
||||
@@ -1116,8 +1114,8 @@ github.com/urfave/cli/v2 v2.27.7/go.mod h1:CyNAG/xg+iAOg0N4MPGZqVmv2rCoP267496AO
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
|
||||
github.com/valyala/fasttemplate v1.1.0/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
|
||||
github.com/vektah/gqlparser/v2 v2.5.26 h1:REqqFkO8+SOEgZHR/eHScjjVjGS8Nk3RMO/juiTobN4=
|
||||
github.com/vektah/gqlparser/v2 v2.5.26/go.mod h1:D1/VCZtV3LPnQrcPBeR/q5jkSQIPti0uYCP/RI0gIeo=
|
||||
github.com/vektah/gqlparser/v2 v2.5.28 h1:bIulcl3LF69ba6EiZVGD88y4MkM+Jxrf3P2MX8xLRkY=
|
||||
github.com/vektah/gqlparser/v2 v2.5.28/go.mod h1:D1/VCZtV3LPnQrcPBeR/q5jkSQIPti0uYCP/RI0gIeo=
|
||||
github.com/vinyldns/go-vinyldns v0.0.0-20200917153823-148a5f6b8f14/go.mod h1:RWc47jtnVuQv6+lY3c768WtXCas/Xi+U5UFc5xULmYg=
|
||||
github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8=
|
||||
github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=
|
||||
@@ -1191,8 +1189,8 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 h1:Ahq7pZmv87yiyn3jeFz
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0/go.mod h1:MJTqhM0im3mRLw1i8uGHnCvUEeS7VwRyxlLC78PA18M=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 h1:EtFWSnwW9hGObjkIdmlnWSydO+Qs8OwzfzXLUPg4xOc=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0/go.mod h1:QjUEoiGCPkvFZ/MjK6ZZfNOS6mfVEVKYE99dFhuN2LI=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0 h1:xJ2qHD0C1BeYVTLLR9sX12+Qb95kfeD/byKj6Ky1pXg=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0/go.mod h1:u5BF1xyjstDowA1R5QAO9JHzqK+ublenEW/dyqTjBVk=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.36.0 h1:nRVXXvf78e00EwY6Wp0YII8ww2JVWshZ20HfTlE11AM=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.36.0/go.mod h1:r49hO7CgrxY9Voaj3Xe8pANWtr0Oq916d0XAmOoCZAQ=
|
||||
go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE=
|
||||
go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
|
||||
go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI=
|
||||
|
||||
+2
-2
@@ -9,14 +9,14 @@ import (
|
||||
)
|
||||
|
||||
func InternedBooleanTerm(b bool) *Term {
|
||||
return v1.InternedBooleanTerm(b)
|
||||
return v1.InternedTerm(b)
|
||||
}
|
||||
|
||||
// InternedIntNumberTerm returns a term with the given integer value. The term is
|
||||
// cached between -1 to 512, and for values outside of that range, this function
|
||||
// is equivalent to ast.IntNumberTerm.
|
||||
func InternedIntNumberTerm(i int) *Term {
|
||||
return v1.InternedIntNumberTerm(i)
|
||||
return v1.InternedTerm(i)
|
||||
}
|
||||
|
||||
func HasInternedIntNumberTerm(i int) bool {
|
||||
|
||||
+4850
File diff suppressed because it is too large
Load Diff
+2
-2
@@ -723,7 +723,7 @@ func (e *EditTree) Unfold(path ast.Ref) (*EditTree, error) {
|
||||
return child.Unfold(path[1:])
|
||||
}
|
||||
|
||||
idxt := ast.InternedIntNumberTerm(idx)
|
||||
idxt := ast.InternedTerm(idx)
|
||||
|
||||
// Fall back to looking up the key in e.value.
|
||||
// Extend the tree if key is present. Error otherwise.
|
||||
@@ -1028,7 +1028,7 @@ func (e *EditTree) Exists(path ast.Ref) bool {
|
||||
}
|
||||
// Fallback if child lookup failed.
|
||||
// We have to ensure that the lookup term is a number here, or Find will fail.
|
||||
_, err = x.Find(ast.Ref{ast.InternedIntNumberTerm(idx)}.Concat(path[1:]))
|
||||
_, err = x.Find(ast.Ref{ast.InternedTerm(idx)}.Concat(path[1:]))
|
||||
return err == nil
|
||||
default:
|
||||
// Catch all primitive types.
|
||||
|
||||
+3
-3
@@ -24,7 +24,7 @@ func IsAllFutureKeywords(imp *ast.Import) bool {
|
||||
path := imp.Path.Value.(ast.Ref)
|
||||
return len(path) == 2 &&
|
||||
ast.FutureRootDocument.Equal(path[0]) &&
|
||||
path[1].Equal(ast.InternedStringTerm("keywords"))
|
||||
path[1].Equal(ast.InternedTerm("keywords"))
|
||||
}
|
||||
|
||||
// IsFutureKeyword returns true if the passed *ast.Import is `future.keywords.{kw}`
|
||||
@@ -32,7 +32,7 @@ func IsFutureKeyword(imp *ast.Import, kw string) bool {
|
||||
path := imp.Path.Value.(ast.Ref)
|
||||
return len(path) == 3 &&
|
||||
ast.FutureRootDocument.Equal(path[0]) &&
|
||||
path[1].Equal(ast.InternedStringTerm("keywords")) &&
|
||||
path[1].Equal(ast.InternedTerm("keywords")) &&
|
||||
path[2].Equal(ast.StringTerm(kw))
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ func WhichFutureKeyword(imp *ast.Import) (string, bool) {
|
||||
path := imp.Path.Value.(ast.Ref)
|
||||
if len(path) == 3 &&
|
||||
ast.FutureRootDocument.Equal(path[0]) &&
|
||||
path[1].Equal(ast.InternedStringTerm("keywords")) {
|
||||
path[1].Equal(ast.InternedTerm("keywords")) {
|
||||
if str, ok := path[2].Value.(ast.String); ok {
|
||||
return string(str), true
|
||||
}
|
||||
|
||||
+20
-20
@@ -423,28 +423,28 @@ func (a *Annotations) toObject() (*Object, *Error) {
|
||||
if len(a.Scope) > 0 {
|
||||
switch a.Scope {
|
||||
case annotationScopeDocument:
|
||||
obj.Insert(InternedStringTerm("scope"), InternedStringTerm("document"))
|
||||
obj.Insert(InternedTerm("scope"), InternedTerm("document"))
|
||||
case annotationScopePackage:
|
||||
obj.Insert(InternedStringTerm("scope"), InternedStringTerm("package"))
|
||||
obj.Insert(InternedTerm("scope"), InternedTerm("package"))
|
||||
case annotationScopeRule:
|
||||
obj.Insert(InternedStringTerm("scope"), InternedStringTerm("rule"))
|
||||
obj.Insert(InternedTerm("scope"), InternedTerm("rule"))
|
||||
case annotationScopeSubpackages:
|
||||
obj.Insert(InternedStringTerm("scope"), InternedStringTerm("subpackages"))
|
||||
obj.Insert(InternedTerm("scope"), InternedTerm("subpackages"))
|
||||
default:
|
||||
obj.Insert(InternedStringTerm("scope"), StringTerm(a.Scope))
|
||||
obj.Insert(InternedTerm("scope"), StringTerm(a.Scope))
|
||||
}
|
||||
}
|
||||
|
||||
if len(a.Title) > 0 {
|
||||
obj.Insert(InternedStringTerm("title"), StringTerm(a.Title))
|
||||
obj.Insert(InternedTerm("title"), StringTerm(a.Title))
|
||||
}
|
||||
|
||||
if a.Entrypoint {
|
||||
obj.Insert(InternedStringTerm("entrypoint"), InternedBooleanTerm(true))
|
||||
obj.Insert(InternedTerm("entrypoint"), InternedTerm(true))
|
||||
}
|
||||
|
||||
if len(a.Description) > 0 {
|
||||
obj.Insert(InternedStringTerm("description"), StringTerm(a.Description))
|
||||
obj.Insert(InternedTerm("description"), StringTerm(a.Description))
|
||||
}
|
||||
|
||||
if len(a.Organizations) > 0 {
|
||||
@@ -452,19 +452,19 @@ func (a *Annotations) toObject() (*Object, *Error) {
|
||||
for _, org := range a.Organizations {
|
||||
orgs = append(orgs, StringTerm(org))
|
||||
}
|
||||
obj.Insert(InternedStringTerm("organizations"), ArrayTerm(orgs...))
|
||||
obj.Insert(InternedTerm("organizations"), ArrayTerm(orgs...))
|
||||
}
|
||||
|
||||
if len(a.RelatedResources) > 0 {
|
||||
rrs := make([]*Term, 0, len(a.RelatedResources))
|
||||
for _, rr := range a.RelatedResources {
|
||||
rrObj := NewObject(Item(InternedStringTerm("ref"), StringTerm(rr.Ref.String())))
|
||||
rrObj := NewObject(Item(InternedTerm("ref"), StringTerm(rr.Ref.String())))
|
||||
if len(rr.Description) > 0 {
|
||||
rrObj.Insert(InternedStringTerm("description"), StringTerm(rr.Description))
|
||||
rrObj.Insert(InternedTerm("description"), StringTerm(rr.Description))
|
||||
}
|
||||
rrs = append(rrs, NewTerm(rrObj))
|
||||
}
|
||||
obj.Insert(InternedStringTerm("related_resources"), ArrayTerm(rrs...))
|
||||
obj.Insert(InternedTerm("related_resources"), ArrayTerm(rrs...))
|
||||
}
|
||||
|
||||
if len(a.Authors) > 0 {
|
||||
@@ -472,14 +472,14 @@ func (a *Annotations) toObject() (*Object, *Error) {
|
||||
for _, author := range a.Authors {
|
||||
aObj := NewObject()
|
||||
if len(author.Name) > 0 {
|
||||
aObj.Insert(InternedStringTerm("name"), StringTerm(author.Name))
|
||||
aObj.Insert(InternedTerm("name"), StringTerm(author.Name))
|
||||
}
|
||||
if len(author.Email) > 0 {
|
||||
aObj.Insert(InternedStringTerm("email"), StringTerm(author.Email))
|
||||
aObj.Insert(InternedTerm("email"), StringTerm(author.Email))
|
||||
}
|
||||
as = append(as, NewTerm(aObj))
|
||||
}
|
||||
obj.Insert(InternedStringTerm("authors"), ArrayTerm(as...))
|
||||
obj.Insert(InternedTerm("authors"), ArrayTerm(as...))
|
||||
}
|
||||
|
||||
if len(a.Schemas) > 0 {
|
||||
@@ -487,21 +487,21 @@ func (a *Annotations) toObject() (*Object, *Error) {
|
||||
for _, s := range a.Schemas {
|
||||
sObj := NewObject()
|
||||
if len(s.Path) > 0 {
|
||||
sObj.Insert(InternedStringTerm("path"), NewTerm(s.Path.toArray()))
|
||||
sObj.Insert(InternedTerm("path"), NewTerm(s.Path.toArray()))
|
||||
}
|
||||
if len(s.Schema) > 0 {
|
||||
sObj.Insert(InternedStringTerm("schema"), NewTerm(s.Schema.toArray()))
|
||||
sObj.Insert(InternedTerm("schema"), NewTerm(s.Schema.toArray()))
|
||||
}
|
||||
if s.Definition != nil {
|
||||
def, err := InterfaceToValue(s.Definition)
|
||||
if err != nil {
|
||||
return nil, NewError(CompileErr, a.Location, "invalid definition in schema annotation: %s", err.Error())
|
||||
}
|
||||
sObj.Insert(InternedStringTerm("definition"), NewTerm(def))
|
||||
sObj.Insert(InternedTerm("definition"), NewTerm(def))
|
||||
}
|
||||
ss = append(ss, NewTerm(sObj))
|
||||
}
|
||||
obj.Insert(InternedStringTerm("schemas"), ArrayTerm(ss...))
|
||||
obj.Insert(InternedTerm("schemas"), ArrayTerm(ss...))
|
||||
}
|
||||
|
||||
if len(a.Custom) > 0 {
|
||||
@@ -509,7 +509,7 @@ func (a *Annotations) toObject() (*Object, *Error) {
|
||||
if err != nil {
|
||||
return nil, NewError(CompileErr, a.Location, "invalid custom annotation %s", err.Error())
|
||||
}
|
||||
obj.Insert(InternedStringTerm("custom"), NewTerm(c))
|
||||
obj.Insert(InternedTerm("custom"), NewTerm(c))
|
||||
}
|
||||
|
||||
return &obj, nil
|
||||
|
||||
+313
-106
File diff suppressed because it is too large
Load Diff
+3
@@ -55,6 +55,7 @@ const FeatureRefHeadStringPrefixes = "rule_head_ref_string_prefixes"
|
||||
const FeatureRefHeads = "rule_head_refs"
|
||||
const FeatureRegoV1 = "rego_v1"
|
||||
const FeatureRegoV1Import = "rego_v1_import"
|
||||
const FeatureKeywordsInRefs = "keywords_in_refs"
|
||||
|
||||
// Capabilities defines a structure containing data that describes the capabilities
|
||||
// or features supported by a particular version of OPA.
|
||||
@@ -133,6 +134,7 @@ func CapabilitiesForThisVersion(opts ...CapabilitiesOption) *Capabilities {
|
||||
FeatureRefHeads,
|
||||
FeatureRegoV1Import,
|
||||
FeatureRegoV1, // Included in v0 capabilities to allow v1 bundles in --v0-compatible mode
|
||||
FeatureKeywordsInRefs,
|
||||
}
|
||||
default:
|
||||
for kw := range futureKeywords {
|
||||
@@ -141,6 +143,7 @@ func CapabilitiesForThisVersion(opts ...CapabilitiesOption) *Capabilities {
|
||||
|
||||
f.Features = []string{
|
||||
FeatureRegoV1,
|
||||
FeatureKeywordsInRefs,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+9
-3
@@ -211,8 +211,10 @@ func (tc *typeChecker) getSchemaType(schemaAnnot *SchemaAnnotation, rule *Rule)
|
||||
tc.schemaTypes = make(map[string]types.Type)
|
||||
}
|
||||
|
||||
if refType, exists := tc.schemaTypes[schemaAnnot.Schema.String()]; exists {
|
||||
return refType, nil
|
||||
if len(schemaAnnot.Schema) > 0 {
|
||||
if refType, exists := tc.schemaTypes[schemaAnnot.Schema.String()]; exists {
|
||||
return refType, nil
|
||||
}
|
||||
}
|
||||
|
||||
refType, err := processAnnotation(tc.ss, schemaAnnot, rule, tc.allowNet)
|
||||
@@ -224,7 +226,11 @@ func (tc *typeChecker) getSchemaType(schemaAnnot *SchemaAnnotation, rule *Rule)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
tc.schemaTypes[schemaAnnot.Schema.String()] = refType
|
||||
// Only add to cache if schema is read from file
|
||||
if len(schemaAnnot.Schema) > 0 {
|
||||
tc.schemaTypes[schemaAnnot.Schema.String()] = refType
|
||||
}
|
||||
|
||||
return refType, nil
|
||||
|
||||
}
|
||||
|
||||
+3
-3
@@ -964,7 +964,7 @@ func (c *Compiler) buildComprehensionIndices() {
|
||||
}
|
||||
}
|
||||
|
||||
var futureKeywordsPrefix = Ref{FutureRootDocument, InternedStringTerm("keywords")}
|
||||
var futureKeywordsPrefix = Ref{FutureRootDocument, InternedTerm("keywords")}
|
||||
|
||||
// buildRequiredCapabilities updates the required capabilities on the compiler
|
||||
// to include any keyword and feature dependencies present in the modules. The
|
||||
@@ -2531,13 +2531,13 @@ func createMetadataChain(chain []*AnnotationsRef) (*Term, *Error) {
|
||||
for _, link := range chain {
|
||||
// Dropping leading 'data' element of path
|
||||
p := link.Path[1:].toArray()
|
||||
obj := NewObject(Item(InternedStringTerm("path"), NewTerm(p)))
|
||||
obj := NewObject(Item(InternedTerm("path"), NewTerm(p)))
|
||||
if link.Annotations != nil {
|
||||
annotObj, err := link.Annotations.toObject()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
obj.Insert(InternedStringTerm("annotations"), NewTerm(*annotObj))
|
||||
obj.Insert(InternedTerm("annotations"), NewTerm(*annotObj))
|
||||
}
|
||||
metaArray = metaArray.Append(NewTerm(obj))
|
||||
}
|
||||
|
||||
+2
-2
@@ -402,7 +402,7 @@ func (i *refindices) updateGlobMatch(rule *Rule, expr *Expr) {
|
||||
if ref == nil {
|
||||
for j, arg := range args {
|
||||
if arg.Equal(match) {
|
||||
ref = Ref{FunctionArgRootDocument, InternedIntNumberTerm(j)}
|
||||
ref = Ref{FunctionArgRootDocument, InternedTerm(j)}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -822,7 +822,7 @@ func eqOperandsToRefAndValue(isVirtual func(Ref) bool, args []*Term, a, b *Term)
|
||||
for i, arg := range args {
|
||||
if arg.Value.Compare(a.Value) == 0 {
|
||||
if bval, ok := indexValue(b); ok {
|
||||
return &refindex{Ref: Ref{FunctionArgRootDocument, InternedIntNumberTerm(i)}, Value: bval}, true
|
||||
return &refindex{Ref: Ref{FunctionArgRootDocument, InternedTerm(i)}, Value: bval}, true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+5
@@ -116,6 +116,11 @@ func (s *Scanner) HasKeyword(keywords map[string]tokens.Token) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *Scanner) IsKeyword(str string) bool {
|
||||
_, ok := s.keywords[str]
|
||||
return ok
|
||||
}
|
||||
|
||||
func (s *Scanner) SetRegoV1Compatible() {
|
||||
s.regoV1Compatible = true
|
||||
}
|
||||
|
||||
+100
-220
@@ -8,18 +8,16 @@ import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type internable interface {
|
||||
bool | string | int | int8 | int16 | int32 | int64 | uint | uint8 | uint16 | uint32 | uint64
|
||||
}
|
||||
|
||||
// NOTE! Great care must be taken **not** to modify the terms returned
|
||||
// from these functions, as they are shared across all callers.
|
||||
// This package is currently considered experimental, and may change
|
||||
// at any time without notice.
|
||||
|
||||
var (
|
||||
booleanTrueTerm = &Term{Value: Boolean(true)}
|
||||
booleanFalseTerm = &Term{Value: Boolean(false)}
|
||||
|
||||
// since this is by far the most common negative number
|
||||
minusOneTerm = &Term{Value: Number("-1")}
|
||||
|
||||
InternedNullTerm = &Term{Value: Null{}}
|
||||
|
||||
InternedEmptyString = StringTerm("")
|
||||
@@ -28,6 +26,16 @@ var (
|
||||
InternedEmptySet = SetTerm()
|
||||
|
||||
InternedEmptyArrayValue = NewArray()
|
||||
|
||||
booleanTrueTerm = &Term{Value: Boolean(true)}
|
||||
booleanFalseTerm = &Term{Value: Boolean(false)}
|
||||
|
||||
// since this is by far the most common negative number
|
||||
minusOneTerm = &Term{Value: Number("-1")}
|
||||
|
||||
internedStringTerms = map[string]*Term{
|
||||
"": InternedEmptyString,
|
||||
}
|
||||
)
|
||||
|
||||
// InternStringTerm interns the given strings as terms. Note that Interning is
|
||||
@@ -44,28 +52,37 @@ func InternStringTerm(str ...string) {
|
||||
}
|
||||
}
|
||||
|
||||
// InternedBooleanTerm returns an interned term with the given boolean value.
|
||||
func InternedBooleanTerm(b bool) *Term {
|
||||
if b {
|
||||
return booleanTrueTerm
|
||||
// Interned returns a possibly interned term for the given scalar value.
|
||||
// If the value is not interned, a new term is created for that value.
|
||||
func InternedTerm[T internable](v T) *Term {
|
||||
switch value := any(v).(type) {
|
||||
case bool:
|
||||
return internedBooleanTerm(value)
|
||||
case string:
|
||||
return internedStringTerm(value)
|
||||
case int:
|
||||
return internedIntNumberTerm(value)
|
||||
case int8:
|
||||
return internedIntNumberTerm(int(value))
|
||||
case int16:
|
||||
return internedIntNumberTerm(int(value))
|
||||
case int32:
|
||||
return internedIntNumberTerm(int(value))
|
||||
case int64:
|
||||
return internedIntNumberTerm(int(value))
|
||||
case uint:
|
||||
return internedIntNumberTerm(int(value))
|
||||
case uint8:
|
||||
return internedIntNumberTerm(int(value))
|
||||
case uint16:
|
||||
return internedIntNumberTerm(int(value))
|
||||
case uint32:
|
||||
return internedIntNumberTerm(int(value))
|
||||
case uint64:
|
||||
return internedIntNumberTerm(int(value))
|
||||
default:
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
return booleanFalseTerm
|
||||
}
|
||||
|
||||
// InternedIntNumberTerm returns a term with the given integer value. The term is
|
||||
// cached between -1 to 512, and for values outside of that range, this function
|
||||
// is equivalent to ast.IntNumberTerm.
|
||||
func InternedIntNumberTerm(i int) *Term {
|
||||
if i >= 0 && i < len(intNumberTerms) {
|
||||
return intNumberTerms[i]
|
||||
}
|
||||
|
||||
if i == -1 {
|
||||
return minusOneTerm
|
||||
}
|
||||
|
||||
return &Term{Value: Number(strconv.Itoa(i))}
|
||||
}
|
||||
|
||||
// InternedIntFromString returns a term with the given integer value if the string
|
||||
@@ -85,17 +102,6 @@ func HasInternedIntNumberTerm(i int) bool {
|
||||
return i >= -1 && i < len(intNumberTerms)
|
||||
}
|
||||
|
||||
// InternedStringTerm returns an interned term with the given string value. If the
|
||||
// provided string is not interned, a new term is created for that value. It does *not*
|
||||
// modify the global interned terms map.
|
||||
func InternedStringTerm(s string) *Term {
|
||||
if term, ok := internedStringTerms[s]; ok {
|
||||
return term
|
||||
}
|
||||
|
||||
return StringTerm(s)
|
||||
}
|
||||
|
||||
// Returns an interned string term representing the integer value i, if
|
||||
// interned. If not, creates a new StringTerm for the integer value.
|
||||
func InternedIntegerString(i int) *Term {
|
||||
@@ -117,195 +123,69 @@ func InternedIntegerString(i int) *Term {
|
||||
return StringTerm(s)
|
||||
}
|
||||
|
||||
var internedStringTerms = map[string]*Term{
|
||||
"": InternedEmptyString,
|
||||
"0": StringTerm("0"),
|
||||
"1": StringTerm("1"),
|
||||
"2": StringTerm("2"),
|
||||
"3": StringTerm("3"),
|
||||
"4": StringTerm("4"),
|
||||
"5": StringTerm("5"),
|
||||
"6": StringTerm("6"),
|
||||
"7": StringTerm("7"),
|
||||
"8": StringTerm("8"),
|
||||
"9": StringTerm("9"),
|
||||
"10": StringTerm("10"),
|
||||
"11": StringTerm("11"),
|
||||
"12": StringTerm("12"),
|
||||
"13": StringTerm("13"),
|
||||
"14": StringTerm("14"),
|
||||
"15": StringTerm("15"),
|
||||
"16": StringTerm("16"),
|
||||
"17": StringTerm("17"),
|
||||
"18": StringTerm("18"),
|
||||
"19": StringTerm("19"),
|
||||
"20": StringTerm("20"),
|
||||
"21": StringTerm("21"),
|
||||
"22": StringTerm("22"),
|
||||
"23": StringTerm("23"),
|
||||
"24": StringTerm("24"),
|
||||
"25": StringTerm("25"),
|
||||
"26": StringTerm("26"),
|
||||
"27": StringTerm("27"),
|
||||
"28": StringTerm("28"),
|
||||
"29": StringTerm("29"),
|
||||
"30": StringTerm("30"),
|
||||
"31": StringTerm("31"),
|
||||
"32": StringTerm("32"),
|
||||
"33": StringTerm("33"),
|
||||
"34": StringTerm("34"),
|
||||
"35": StringTerm("35"),
|
||||
"36": StringTerm("36"),
|
||||
"37": StringTerm("37"),
|
||||
"38": StringTerm("38"),
|
||||
"39": StringTerm("39"),
|
||||
"40": StringTerm("40"),
|
||||
"41": StringTerm("41"),
|
||||
"42": StringTerm("42"),
|
||||
"43": StringTerm("43"),
|
||||
"44": StringTerm("44"),
|
||||
"45": StringTerm("45"),
|
||||
"46": StringTerm("46"),
|
||||
"47": StringTerm("47"),
|
||||
"48": StringTerm("48"),
|
||||
"49": StringTerm("49"),
|
||||
"50": StringTerm("50"),
|
||||
"51": StringTerm("51"),
|
||||
"52": StringTerm("52"),
|
||||
"53": StringTerm("53"),
|
||||
"54": StringTerm("54"),
|
||||
"55": StringTerm("55"),
|
||||
"56": StringTerm("56"),
|
||||
"57": StringTerm("57"),
|
||||
"58": StringTerm("58"),
|
||||
"59": StringTerm("59"),
|
||||
"60": StringTerm("60"),
|
||||
"61": StringTerm("61"),
|
||||
"62": StringTerm("62"),
|
||||
"63": StringTerm("63"),
|
||||
"64": StringTerm("64"),
|
||||
"65": StringTerm("65"),
|
||||
"66": StringTerm("66"),
|
||||
"67": StringTerm("67"),
|
||||
"68": StringTerm("68"),
|
||||
"69": StringTerm("69"),
|
||||
"70": StringTerm("70"),
|
||||
"71": StringTerm("71"),
|
||||
"72": StringTerm("72"),
|
||||
"73": StringTerm("73"),
|
||||
"74": StringTerm("74"),
|
||||
"75": StringTerm("75"),
|
||||
"76": StringTerm("76"),
|
||||
"77": StringTerm("77"),
|
||||
"78": StringTerm("78"),
|
||||
"79": StringTerm("79"),
|
||||
"80": StringTerm("80"),
|
||||
"81": StringTerm("81"),
|
||||
"82": StringTerm("82"),
|
||||
"83": StringTerm("83"),
|
||||
"84": StringTerm("84"),
|
||||
"85": StringTerm("85"),
|
||||
"86": StringTerm("86"),
|
||||
"87": StringTerm("87"),
|
||||
"88": StringTerm("88"),
|
||||
"89": StringTerm("89"),
|
||||
"90": StringTerm("90"),
|
||||
"91": StringTerm("91"),
|
||||
"92": StringTerm("92"),
|
||||
"93": StringTerm("93"),
|
||||
"94": StringTerm("94"),
|
||||
"95": StringTerm("95"),
|
||||
"96": StringTerm("96"),
|
||||
"97": StringTerm("97"),
|
||||
"98": StringTerm("98"),
|
||||
"99": StringTerm("99"),
|
||||
"100": StringTerm("100"),
|
||||
// InternedBooleanTerm returns an interned term with the given boolean value.
|
||||
func internedBooleanTerm(b bool) *Term {
|
||||
if b {
|
||||
return booleanTrueTerm
|
||||
}
|
||||
|
||||
// Types
|
||||
"null": StringTerm("null"),
|
||||
"boolean": StringTerm("boolean"),
|
||||
"number": StringTerm("number"),
|
||||
"string": StringTerm("string"),
|
||||
"array": StringTerm("array"),
|
||||
"object": StringTerm("object"),
|
||||
"set": StringTerm("set"),
|
||||
return booleanFalseTerm
|
||||
}
|
||||
|
||||
// Runtime
|
||||
"config": StringTerm("config"),
|
||||
"env": StringTerm("env"),
|
||||
"version": StringTerm("version"),
|
||||
"commit": StringTerm("commit"),
|
||||
"authorization_enabled": StringTerm("authorization_enabled"),
|
||||
"skip_known_schema_check": StringTerm("skip_known_schema_check"),
|
||||
// InternedIntNumberTerm returns a term with the given integer value. The term is
|
||||
// cached between -1 to 512, and for values outside of that range, this function
|
||||
// is equivalent to IntNumberTerm.
|
||||
func internedIntNumberTerm(i int) *Term {
|
||||
if i >= 0 && i < len(intNumberTerms) {
|
||||
return intNumberTerms[i]
|
||||
}
|
||||
|
||||
// Annotations
|
||||
"annotations": StringTerm("annotations"),
|
||||
"scope": StringTerm("scope"),
|
||||
"title": StringTerm("title"),
|
||||
"entrypoint": StringTerm("entrypoint"),
|
||||
"description": StringTerm("description"),
|
||||
"organizations": StringTerm("organizations"),
|
||||
"authors": StringTerm("authors"),
|
||||
"related_resources": StringTerm("related_resources"),
|
||||
"schemas": StringTerm("schemas"),
|
||||
"custom": StringTerm("custom"),
|
||||
"ref": StringTerm("ref"),
|
||||
"name": StringTerm("name"),
|
||||
"email": StringTerm("email"),
|
||||
"schema": StringTerm("schema"),
|
||||
"definition": StringTerm("definition"),
|
||||
"document": StringTerm("document"),
|
||||
"package": StringTerm("package"),
|
||||
"rule": StringTerm("rule"),
|
||||
"subpackages": StringTerm("subpackages"),
|
||||
if i == -1 {
|
||||
return minusOneTerm
|
||||
}
|
||||
|
||||
// Debug
|
||||
"text": StringTerm("text"),
|
||||
"value": StringTerm("value"),
|
||||
"bindings": StringTerm("bindings"),
|
||||
"expressions": StringTerm("expressions"),
|
||||
return &Term{Value: Number(strconv.Itoa(i))}
|
||||
}
|
||||
|
||||
// Various
|
||||
"data": StringTerm("data"),
|
||||
"input": StringTerm("input"),
|
||||
"result": StringTerm("result"),
|
||||
"keywords": StringTerm("keywords"),
|
||||
"path": StringTerm("path"),
|
||||
"v1": StringTerm("v1"),
|
||||
"error": StringTerm("error"),
|
||||
"partial": StringTerm("partial"),
|
||||
// InternedStringTerm returns an interned term with the given string value. If the
|
||||
// provided string is not interned, a new term is created for that value. It does *not*
|
||||
// modify the global interned terms map.
|
||||
func internedStringTerm(s string) *Term {
|
||||
if term, ok := internedStringTerms[s]; ok {
|
||||
return term
|
||||
}
|
||||
|
||||
// HTTP
|
||||
"code": StringTerm("code"),
|
||||
"message": StringTerm("message"),
|
||||
"status_code": StringTerm("status_code"),
|
||||
"method": StringTerm("method"),
|
||||
"url": StringTerm("url"),
|
||||
return StringTerm(s)
|
||||
}
|
||||
|
||||
// JWT
|
||||
"enc": StringTerm("enc"),
|
||||
"cty": StringTerm("cty"),
|
||||
"iss": StringTerm("iss"),
|
||||
"exp": StringTerm("exp"),
|
||||
"nbf": StringTerm("nbf"),
|
||||
"aud": StringTerm("aud"),
|
||||
"secret": StringTerm("secret"),
|
||||
"cert": StringTerm("cert"),
|
||||
|
||||
// Decisions
|
||||
"revision": StringTerm("revision"),
|
||||
"labels": StringTerm("labels"),
|
||||
"decision_id": StringTerm("decision_id"),
|
||||
"bundles": StringTerm("bundles"),
|
||||
"query": StringTerm("query"),
|
||||
"mapped_result": StringTerm("mapped_result"),
|
||||
"nd_builtin_cache": StringTerm("nd_builtin_cache"),
|
||||
"erased": StringTerm("erased"),
|
||||
"masked": StringTerm("masked"),
|
||||
"requested_by": StringTerm("requested_by"),
|
||||
"timestamp": StringTerm("timestamp"),
|
||||
"metrics": StringTerm("metrics"),
|
||||
"req_id": StringTerm("req_id"),
|
||||
func init() {
|
||||
InternStringTerm(
|
||||
// Numbers
|
||||
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20",
|
||||
"21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38",
|
||||
"39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "55", "56",
|
||||
"57", "58", "59", "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "70", "71", "72", "73", "74",
|
||||
"75", "76", "77", "78", "79", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "90", "91", "92",
|
||||
"93", "94", "95", "96", "97", "98", "99", "100",
|
||||
// Types
|
||||
"null", "boolean", "number", "string", "array", "object", "set", "var", "ref", "true", "false",
|
||||
// Runtime
|
||||
"config", "env", "version", "commit", "authorization_enabled", "skip_known_schema_check",
|
||||
// Annotations
|
||||
"annotations", "scope", "title", "entrypoint", "description", "organizations", "authors", "related_resources",
|
||||
"schemas", "custom", "name", "email", "schema", "definition", "document", "package", "rule", "subpackages",
|
||||
// Debug
|
||||
"text", "value", "bindings", "expressions",
|
||||
// Various
|
||||
"data", "input", "result", "keywords", "path", "v1", "error", "partial",
|
||||
// HTTP
|
||||
"code", "message", "status_code", "method", "url", "uri",
|
||||
// JWT
|
||||
"enc", "cty", "iss", "exp", "nbf", "aud", "secret", "cert",
|
||||
// Decisions
|
||||
"revision", "labels", "decision_id", "bundles", "query", "mapped_result", "nd_builtin_cache",
|
||||
"erased", "masked", "requested_by", "timestamp", "metrics", "req_id",
|
||||
)
|
||||
}
|
||||
|
||||
var stringToIntNumberTermMap = map[string]*Term{
|
||||
|
||||
+193
-52
@@ -36,7 +36,7 @@ const DefaultMaxParsingRecursionDepth = 100000
|
||||
// recursion exceeds the maximum allowed depth
|
||||
var ErrMaxParsingRecursionDepthExceeded = errors.New("max parsing recursion depth exceeded")
|
||||
|
||||
var RegoV1CompatibleRef = Ref{VarTerm("rego"), InternedStringTerm("v1")}
|
||||
var RegoV1CompatibleRef = Ref{VarTerm("rego"), InternedTerm("v1")}
|
||||
|
||||
// RegoVersion defines the Rego syntax requirements for a module.
|
||||
type RegoVersion int
|
||||
@@ -572,8 +572,19 @@ func (p *Parser) parsePackage() *Package {
|
||||
return nil
|
||||
}
|
||||
|
||||
p.scan()
|
||||
if p.s.tok != tokens.Ident {
|
||||
p.scanWS()
|
||||
|
||||
// Make sure we allow the first term of refs to be the 'package' keyword.
|
||||
if p.s.tok == tokens.Dot || p.s.tok == tokens.LBrack {
|
||||
// This is a ref, not a package declaration.
|
||||
return nil
|
||||
}
|
||||
|
||||
if p.s.tok == tokens.Whitespace {
|
||||
p.scan()
|
||||
}
|
||||
|
||||
if !isIdentOrAllowedRefKeyword(p) {
|
||||
p.illegalToken()
|
||||
return nil
|
||||
}
|
||||
@@ -630,11 +641,23 @@ func (p *Parser) parseImport() *Import {
|
||||
return nil
|
||||
}
|
||||
|
||||
p.scan()
|
||||
if p.s.tok != tokens.Ident {
|
||||
p.error(p.s.Loc(), "expected ident")
|
||||
p.scanWS()
|
||||
|
||||
// Make sure we allow the first term of refs to be the 'import' keyword.
|
||||
if p.s.tok == tokens.Dot || p.s.tok == tokens.LBrack {
|
||||
// This is a ref, not an import declaration.
|
||||
return nil
|
||||
}
|
||||
|
||||
if p.s.tok == tokens.Whitespace {
|
||||
p.scan()
|
||||
}
|
||||
|
||||
if !isIdentOrAllowedRefKeyword(p) {
|
||||
p.illegalToken()
|
||||
return nil
|
||||
}
|
||||
|
||||
q, prev := p.presentParser()
|
||||
term := q.parseTerm()
|
||||
if term != nil {
|
||||
@@ -693,17 +716,81 @@ func (p *Parser) parseImport() *Import {
|
||||
return nil
|
||||
}
|
||||
|
||||
if imp.Alias != "" {
|
||||
// Unreachable: parsing the alias var should already have generated an error.
|
||||
name := imp.Alias.String()
|
||||
if IsKeywordInRegoVersion(name, p.po.EffectiveRegoVersion()) {
|
||||
p.errorf(imp.Location, "unexpected import alias, must not be a keyword, got: %s", name)
|
||||
}
|
||||
return &imp
|
||||
}
|
||||
|
||||
r := imp.Path.Value.(Ref)
|
||||
|
||||
// Don't allow keywords in the tail path term unless it's a future import
|
||||
if len(r) == 1 {
|
||||
t := r[0]
|
||||
name := string(t.Value.(Var))
|
||||
if IsKeywordInRegoVersion(name, p.po.EffectiveRegoVersion()) {
|
||||
p.errorf(t.Location, "unexpected import path, must not end with a keyword, got: %s", name)
|
||||
p.hint("import a different path or use an alias")
|
||||
}
|
||||
} else if !FutureRootDocument.Equal(r[0]) {
|
||||
t := r[len(r)-1]
|
||||
name := string(t.Value.(String))
|
||||
if IsKeywordInRegoVersion(name, p.po.EffectiveRegoVersion()) {
|
||||
p.errorf(t.Location, "unexpected import path, must not end with a keyword, got: %s", name)
|
||||
p.hint("import a different path or use an alias")
|
||||
}
|
||||
}
|
||||
|
||||
return &imp
|
||||
}
|
||||
|
||||
// isIdentOrAllowedRefKeyword checks if the current token is an Ident or a keyword in the active rego-version.
|
||||
// If a keyword, sets p.s.token to token.Ident
|
||||
func isIdentOrAllowedRefKeyword(p *Parser) bool {
|
||||
if p.s.tok == tokens.Ident {
|
||||
return true
|
||||
}
|
||||
|
||||
if p.isAllowedRefKeyword(p.s.tok) {
|
||||
p.s.tok = tokens.Ident
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func scanAheadRef(p *Parser) bool {
|
||||
if p.isAllowedRefKeyword(p.s.tok) {
|
||||
// scan ahead to check if we're parsing a ref
|
||||
s := p.save()
|
||||
p.scanWS()
|
||||
tok := p.s.tok
|
||||
p.restore(s)
|
||||
|
||||
if tok == tokens.Dot || tok == tokens.LBrack {
|
||||
p.s.tok = tokens.Ident
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (p *Parser) parseRules() []*Rule {
|
||||
|
||||
var rule Rule
|
||||
rule.SetLoc(p.s.Loc())
|
||||
|
||||
// This allows keywords in the first var term of the ref
|
||||
_ = scanAheadRef(p)
|
||||
|
||||
if p.s.tok == tokens.Default {
|
||||
p.scan()
|
||||
rule.Default = true
|
||||
_ = scanAheadRef(p)
|
||||
}
|
||||
|
||||
if p.s.tok != tokens.Ident {
|
||||
@@ -817,17 +904,20 @@ func (p *Parser) parseRules() []*Rule {
|
||||
}
|
||||
|
||||
if p.s.tok == tokens.Else {
|
||||
if r := rule.Head.Ref(); len(r) > 1 && !r.IsGround() {
|
||||
p.error(p.s.Loc(), "else keyword cannot be used on rules with variables in head")
|
||||
return nil
|
||||
}
|
||||
if rule.Head.Key != nil {
|
||||
p.error(p.s.Loc(), "else keyword cannot be used on multi-value rules")
|
||||
return nil
|
||||
}
|
||||
// This might just be a refhead rule with a leading 'else' term.
|
||||
if !scanAheadRef(p) {
|
||||
if r := rule.Head.Ref(); len(r) > 1 && !r.IsGround() {
|
||||
p.error(p.s.Loc(), "else keyword cannot be used on rules with variables in head")
|
||||
return nil
|
||||
}
|
||||
if rule.Head.Key != nil {
|
||||
p.error(p.s.Loc(), "else keyword cannot be used on multi-value rules")
|
||||
return nil
|
||||
}
|
||||
|
||||
if rule.Else = p.parseElse(rule.Head); rule.Else == nil {
|
||||
return nil
|
||||
if rule.Else = p.parseElse(rule.Head); rule.Else == nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1102,10 +1192,31 @@ func (p *Parser) parseLiteral() (expr *Expr) {
|
||||
}
|
||||
}()
|
||||
|
||||
// Check that we're not parsing a ref
|
||||
if p.isAllowedRefKeyword(p.s.tok) {
|
||||
// Scan ahead
|
||||
s := p.save()
|
||||
p.scanWS()
|
||||
tok := p.s.tok
|
||||
p.restore(s)
|
||||
|
||||
if tok == tokens.Dot || tok == tokens.LBrack {
|
||||
p.s.tok = tokens.Ident
|
||||
return p.parseLiteralExpr(false)
|
||||
}
|
||||
}
|
||||
|
||||
var negated bool
|
||||
if p.s.tok == tokens.Not {
|
||||
p.scan()
|
||||
negated = true
|
||||
s := p.save()
|
||||
p.scanWS()
|
||||
tok := p.s.tok
|
||||
p.restore(s)
|
||||
|
||||
if tok != tokens.Dot && tok != tokens.LBrack {
|
||||
p.scan()
|
||||
negated = true
|
||||
}
|
||||
}
|
||||
|
||||
switch p.s.tok {
|
||||
@@ -1122,35 +1233,51 @@ func (p *Parser) parseLiteral() (expr *Expr) {
|
||||
}
|
||||
return p.parseEvery()
|
||||
default:
|
||||
s := p.save()
|
||||
expr := p.parseExpr()
|
||||
if expr != nil {
|
||||
expr.Negated = negated
|
||||
if p.s.tok == tokens.With {
|
||||
if expr.With = p.parseWith(); expr.With == nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// If we find a plain `every` identifier, attempt to parse an every expression,
|
||||
// add hint if it succeeds.
|
||||
if term, ok := expr.Terms.(*Term); ok && Var("every").Equal(term.Value) {
|
||||
var hint bool
|
||||
t := p.save()
|
||||
p.restore(s)
|
||||
if expr := p.futureParser().parseEvery(); expr != nil {
|
||||
_, hint = expr.Terms.(*Every)
|
||||
}
|
||||
p.restore(t)
|
||||
if hint {
|
||||
p.hint("`import future.keywords.every` for `every x in xs { ... }` expressions")
|
||||
}
|
||||
}
|
||||
return expr
|
||||
}
|
||||
return nil
|
||||
return p.parseLiteralExpr(negated)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Parser) isAllowedRefKeyword(t tokens.Token) bool {
|
||||
return p.isAllowedRefKeywordStr(t.String())
|
||||
}
|
||||
|
||||
func (p *Parser) isAllowedRefKeywordStr(s string) bool {
|
||||
if p.po.Capabilities.ContainsFeature(FeatureKeywordsInRefs) {
|
||||
return IsKeywordInRegoVersion(s, p.po.EffectiveRegoVersion()) || p.s.s.IsKeyword(s)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (p *Parser) parseLiteralExpr(negated bool) *Expr {
|
||||
s := p.save()
|
||||
expr := p.parseExpr()
|
||||
if expr != nil {
|
||||
expr.Negated = negated
|
||||
if p.s.tok == tokens.With {
|
||||
if expr.With = p.parseWith(); expr.With == nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// If we find a plain `every` identifier, attempt to parse an every expression,
|
||||
// add hint if it succeeds.
|
||||
if term, ok := expr.Terms.(*Term); ok && Var("every").Equal(term.Value) {
|
||||
var hint bool
|
||||
t := p.save()
|
||||
p.restore(s)
|
||||
if expr := p.futureParser().parseEvery(); expr != nil {
|
||||
_, hint = expr.Terms.(*Every)
|
||||
}
|
||||
p.restore(t)
|
||||
if hint {
|
||||
p.hint("`import future.keywords.every` for `every x in xs { ... }` expressions")
|
||||
}
|
||||
}
|
||||
return expr
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseWith() []*With {
|
||||
|
||||
withs := []*With{}
|
||||
@@ -1431,6 +1558,9 @@ func (p *Parser) parseTermIn(lhs *Term, keyVal bool, offset int) *Term {
|
||||
}
|
||||
p.restore(s)
|
||||
}
|
||||
|
||||
_ = scanAheadRef(p)
|
||||
|
||||
if op := p.parseTermOpName(memberRef, tokens.In); op != nil {
|
||||
if rhs := p.parseTermRelation(nil, p.s.loc.Offset); rhs != nil {
|
||||
call := p.setLoc(CallTerm(op, lhs, rhs), lhs.Location, offset, p.s.lastEnd)
|
||||
@@ -1647,6 +1777,8 @@ func (p *Parser) parseTermFinish(head *Term, skipws bool) *Term {
|
||||
func (p *Parser) parseNumber() *Term {
|
||||
var prefix string
|
||||
loc := p.s.Loc()
|
||||
|
||||
// Handle negative sign
|
||||
if p.s.tok == tokens.Sub {
|
||||
prefix = "-"
|
||||
p.scan()
|
||||
@@ -1658,6 +1790,8 @@ func (p *Parser) parseNumber() *Term {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Handle decimal point
|
||||
if p.s.tok == tokens.Dot {
|
||||
prefix += "."
|
||||
p.scan()
|
||||
@@ -1667,12 +1801,19 @@ func (p *Parser) parseNumber() *Term {
|
||||
}
|
||||
}
|
||||
|
||||
// Check for multiple leading 0's, parsed by math/big.Float.Parse as decimal 0:
|
||||
// https://golang.org/pkg/math/big/#Float.Parse
|
||||
if ((len(prefix) != 0 && prefix[0] == '-') || len(prefix) == 0) &&
|
||||
len(p.s.lit) > 1 && p.s.lit[0] == '0' && p.s.lit[1] == '0' {
|
||||
p.illegal("expected number")
|
||||
return nil
|
||||
// Validate leading zeros: reject numbers like "01", "007", etc.
|
||||
// Skip validation if prefix ends with '.' (like ".123")
|
||||
hasDecimalPrefix := len(prefix) > 0 && prefix[len(prefix)-1] == '.'
|
||||
|
||||
if !hasDecimalPrefix && len(p.s.lit) > 1 && p.s.lit[0] == '0' {
|
||||
// These are the only valid cases starting with '0':
|
||||
isDecimal := p.s.lit[1] == '.' // "0.123"
|
||||
isScientific := len(p.s.lit) > 2 && (p.s.lit[1] == 'e' || p.s.lit[1] == 'E') // "0e5", "0E-3"
|
||||
|
||||
if !isDecimal && !isScientific {
|
||||
p.illegal("expected number without leading zero")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the number is valid
|
||||
@@ -1789,7 +1930,7 @@ func (p *Parser) parseRef(head *Term, offset int) (term *Term) {
|
||||
switch p.s.tok {
|
||||
case tokens.Dot:
|
||||
p.scanWS()
|
||||
if p.s.tok != tokens.Ident {
|
||||
if p.s.tok != tokens.Ident && !p.isAllowedRefKeyword(p.s.tok) {
|
||||
p.illegal("expected %v", tokens.Ident)
|
||||
return nil
|
||||
}
|
||||
@@ -2778,7 +2919,7 @@ func IsFutureKeywordForRegoVersion(s string, v RegoVersion) bool {
|
||||
func (p *Parser) futureImport(imp *Import, allowedFutureKeywords map[string]tokens.Token) {
|
||||
path := imp.Path.Value.(Ref)
|
||||
|
||||
if len(path) == 1 || !path[1].Equal(InternedStringTerm("keywords")) {
|
||||
if len(path) == 1 || !path[1].Equal(InternedTerm("keywords")) {
|
||||
p.errorf(imp.Path.Location, "invalid import, must be `future.keywords`")
|
||||
return
|
||||
}
|
||||
|
||||
+1
-1
@@ -191,7 +191,7 @@ func checkRegoV1Rule(rule *Rule, opts RegoCheckOptions) Errors {
|
||||
|
||||
var errs Errors
|
||||
|
||||
if opts.NoKeywordsAsRuleNames && IsKeywordInRegoVersion(rule.Head.Name.String(), RegoV1) {
|
||||
if opts.NoKeywordsAsRuleNames && len(rule.Head.Reference) < 2 && IsKeywordInRegoVersion(rule.Head.Name.String(), RegoV1) {
|
||||
errs = append(errs, NewError(ParseErr, rule.Location, "%s keyword cannot be used for rule name", rule.Head.Name.String()))
|
||||
}
|
||||
if opts.RequireRuleBodyOrValue && rule.generatedBody && rule.Head.generatedValue {
|
||||
|
||||
+7
-7
@@ -61,7 +61,7 @@ func InterfaceToValue(x any) (Value, error) {
|
||||
case nil:
|
||||
return NullValue, nil
|
||||
case bool:
|
||||
return InternedBooleanTerm(x).Value, nil
|
||||
return InternedTerm(x).Value, nil
|
||||
case json.Number:
|
||||
if interned := InternedIntNumberTermFromString(string(x)); interned != nil {
|
||||
return interned.Value, nil
|
||||
@@ -587,9 +587,9 @@ type Boolean bool
|
||||
// BooleanTerm creates a new Term with a Boolean value.
|
||||
func BooleanTerm(b bool) *Term {
|
||||
if b {
|
||||
return &Term{Value: InternedBooleanTerm(true).Value}
|
||||
return &Term{Value: InternedTerm(true).Value}
|
||||
}
|
||||
return &Term{Value: InternedBooleanTerm(false).Value}
|
||||
return &Term{Value: InternedTerm(false).Value}
|
||||
}
|
||||
|
||||
// Equal returns true if the other Value is a Boolean and is equal.
|
||||
@@ -624,7 +624,7 @@ func (bol Boolean) Compare(other Value) int {
|
||||
// Find returns the current value or a not found error.
|
||||
func (bol Boolean) Find(path Ref) (Value, error) {
|
||||
if len(path) == 0 {
|
||||
return InternedBooleanTerm(bool(bol)).Value, nil
|
||||
return InternedTerm(bool(bol)).Value, nil
|
||||
}
|
||||
return nil, errFindNotFound
|
||||
}
|
||||
@@ -676,8 +676,8 @@ func (num Number) Equal(other Value) bool {
|
||||
case Number:
|
||||
if n1, ok1 := num.Int64(); ok1 {
|
||||
n2, ok2 := other.Int64()
|
||||
if ok1 && ok2 && n1 == n2 {
|
||||
return true
|
||||
if ok1 && ok2 {
|
||||
return n1 == n2
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1237,7 +1237,7 @@ func (ref Ref) toArray() *Array {
|
||||
if _, ok := term.Value.(String); ok {
|
||||
terms = append(terms, term)
|
||||
} else {
|
||||
terms = append(terms, InternedStringTerm(term.Value.String()))
|
||||
terms = append(terms, InternedTerm(term.Value.String()))
|
||||
}
|
||||
}
|
||||
return NewArray(terms...)
|
||||
|
||||
+7
@@ -1402,6 +1402,13 @@
|
||||
}
|
||||
},
|
||||
"features": {
|
||||
"keywords_in_refs": {
|
||||
"Major": 1,
|
||||
"Minor": 6,
|
||||
"Patch": 0,
|
||||
"PreRelease": "",
|
||||
"Metadata": ""
|
||||
},
|
||||
"rego_v1": {
|
||||
"Major": 1,
|
||||
"Minor": 0,
|
||||
|
||||
+36
-12
@@ -1092,31 +1092,55 @@ func (b *Bundle) FormatModules(useModulePath bool) error {
|
||||
|
||||
// FormatModulesForRegoVersion formats Rego modules to comply with a given Rego version
|
||||
func (b *Bundle) FormatModulesForRegoVersion(version ast.RegoVersion, preserveModuleRegoVersion bool, useModulePath bool) error {
|
||||
return b.FormatModulesWithOptions(BundleFormatOptions{
|
||||
RegoVersion: version,
|
||||
PreserveModuleRegoVersion: preserveModuleRegoVersion,
|
||||
UseModulePath: useModulePath,
|
||||
})
|
||||
}
|
||||
|
||||
type BundleFormatOptions struct {
|
||||
RegoVersion ast.RegoVersion
|
||||
Capabilities *ast.Capabilities
|
||||
PreserveModuleRegoVersion bool
|
||||
UseModulePath bool
|
||||
}
|
||||
|
||||
// FormatModulesWithOptions formats Rego modules with the given options.
|
||||
func (b *Bundle) FormatModulesWithOptions(opts BundleFormatOptions) error {
|
||||
var err error
|
||||
|
||||
for i, module := range b.Modules {
|
||||
opts := format.Opts{}
|
||||
if preserveModuleRegoVersion {
|
||||
opts.RegoVersion = module.Parsed.RegoVersion()
|
||||
opts.ParserOptions = &ast.ParserOptions{
|
||||
RegoVersion: opts.RegoVersion,
|
||||
fmtOpts := format.Opts{
|
||||
RegoVersion: opts.RegoVersion,
|
||||
Capabilities: opts.Capabilities,
|
||||
}
|
||||
|
||||
if module.Parsed != nil {
|
||||
fmtOpts.ParserOptions = &ast.ParserOptions{
|
||||
RegoVersion: module.Parsed.RegoVersion(),
|
||||
}
|
||||
} else {
|
||||
opts.RegoVersion = version
|
||||
if opts.PreserveModuleRegoVersion {
|
||||
fmtOpts.RegoVersion = module.Parsed.RegoVersion()
|
||||
}
|
||||
}
|
||||
|
||||
if fmtOpts.Capabilities == nil {
|
||||
fmtOpts.Capabilities = ast.CapabilitiesForThisVersion(ast.CapabilitiesRegoVersion(fmtOpts.RegoVersion))
|
||||
}
|
||||
|
||||
if module.Raw == nil {
|
||||
module.Raw, err = format.AstWithOpts(module.Parsed, opts)
|
||||
module.Raw, err = format.AstWithOpts(module.Parsed, fmtOpts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
path := module.URL
|
||||
if useModulePath {
|
||||
path = module.Path
|
||||
p := module.URL
|
||||
if opts.UseModulePath {
|
||||
p = module.Path
|
||||
}
|
||||
|
||||
module.Raw, err = format.SourceWithOpts(path, module.Raw, opts)
|
||||
module.Raw, err = format.SourceWithOpts(p, module.Raw, fmtOpts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
+48
-10
@@ -37,6 +37,8 @@ type Opts struct {
|
||||
// DropV0Imports instructs the formatter to drop all v0 imports from the module; i.e. 'rego.v1' and 'future.keywords' imports.
|
||||
// Imports are only removed if [Opts.RegoVersion] makes them redundant.
|
||||
DropV0Imports bool
|
||||
|
||||
Capabilities *ast.Capabilities
|
||||
}
|
||||
|
||||
func (o Opts) effectiveRegoVersion() ast.RegoVersion {
|
||||
@@ -146,6 +148,10 @@ type fmtOpts struct {
|
||||
regoV1 bool
|
||||
regoV1Imported bool
|
||||
futureKeywords []string
|
||||
|
||||
// If true, the formatter will retain keywords in refs, e.g. `p.not ` instead of `p["not"]`.
|
||||
// The format of the original ref is preserved, so `p["not"]` will still be formatted as `p["not"]`.
|
||||
allowKeywordsInRefs bool
|
||||
}
|
||||
|
||||
func (o fmtOpts) keywords() []string {
|
||||
@@ -179,6 +185,12 @@ func AstWithOpts(x any, opts Opts) ([]byte, error) {
|
||||
o.contains = true
|
||||
}
|
||||
|
||||
capabilities := opts.Capabilities
|
||||
if capabilities == nil {
|
||||
capabilities = ast.CapabilitiesForThisVersion(ast.CapabilitiesRegoVersion(opts.effectiveRegoVersion()))
|
||||
}
|
||||
o.allowKeywordsInRefs = capabilities.ContainsFeature(ast.FeatureKeywordsInRefs)
|
||||
|
||||
memberRef := ast.Member.Ref()
|
||||
memberWithKeyRef := ast.MemberWithKey.Ref()
|
||||
|
||||
@@ -533,7 +545,7 @@ func (w *writer) writeRules(rules []*ast.Rule, comments []*ast.Comment) ([]*ast.
|
||||
return comments, nil
|
||||
}
|
||||
|
||||
var expandedConst = ast.NewBody(ast.NewExpr(ast.InternedBooleanTerm(true)))
|
||||
var expandedConst = ast.NewBody(ast.NewExpr(ast.InternedTerm(true)))
|
||||
|
||||
func (w *writer) groupableOneLiner(rule *ast.Rule) bool {
|
||||
// Location required to determine if two rules are adjacent in the policy.
|
||||
@@ -790,7 +802,7 @@ func (w *writer) writeHead(head *ast.Head, isDefault bool, isExpandedConst bool,
|
||||
}
|
||||
|
||||
if head.Value != nil &&
|
||||
(head.Key != nil || !ast.InternedBooleanTerm(true).Equal(head.Value) || isExpandedConst || isDefault) {
|
||||
(head.Key != nil || !ast.InternedTerm(true).Equal(head.Value) || isExpandedConst || isDefault) {
|
||||
|
||||
// in rego v1, explicitly print value for ref-head constants that aren't partial set assignments, e.g.:
|
||||
// * a -> parser error, won't reach here
|
||||
@@ -801,7 +813,7 @@ func (w *writer) writeHead(head *ast.Head, isDefault bool, isExpandedConst bool,
|
||||
|
||||
if head.Location == head.Value.Location &&
|
||||
head.Name != "else" &&
|
||||
ast.InternedBooleanTerm(true).Equal(head.Value) &&
|
||||
ast.InternedTerm(true).Equal(head.Value) &&
|
||||
!isRegoV1RefConst {
|
||||
// If the value location is the same as the location of the head,
|
||||
// we know that the value is generated, i.e. f(1)
|
||||
@@ -1070,8 +1082,16 @@ func (w *writer) writeFunctionCall(expr *ast.Expr, comments []*ast.Comment) ([]*
|
||||
}
|
||||
|
||||
func (w *writer) writeFunctionCallPlain(terms []*ast.Term, comments []*ast.Comment) ([]*ast.Comment, error) {
|
||||
w.write(terms[0].String() + "(")
|
||||
if r, ok := terms[0].Value.(ast.Ref); ok {
|
||||
if c, err := w.writeRef(r, comments); err != nil {
|
||||
return c, err
|
||||
}
|
||||
} else {
|
||||
w.write(terms[0].String())
|
||||
}
|
||||
w.write("(")
|
||||
defer w.write(")")
|
||||
|
||||
args := make([]any, len(terms)-1)
|
||||
for i, t := range terms[1:] {
|
||||
args[i] = t
|
||||
@@ -1264,7 +1284,7 @@ func (w *writer) writeRef(x ast.Ref, comments []*ast.Comment) ([]*ast.Comment, e
|
||||
for _, t := range path {
|
||||
switch p := t.Value.(type) {
|
||||
case ast.String:
|
||||
w.writeRefStringPath(p)
|
||||
w.writeRefStringPath(p, t.Location)
|
||||
case ast.Var:
|
||||
w.writeBracketed(w.formatVar(p))
|
||||
default:
|
||||
@@ -1292,15 +1312,33 @@ func (w *writer) writeBracketed(str string) {
|
||||
|
||||
var varRegexp = regexp.MustCompile("^[[:alpha:]_][[:alpha:][:digit:]_]*$")
|
||||
|
||||
func (w *writer) writeRefStringPath(s ast.String) {
|
||||
func (w *writer) writeRefStringPath(s ast.String, l *ast.Location) {
|
||||
str := string(s)
|
||||
if varRegexp.MatchString(str) && !ast.IsInKeywords(str, w.fmtOpts.keywords()) {
|
||||
w.write("." + str)
|
||||
} else {
|
||||
if w.shouldBracketRefTerm(str, l) {
|
||||
w.writeBracketed(s.String())
|
||||
} else {
|
||||
w.write("." + str)
|
||||
}
|
||||
}
|
||||
|
||||
func (w *writer) shouldBracketRefTerm(s string, l *ast.Location) bool {
|
||||
if !varRegexp.MatchString(s) {
|
||||
return true
|
||||
}
|
||||
|
||||
if ast.IsInKeywords(s, w.fmtOpts.keywords()) {
|
||||
if !w.fmtOpts.allowKeywordsInRefs {
|
||||
return true
|
||||
}
|
||||
|
||||
if l != nil && l.Text[0] == 34 { // If the original term text starts with '"', we preserve the brackets and quotes
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (*writer) formatVar(v ast.Var) string {
|
||||
if v.IsWildcard() {
|
||||
return ast.Wildcard.String()
|
||||
@@ -2211,5 +2249,5 @@ func isRegoV1Compatible(imp *ast.Import) bool {
|
||||
path := imp.Path.Value.(ast.Ref)
|
||||
return len(path) == 2 &&
|
||||
ast.RegoRootDocument.Equal(path[0]) &&
|
||||
path[1].Equal(ast.InternedStringTerm("v1"))
|
||||
path[1].Equal(ast.InternedTerm("v1"))
|
||||
}
|
||||
|
||||
+1
-1
@@ -462,7 +462,7 @@ func getSchemaSetByPathKey(path string) ast.Ref {
|
||||
key := make(ast.Ref, 1+len(parts))
|
||||
key[0] = ast.SchemaRootDocument
|
||||
for i := range parts {
|
||||
key[i+1] = ast.StringTerm(parts[i])
|
||||
key[i+1] = ast.InternedTerm(parts[i])
|
||||
}
|
||||
|
||||
return key
|
||||
|
||||
+62
-10
@@ -66,9 +66,17 @@ type metrics struct {
|
||||
|
||||
// New returns a new Metrics object.
|
||||
func New() Metrics {
|
||||
m := &metrics{}
|
||||
m.Clear()
|
||||
return m
|
||||
return &metrics{
|
||||
timers: map[string]Timer{},
|
||||
histograms: map[string]Histogram{},
|
||||
counters: map[string]Counter{},
|
||||
}
|
||||
}
|
||||
|
||||
// NoOp returns a Metrics implementation that does nothing and costs nothing.
|
||||
// Used when metrics are expected, but not of interest.
|
||||
func NoOp() Metrics {
|
||||
return noOpMetricsInstance
|
||||
}
|
||||
|
||||
type metric struct {
|
||||
@@ -83,7 +91,6 @@ func (*metrics) Info() Info {
|
||||
}
|
||||
|
||||
func (m *metrics) String() string {
|
||||
|
||||
all := m.All()
|
||||
sorted := make([]metric, 0, len(all))
|
||||
|
||||
@@ -147,7 +154,7 @@ func (m *metrics) Counter(name string) Counter {
|
||||
func (m *metrics) All() map[string]any {
|
||||
m.mtx.Lock()
|
||||
defer m.mtx.Unlock()
|
||||
result := map[string]any{}
|
||||
result := make(map[string]any, len(m.timers)+len(m.histograms)+len(m.counters))
|
||||
for name, timer := range m.timers {
|
||||
result[m.formatKey(name, timer)] = timer.Value()
|
||||
}
|
||||
@@ -163,7 +170,7 @@ func (m *metrics) All() map[string]any {
|
||||
func (m *metrics) Timers() map[string]any {
|
||||
m.mtx.Lock()
|
||||
defer m.mtx.Unlock()
|
||||
ts := map[string]any{}
|
||||
ts := make(map[string]any, len(m.timers))
|
||||
for n, t := range m.timers {
|
||||
ts[m.formatKey(n, t)] = t.Value()
|
||||
}
|
||||
@@ -196,7 +203,10 @@ func (*metrics) formatKey(name string, metrics any) string {
|
||||
type Timer interface {
|
||||
Value() any
|
||||
Int64() int64
|
||||
// Start or resume a timer's time tracking.
|
||||
Start()
|
||||
// Stop a timer, and accumulate the delta (in nanoseconds) since it was last
|
||||
// started.
|
||||
Stop() int64
|
||||
}
|
||||
|
||||
@@ -208,15 +218,22 @@ type timer struct {
|
||||
|
||||
func (t *timer) Start() {
|
||||
t.mtx.Lock()
|
||||
defer t.mtx.Unlock()
|
||||
t.start = time.Now()
|
||||
t.mtx.Unlock()
|
||||
}
|
||||
|
||||
func (t *timer) Stop() int64 {
|
||||
t.mtx.Lock()
|
||||
defer t.mtx.Unlock()
|
||||
delta := time.Since(t.start).Nanoseconds()
|
||||
t.value += delta
|
||||
|
||||
var delta int64
|
||||
if !t.start.IsZero() {
|
||||
// Add the delta to the accumulated time value so far.
|
||||
delta = time.Since(t.start).Nanoseconds()
|
||||
t.value += delta
|
||||
t.start = time.Time{} // Reset the start time to zero.
|
||||
}
|
||||
|
||||
return delta
|
||||
}
|
||||
|
||||
@@ -254,7 +271,7 @@ func (h *histogram) Update(v int64) {
|
||||
}
|
||||
|
||||
func (h *histogram) Value() any {
|
||||
values := map[string]any{}
|
||||
values := make(map[string]any, 12)
|
||||
snap := h.hist.Snapshot()
|
||||
percentiles := snap.Percentiles([]float64{
|
||||
0.5,
|
||||
@@ -310,3 +327,38 @@ func Statistics(num ...int64) any {
|
||||
}
|
||||
return t.Value()
|
||||
}
|
||||
|
||||
type noOpMetrics struct{}
|
||||
type noOpTimer struct{}
|
||||
type noOpHistogram struct{}
|
||||
type noOpCounter struct{}
|
||||
|
||||
var (
|
||||
noOpMetricsInstance = &noOpMetrics{}
|
||||
noOpTimerInstance = &noOpTimer{}
|
||||
noOpHistogramInstance = &noOpHistogram{}
|
||||
noOpCounterInstance = &noOpCounter{}
|
||||
)
|
||||
|
||||
func (*noOpMetrics) Info() Info { return Info{Name: "<built-in no-op>"} }
|
||||
func (*noOpMetrics) Timer(name string) Timer { return noOpTimerInstance }
|
||||
func (*noOpMetrics) Histogram(name string) Histogram { return noOpHistogramInstance }
|
||||
func (*noOpMetrics) Counter(name string) Counter { return noOpCounterInstance }
|
||||
func (*noOpMetrics) All() map[string]any { return nil }
|
||||
func (*noOpMetrics) Clear() {}
|
||||
func (*noOpMetrics) MarshalJSON() ([]byte, error) {
|
||||
return []byte(`{"name": "<built-in no-op>"}`), nil
|
||||
}
|
||||
|
||||
func (*noOpTimer) Start() {}
|
||||
func (*noOpTimer) Stop() int64 { return 0 }
|
||||
func (*noOpTimer) Value() any { return 0 }
|
||||
func (*noOpTimer) Int64() int64 { return 0 }
|
||||
|
||||
func (*noOpHistogram) Update(v int64) {}
|
||||
func (*noOpHistogram) Value() any { return nil }
|
||||
|
||||
func (*noOpCounter) Incr() {}
|
||||
func (*noOpCounter) Add(_ uint64) {}
|
||||
func (*noOpCounter) Value() any { return 0 }
|
||||
func (*noOpCounter) Int64() int64 { return 0 }
|
||||
|
||||
+4
-5
@@ -11,6 +11,7 @@ import (
|
||||
"fmt"
|
||||
"maps"
|
||||
mr "math/rand"
|
||||
"net/http"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -18,8 +19,6 @@ import (
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"go.opentelemetry.io/otel/sdk/trace"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
|
||||
bundleUtils "github.com/open-policy-agent/opa/internal/bundle"
|
||||
cfg "github.com/open-policy-agent/opa/internal/config"
|
||||
initload "github.com/open-policy-agent/opa/internal/runtime/init"
|
||||
@@ -207,7 +206,7 @@ type Manager struct {
|
||||
serverInitializedOnce sync.Once
|
||||
printHook print.Hook
|
||||
enablePrintStatements bool
|
||||
router *mux.Router
|
||||
router *http.ServeMux
|
||||
prometheusRegister prometheus.Registerer
|
||||
tracerProvider *trace.TracerProvider
|
||||
distributedTacingOpts tracing.Options
|
||||
@@ -370,7 +369,7 @@ func PrintHook(h print.Hook) func(*Manager) {
|
||||
}
|
||||
}
|
||||
|
||||
func WithRouter(r *mux.Router) func(*Manager) {
|
||||
func WithRouter(r *http.ServeMux) func(*Manager) {
|
||||
return func(m *Manager) {
|
||||
m.router = r
|
||||
}
|
||||
@@ -655,7 +654,7 @@ func (m *Manager) setCompiler(compiler *ast.Compiler) {
|
||||
}
|
||||
|
||||
// GetRouter returns the managers router if set
|
||||
func (m *Manager) GetRouter() *mux.Router {
|
||||
func (m *Manager) GetRouter() *http.ServeMux {
|
||||
m.mtx.Lock()
|
||||
defer m.mtx.Unlock()
|
||||
return m.router
|
||||
|
||||
+3
-3
@@ -637,7 +637,7 @@ type Rego struct {
|
||||
generateJSON func(*ast.Term, *EvalContext) (any, error)
|
||||
printHook print.Hook
|
||||
enablePrintStatements bool
|
||||
distributedTacingOpts tracing.Options
|
||||
distributedTracingOpts tracing.Options
|
||||
strict bool
|
||||
pluginMgr *plugins.Manager
|
||||
plugins []TargetPlugin
|
||||
@@ -1251,7 +1251,7 @@ func PrintHook(h print.Hook) func(r *Rego) {
|
||||
// DistributedTracingOpts sets the options to be used by distributed tracing.
|
||||
func DistributedTracingOpts(tr tracing.Options) func(r *Rego) {
|
||||
return func(r *Rego) {
|
||||
r.distributedTacingOpts = tr
|
||||
r.distributedTracingOpts = tr
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2185,7 +2185,7 @@ func (r *Rego) eval(ctx context.Context, ectx *EvalContext) (ResultSet, error) {
|
||||
WithBuiltinErrorList(r.builtinErrorList).
|
||||
WithSeed(ectx.seed).
|
||||
WithPrintHook(ectx.printHook).
|
||||
WithDistributedTracingOpts(r.distributedTacingOpts).
|
||||
WithDistributedTracingOpts(r.distributedTracingOpts).
|
||||
WithVirtualCache(ectx.virtualCache).
|
||||
WithBaseCache(ectx.baseCache)
|
||||
|
||||
|
||||
+1
-1
@@ -168,7 +168,7 @@ func getResult(evalResult *opa.Result) (ast.Value, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := obj.Get(ast.InternedStringTerm("result"))
|
||||
result := obj.Get(ast.InternedTerm("result"))
|
||||
|
||||
return result.Value, nil
|
||||
}
|
||||
|
||||
+3
-3
@@ -154,7 +154,7 @@ func newUpdateArrayAST(data *ast.Array, op storage.PatchOp, path storage.Path, i
|
||||
}
|
||||
|
||||
func newUpdateObjectAST(data ast.Object, op storage.PatchOp, path storage.Path, idx int, value ast.Value) (*updateAST, error) {
|
||||
key := ast.InternedStringTerm(path[idx])
|
||||
key := ast.InternedTerm(path[idx])
|
||||
val := data.Get(key)
|
||||
|
||||
if idx == len(path)-1 {
|
||||
@@ -200,7 +200,7 @@ func setInAst(data ast.Value, path storage.Path, value ast.Value) (ast.Value, er
|
||||
}
|
||||
|
||||
func setInAstObject(obj ast.Object, path storage.Path, value ast.Value) (ast.Value, error) {
|
||||
key := ast.InternedStringTerm(path[0])
|
||||
key := ast.InternedTerm(path[0])
|
||||
|
||||
if len(path) == 1 {
|
||||
obj.Insert(key, ast.NewTerm(value))
|
||||
@@ -256,7 +256,7 @@ func removeInAst(value ast.Value, path storage.Path) (ast.Value, error) {
|
||||
}
|
||||
|
||||
func removeInAstObject(obj ast.Object, path storage.Path) (ast.Value, error) {
|
||||
key := ast.InternedStringTerm(path[0])
|
||||
key := ast.InternedTerm(path[0])
|
||||
|
||||
if len(path) == 1 {
|
||||
var items [][2]*ast.Term
|
||||
|
||||
+21
-21
@@ -14,13 +14,13 @@ import (
|
||||
func builtinCount(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
switch a := operands[0].Value.(type) {
|
||||
case *ast.Array:
|
||||
return iter(ast.InternedIntNumberTerm(a.Len()))
|
||||
return iter(ast.InternedTerm(a.Len()))
|
||||
case ast.Object:
|
||||
return iter(ast.InternedIntNumberTerm(a.Len()))
|
||||
return iter(ast.InternedTerm(a.Len()))
|
||||
case ast.Set:
|
||||
return iter(ast.InternedIntNumberTerm(a.Len()))
|
||||
return iter(ast.InternedTerm(a.Len()))
|
||||
case ast.String:
|
||||
return iter(ast.InternedIntNumberTerm(len([]rune(a))))
|
||||
return iter(ast.InternedTerm(len([]rune(a))))
|
||||
}
|
||||
return builtins.NewOperandTypeErr(1, operands[0].Value, "array", "object", "set", "string")
|
||||
}
|
||||
@@ -40,7 +40,7 @@ func builtinSum(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) err
|
||||
return true
|
||||
})
|
||||
if !nonInts {
|
||||
return iter(ast.InternedIntNumberTerm(is))
|
||||
return iter(ast.InternedTerm(is))
|
||||
}
|
||||
|
||||
// Non-integer values found, so we need to sum as floats.
|
||||
@@ -70,7 +70,7 @@ func builtinSum(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) err
|
||||
return true
|
||||
})
|
||||
if !nonInts {
|
||||
return iter(ast.InternedIntNumberTerm(is))
|
||||
return iter(ast.InternedTerm(is))
|
||||
}
|
||||
|
||||
sum := big.NewFloat(0)
|
||||
@@ -209,7 +209,7 @@ func builtinAll(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) err
|
||||
switch val := operands[0].Value.(type) {
|
||||
case ast.Set:
|
||||
res := true
|
||||
match := ast.InternedBooleanTerm(true)
|
||||
match := ast.InternedTerm(true)
|
||||
val.Until(func(term *ast.Term) bool {
|
||||
if !match.Equal(term) {
|
||||
res = false
|
||||
@@ -217,10 +217,10 @@ func builtinAll(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) err
|
||||
}
|
||||
return false
|
||||
})
|
||||
return iter(ast.InternedBooleanTerm(res))
|
||||
return iter(ast.InternedTerm(res))
|
||||
case *ast.Array:
|
||||
res := true
|
||||
match := ast.InternedBooleanTerm(true)
|
||||
match := ast.InternedTerm(true)
|
||||
val.Until(func(term *ast.Term) bool {
|
||||
if !match.Equal(term) {
|
||||
res = false
|
||||
@@ -228,7 +228,7 @@ func builtinAll(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) err
|
||||
}
|
||||
return false
|
||||
})
|
||||
return iter(ast.InternedBooleanTerm(res))
|
||||
return iter(ast.InternedTerm(res))
|
||||
default:
|
||||
return builtins.NewOperandTypeErr(1, operands[0].Value, "array", "set")
|
||||
}
|
||||
@@ -237,11 +237,11 @@ func builtinAll(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) err
|
||||
func builtinAny(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
switch val := operands[0].Value.(type) {
|
||||
case ast.Set:
|
||||
res := val.Len() > 0 && val.Contains(ast.InternedBooleanTerm(true))
|
||||
return iter(ast.InternedBooleanTerm(res))
|
||||
res := val.Len() > 0 && val.Contains(ast.InternedTerm(true))
|
||||
return iter(ast.InternedTerm(res))
|
||||
case *ast.Array:
|
||||
res := false
|
||||
match := ast.InternedBooleanTerm(true)
|
||||
match := ast.InternedTerm(true)
|
||||
val.Until(func(term *ast.Term) bool {
|
||||
if match.Equal(term) {
|
||||
res = true
|
||||
@@ -249,7 +249,7 @@ func builtinAny(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) err
|
||||
}
|
||||
return false
|
||||
})
|
||||
return iter(ast.InternedBooleanTerm(res))
|
||||
return iter(ast.InternedTerm(res))
|
||||
default:
|
||||
return builtins.NewOperandTypeErr(1, operands[0].Value, "array", "set")
|
||||
}
|
||||
@@ -259,20 +259,20 @@ func builtinMember(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term)
|
||||
containee := operands[0]
|
||||
switch c := operands[1].Value.(type) {
|
||||
case ast.Set:
|
||||
return iter(ast.InternedBooleanTerm(c.Contains(containee)))
|
||||
return iter(ast.InternedTerm(c.Contains(containee)))
|
||||
case *ast.Array:
|
||||
for i := range c.Len() {
|
||||
if c.Elem(i).Value.Compare(containee.Value) == 0 {
|
||||
return iter(ast.InternedBooleanTerm(true))
|
||||
return iter(ast.InternedTerm(true))
|
||||
}
|
||||
}
|
||||
return iter(ast.InternedBooleanTerm(false))
|
||||
return iter(ast.InternedTerm(false))
|
||||
case ast.Object:
|
||||
return iter(ast.InternedBooleanTerm(c.Until(func(_, v *ast.Term) bool {
|
||||
return iter(ast.InternedTerm(c.Until(func(_, v *ast.Term) bool {
|
||||
return v.Value.Compare(containee.Value) == 0
|
||||
})))
|
||||
}
|
||||
return iter(ast.InternedBooleanTerm(false))
|
||||
return iter(ast.InternedTerm(false))
|
||||
}
|
||||
|
||||
func builtinMemberWithKey(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
@@ -283,9 +283,9 @@ func builtinMemberWithKey(_ BuiltinContext, operands []*ast.Term, iter func(*ast
|
||||
if act := c.Get(key); act != nil {
|
||||
ret = act.Value.Compare(val.Value) == 0
|
||||
}
|
||||
return iter(ast.InternedBooleanTerm(ret))
|
||||
return iter(ast.InternedTerm(ret))
|
||||
}
|
||||
return iter(ast.InternedBooleanTerm(false))
|
||||
return iter(ast.InternedTerm(false))
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
||||
+4
-4
@@ -67,7 +67,7 @@ func builtinPlus(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) er
|
||||
y, ok2 := n2.Int()
|
||||
|
||||
if ok1 && ok2 && inSmallIntRange(x) && inSmallIntRange(y) {
|
||||
return iter(ast.InternedIntNumberTerm(x + y))
|
||||
return iter(ast.InternedTerm(x + y))
|
||||
}
|
||||
|
||||
f := new(big.Float).Add(builtins.NumberToFloat(n1), builtins.NumberToFloat(n2))
|
||||
@@ -89,7 +89,7 @@ func builtinMultiply(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term
|
||||
y, ok2 := n2.Int()
|
||||
|
||||
if ok1 && ok2 && inSmallIntRange(x) && inSmallIntRange(y) {
|
||||
return iter(ast.InternedIntNumberTerm(x * y))
|
||||
return iter(ast.InternedTerm(x * y))
|
||||
}
|
||||
|
||||
f := new(big.Float).Mul(builtins.NumberToFloat(n1), builtins.NumberToFloat(n2))
|
||||
@@ -155,7 +155,7 @@ func builtinMinus(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) e
|
||||
y, oky := n2.Int()
|
||||
|
||||
if okx && oky && inSmallIntRange(x) && inSmallIntRange(y) {
|
||||
return iter(ast.InternedIntNumberTerm(x - y))
|
||||
return iter(ast.InternedTerm(x - y))
|
||||
}
|
||||
|
||||
f := new(big.Float).Sub(builtins.NumberToFloat(n1), builtins.NumberToFloat(n2))
|
||||
@@ -199,7 +199,7 @@ func builtinRem(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) err
|
||||
return errors.New("modulo by zero")
|
||||
}
|
||||
|
||||
return iter(ast.InternedIntNumberTerm(x % y))
|
||||
return iter(ast.InternedTerm(x % y))
|
||||
}
|
||||
|
||||
op1, err1 := builtins.NumberToInt(n1)
|
||||
|
||||
+1
-1
@@ -39,7 +39,7 @@ type NDBCache map[string]ast.Object
|
||||
func (c NDBCache) AsValue() ast.Value {
|
||||
out := ast.NewObject()
|
||||
for bname, obj := range c {
|
||||
out.Insert(ast.InternedStringTerm(bname), ast.NewTerm(obj))
|
||||
out.Insert(ast.InternedTerm(bname), ast.NewTerm(obj))
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
+3
-3
@@ -15,12 +15,12 @@ import (
|
||||
func builtinToNumber(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
switch a := operands[0].Value.(type) {
|
||||
case ast.Null:
|
||||
return iter(ast.InternedIntNumberTerm(0))
|
||||
return iter(ast.InternedTerm(0))
|
||||
case ast.Boolean:
|
||||
if a {
|
||||
return iter(ast.InternedIntNumberTerm(1))
|
||||
return iter(ast.InternedTerm(1))
|
||||
}
|
||||
return iter(ast.InternedIntNumberTerm(0))
|
||||
return iter(ast.InternedTerm(0))
|
||||
case ast.Number:
|
||||
return iter(operands[0])
|
||||
case ast.String:
|
||||
|
||||
+7
-7
@@ -76,7 +76,7 @@ func builtinNetCIDRIntersects(_ BuiltinContext, operands []*ast.Term, iter func(
|
||||
// If either net contains the others starting IP they are overlapping
|
||||
cidrsOverlap := cidrnetA.Contains(cidrnetB.IP) || cidrnetB.Contains(cidrnetA.IP)
|
||||
|
||||
return iter(ast.InternedBooleanTerm(cidrsOverlap))
|
||||
return iter(ast.InternedTerm(cidrsOverlap))
|
||||
}
|
||||
|
||||
func builtinNetCIDRContains(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
@@ -93,7 +93,7 @@ func builtinNetCIDRContains(_ BuiltinContext, operands []*ast.Term, iter func(*a
|
||||
|
||||
ip := net.ParseIP(string(bStr))
|
||||
if ip != nil {
|
||||
return iter(ast.InternedBooleanTerm(cidrnetA.Contains(ip)))
|
||||
return iter(ast.InternedTerm(cidrnetA.Contains(ip)))
|
||||
}
|
||||
|
||||
// It wasn't an IP, try and parse it as a CIDR
|
||||
@@ -114,7 +114,7 @@ func builtinNetCIDRContains(_ BuiltinContext, operands []*ast.Term, iter func(*a
|
||||
cidrContained = cidrnetA.Contains(lastIP)
|
||||
}
|
||||
|
||||
return iter(ast.InternedBooleanTerm(cidrContained))
|
||||
return iter(ast.InternedTerm(cidrContained))
|
||||
}
|
||||
|
||||
var errNetCIDRContainsMatchElementType = errors.New("element must be string or non-empty array")
|
||||
@@ -143,7 +143,7 @@ func evalNetCIDRContainsMatchesOperand(operand int, a *ast.Term, iter func(cidr,
|
||||
if err != nil {
|
||||
return fmt.Errorf("operand %v: %v", operand, err)
|
||||
}
|
||||
if err := iter(cidr, ast.InternedIntNumberTerm(i)); err != nil {
|
||||
if err := iter(cidr, ast.InternedTerm(i)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -220,13 +220,13 @@ func builtinNetCIDRExpand(bctx BuiltinContext, operands []*ast.Term, iter func(*
|
||||
func builtinNetCIDRIsValid(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
cidr, err := builtins.StringOperand(operands[0].Value, 1)
|
||||
if err != nil {
|
||||
return iter(ast.InternedBooleanTerm(false))
|
||||
return iter(ast.InternedTerm(false))
|
||||
}
|
||||
|
||||
if _, _, err := net.ParseCIDR(string(cidr)); err != nil {
|
||||
return iter(ast.InternedBooleanTerm(false))
|
||||
return iter(ast.InternedTerm(false))
|
||||
}
|
||||
return iter(ast.InternedBooleanTerm(true))
|
||||
return iter(ast.InternedTerm(true))
|
||||
}
|
||||
|
||||
type cidrBlockRange struct {
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ func compareEq(a, b ast.Value) bool {
|
||||
|
||||
func builtinCompare(cmp compareFunc) BuiltinFunc {
|
||||
return func(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
return iter(ast.InternedBooleanTerm(cmp(operands[0].Value, operands[1].Value)))
|
||||
return iter(ast.InternedTerm(cmp(operands[0].Value, operands[1].Value)))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+7
-7
@@ -99,12 +99,12 @@ func builtinCryptoX509ParseAndVerifyCertificates(_ BuiltinContext, operands []*a
|
||||
|
||||
certs, err := getX509CertsFromString(string(input))
|
||||
if err != nil {
|
||||
return iter(ast.ArrayTerm(ast.InternedBooleanTerm(false), ast.InternedEmptyArray))
|
||||
return iter(ast.ArrayTerm(ast.InternedTerm(false), ast.InternedEmptyArray))
|
||||
}
|
||||
|
||||
verified, err := verifyX509CertificateChain(certs, x509.VerifyOptions{})
|
||||
if err != nil {
|
||||
return iter(ast.ArrayTerm(ast.InternedBooleanTerm(false), ast.InternedEmptyArray))
|
||||
return iter(ast.ArrayTerm(ast.InternedTerm(false), ast.InternedEmptyArray))
|
||||
}
|
||||
|
||||
value, err := ast.InterfaceToValue(extendCertificates(verified))
|
||||
@@ -112,7 +112,7 @@ func builtinCryptoX509ParseAndVerifyCertificates(_ BuiltinContext, operands []*a
|
||||
return err
|
||||
}
|
||||
|
||||
valid := ast.ArrayTerm(ast.InternedBooleanTerm(true), ast.NewTerm(value))
|
||||
valid := ast.ArrayTerm(ast.InternedTerm(true), ast.NewTerm(value))
|
||||
|
||||
return iter(valid)
|
||||
}
|
||||
@@ -148,7 +148,7 @@ func builtinCryptoX509ParseAndVerifyCertificatesWithOptions(_ BuiltinContext, op
|
||||
|
||||
certs, err := getX509CertsFromString(string(input))
|
||||
if err != nil {
|
||||
return iter(ast.ArrayTerm(ast.InternedBooleanTerm(false), ast.InternedEmptyArray))
|
||||
return iter(ast.ArrayTerm(ast.InternedTerm(false), ast.InternedEmptyArray))
|
||||
}
|
||||
|
||||
// Collect the cert verification options
|
||||
@@ -159,7 +159,7 @@ func builtinCryptoX509ParseAndVerifyCertificatesWithOptions(_ BuiltinContext, op
|
||||
|
||||
verified, err := verifyX509CertificateChain(certs, verifyOpt)
|
||||
if err != nil {
|
||||
return iter(ast.ArrayTerm(ast.InternedBooleanTerm(false), ast.InternedEmptyArray))
|
||||
return iter(ast.ArrayTerm(ast.InternedTerm(false), ast.InternedEmptyArray))
|
||||
}
|
||||
|
||||
value, err := ast.InterfaceToValue(verified)
|
||||
@@ -167,7 +167,7 @@ func builtinCryptoX509ParseAndVerifyCertificatesWithOptions(_ BuiltinContext, op
|
||||
return err
|
||||
}
|
||||
|
||||
return iter(ast.ArrayTerm(ast.InternedBooleanTerm(true), ast.NewTerm(value)))
|
||||
return iter(ast.ArrayTerm(ast.InternedTerm(true), ast.NewTerm(value)))
|
||||
}
|
||||
|
||||
func extractVerifyOpts(options ast.Object) (verifyOpt x509.VerifyOptions, err error) {
|
||||
@@ -513,7 +513,7 @@ func builtinCryptoHmacEqual(_ BuiltinContext, operands []*ast.Term, iter func(*a
|
||||
|
||||
res := hmac.Equal([]byte(mac1), []byte(mac2))
|
||||
|
||||
return iter(ast.InternedBooleanTerm(res))
|
||||
return iter(ast.InternedTerm(res))
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
||||
+8
-8
@@ -144,10 +144,10 @@ func builtinJSONIsValid(_ BuiltinContext, operands []*ast.Term, iter func(*ast.T
|
||||
|
||||
str, err := builtins.StringOperand(operands[0].Value, 1)
|
||||
if err != nil {
|
||||
return iter(ast.InternedBooleanTerm(false))
|
||||
return iter(ast.InternedTerm(false))
|
||||
}
|
||||
|
||||
return iter(ast.InternedBooleanTerm(json.Valid([]byte(str))))
|
||||
return iter(ast.InternedTerm(json.Valid([]byte(str))))
|
||||
}
|
||||
|
||||
func builtinBase64Encode(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
@@ -169,17 +169,17 @@ func builtinBase64Decode(_ BuiltinContext, operands []*ast.Term, iter func(*ast.
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return iter(ast.StringTerm(string(result)))
|
||||
return iter(ast.InternedTerm(string(result)))
|
||||
}
|
||||
|
||||
func builtinBase64IsValid(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
str, err := builtins.StringOperand(operands[0].Value, 1)
|
||||
if err != nil {
|
||||
return iter(ast.InternedBooleanTerm(false))
|
||||
return iter(ast.InternedTerm(false))
|
||||
}
|
||||
|
||||
_, err = base64.StdEncoding.DecodeString(string(str))
|
||||
return iter(ast.InternedBooleanTerm(err == nil))
|
||||
return iter(ast.InternedTerm(err == nil))
|
||||
}
|
||||
|
||||
func builtinBase64UrlEncode(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
@@ -224,7 +224,7 @@ func builtinBase64UrlDecode(_ BuiltinContext, operands []*ast.Term, iter func(*a
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return iter(ast.StringTerm(string(result)))
|
||||
return iter(ast.InternedTerm(string(result)))
|
||||
}
|
||||
|
||||
func builtinURLQueryEncode(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
@@ -355,12 +355,12 @@ func builtinYAMLUnmarshal(_ BuiltinContext, operands []*ast.Term, iter func(*ast
|
||||
func builtinYAMLIsValid(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
str, err := builtins.StringOperand(operands[0].Value, 1)
|
||||
if err != nil {
|
||||
return iter(ast.InternedBooleanTerm(false))
|
||||
return iter(ast.InternedTerm(false))
|
||||
}
|
||||
|
||||
var x any
|
||||
err = yaml.Unmarshal([]byte(str), &x)
|
||||
return iter(ast.InternedBooleanTerm(err == nil))
|
||||
return iter(ast.InternedTerm(err == nil))
|
||||
}
|
||||
|
||||
func builtinHexEncode(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
|
||||
+64
-41
@@ -229,6 +229,11 @@ func (e *eval) unknown(x any, b *bindings) bool {
|
||||
return saveRequired(e.compiler, e.inliningControl, true, e.saveSet, b, x, false)
|
||||
}
|
||||
|
||||
// exactly like `unknown` above` but without the cost of `any` boxing when arg is known to be a ref
|
||||
func (e *eval) unknownRef(ref ast.Ref, b *bindings) bool {
|
||||
return e.partial() && saveRequired(e.compiler, e.inliningControl, true, e.saveSet, b, ast.NewTerm(ref), false)
|
||||
}
|
||||
|
||||
func (e *eval) traceEnter(x ast.Node) {
|
||||
e.traceEvent(EnterOp, x, "", nil)
|
||||
}
|
||||
@@ -458,7 +463,7 @@ func (e *eval) evalStep(iter evalIterator) error {
|
||||
return iter(e)
|
||||
})
|
||||
}
|
||||
if !e.bindings.Plug(rterm).Equal(ast.InternedBooleanTerm(false)) {
|
||||
if !e.bindings.Plug(rterm).Equal(ast.InternedTerm(false)) {
|
||||
defined = true
|
||||
err := iter(e)
|
||||
e.traceRedo(expr)
|
||||
@@ -519,7 +524,7 @@ func (e *eval) evalStep(iter evalIterator) error {
|
||||
return iter(e)
|
||||
})
|
||||
}
|
||||
if !e.bindings.Plug(rterm).Equal(ast.InternedBooleanTerm(false)) {
|
||||
if !e.bindings.Plug(rterm).Equal(ast.InternedTerm(false)) {
|
||||
return iter(e)
|
||||
}
|
||||
return nil
|
||||
@@ -917,6 +922,7 @@ func (e *eval) evalCall(terms []*ast.Term, iter unifyIterator) error {
|
||||
} else {
|
||||
ir, err = e.getRules(ref, terms[1:])
|
||||
}
|
||||
defer ast.IndexResultPool.Put(ir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -943,36 +949,41 @@ func (e *eval) evalCall(terms []*ast.Term, iter unifyIterator) error {
|
||||
return e.saveCall(bi.Decl.Arity(), terms, iter)
|
||||
}
|
||||
|
||||
var parentID uint64
|
||||
if e.parent != nil {
|
||||
parentID = e.parent.queryID
|
||||
}
|
||||
var bctx *BuiltinContext
|
||||
|
||||
var capabilities *ast.Capabilities
|
||||
if e.compiler != nil {
|
||||
capabilities = e.compiler.Capabilities()
|
||||
}
|
||||
// Creating a BuiltinContext is expensive, so only do it if the builtin depends on it.
|
||||
if bi.NeedsBuiltInContext() {
|
||||
var parentID uint64
|
||||
if e.parent != nil {
|
||||
parentID = e.parent.queryID
|
||||
}
|
||||
|
||||
bctx := BuiltinContext{
|
||||
Context: e.ctx,
|
||||
Metrics: e.metrics,
|
||||
Seed: e.seed,
|
||||
Time: e.time,
|
||||
Cancel: e.cancel,
|
||||
Runtime: e.runtime,
|
||||
Cache: e.builtinCache,
|
||||
InterQueryBuiltinCache: e.interQueryBuiltinCache,
|
||||
InterQueryBuiltinValueCache: e.interQueryBuiltinValueCache,
|
||||
NDBuiltinCache: e.ndBuiltinCache,
|
||||
Location: e.query[e.index].Location,
|
||||
QueryTracers: e.tracers,
|
||||
TraceEnabled: e.traceEnabled,
|
||||
QueryID: e.queryID,
|
||||
ParentID: parentID,
|
||||
PrintHook: e.printHook,
|
||||
DistributedTracingOpts: e.tracingOpts,
|
||||
Capabilities: capabilities,
|
||||
RoundTripper: e.roundTripper,
|
||||
var capabilities *ast.Capabilities
|
||||
if e.compiler != nil {
|
||||
capabilities = e.compiler.Capabilities()
|
||||
}
|
||||
|
||||
bctx = &BuiltinContext{
|
||||
Context: e.ctx,
|
||||
Metrics: e.metrics,
|
||||
Seed: e.seed,
|
||||
Time: e.time,
|
||||
Cancel: e.cancel,
|
||||
Runtime: e.runtime,
|
||||
Cache: e.builtinCache,
|
||||
InterQueryBuiltinCache: e.interQueryBuiltinCache,
|
||||
InterQueryBuiltinValueCache: e.interQueryBuiltinValueCache,
|
||||
NDBuiltinCache: e.ndBuiltinCache,
|
||||
Location: e.query[e.index].Location,
|
||||
QueryTracers: e.tracers,
|
||||
TraceEnabled: e.traceEnabled,
|
||||
QueryID: e.queryID,
|
||||
ParentID: parentID,
|
||||
PrintHook: e.printHook,
|
||||
DistributedTracingOpts: e.tracingOpts,
|
||||
Capabilities: capabilities,
|
||||
RoundTripper: e.roundTripper,
|
||||
}
|
||||
}
|
||||
|
||||
eval := evalBuiltin{
|
||||
@@ -1895,6 +1906,7 @@ func (e *eval) getDeclArgsLen(x *ast.Expr) (int, error) {
|
||||
}
|
||||
|
||||
ir, err := e.getRules(operator, nil)
|
||||
defer ast.IndexResultPool.Put(ir)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
} else if ir == nil || ir.Empty() {
|
||||
@@ -1916,14 +1928,14 @@ func (e *eval) updateFromQuery(expr *ast.Expr) {
|
||||
type evalBuiltin struct {
|
||||
e *eval
|
||||
bi *ast.Builtin
|
||||
bctx BuiltinContext
|
||||
bctx *BuiltinContext
|
||||
f BuiltinFunc
|
||||
terms []*ast.Term
|
||||
}
|
||||
|
||||
// Is this builtin non-deterministic, and did the caller provide an NDBCache?
|
||||
func (e *evalBuiltin) canUseNDBCache(bi *ast.Builtin) bool {
|
||||
return bi.Nondeterministic && e.bctx.NDBuiltinCache != nil
|
||||
return bi.Nondeterministic && e.bctx != nil && e.bctx.NDBuiltinCache != nil
|
||||
}
|
||||
|
||||
func (e *evalBuiltin) eval(iter unifyIterator) error {
|
||||
@@ -1971,8 +1983,18 @@ func (e *evalBuiltin) eval(iter unifyIterator) error {
|
||||
e.e.instr.startTimer(evalOpBuiltinCall)
|
||||
}
|
||||
|
||||
var bctx BuiltinContext
|
||||
if e.bctx == nil {
|
||||
bctx = BuiltinContext{
|
||||
// Location potentially needed for error reporting.
|
||||
Location: e.e.query[e.e.index].Location,
|
||||
}
|
||||
} else {
|
||||
bctx = *e.bctx
|
||||
}
|
||||
|
||||
// Normal unification flow for builtins:
|
||||
err := e.f(e.bctx, operands, func(output *ast.Term) error {
|
||||
err := e.f(bctx, operands, func(output *ast.Term) error {
|
||||
|
||||
e.e.instr.stopTimer(evalOpBuiltinCall)
|
||||
|
||||
@@ -2053,7 +2075,7 @@ func (e evalFunc) eval(iter unifyIterator) error {
|
||||
if len(defRule.Head.Args) == len(e.terms)-1 {
|
||||
// The function is called without collecting the result in an output term,
|
||||
// therefore any successful evaluation of the function is of interest, including the default value ...
|
||||
if ret := defRule.Head.Value; ret == nil || !ret.Equal(ast.InternedBooleanTerm(false)) {
|
||||
if ret := defRule.Head.Value; ret == nil || !ret.Equal(ast.InternedTerm(false)) {
|
||||
// ... unless the default value is false,
|
||||
mustGenerateSupport = true
|
||||
}
|
||||
@@ -2070,7 +2092,7 @@ func (e evalFunc) eval(iter unifyIterator) error {
|
||||
if mustGenerateSupport || e.e.inliningControl.shallow || e.e.inliningControl.Disabled(ref, false) {
|
||||
// check if the function definitions, or any of the arguments
|
||||
// contain something unknown
|
||||
unknown := e.e.unknown(ref, e.e.bindings)
|
||||
unknown := e.e.unknownRef(ref, e.e.bindings)
|
||||
for i := 1; !unknown && i <= argCount; i++ {
|
||||
unknown = e.e.unknown(e.terms[i], e.e.bindings)
|
||||
}
|
||||
@@ -2406,7 +2428,7 @@ func (e evalTree) finish(iter unifyIterator) error {
|
||||
// In some cases, it may not be possible to PE the ref. If the path refers
|
||||
// to virtual docs that PE does not support or base documents where inlining
|
||||
// has been disabled, then we have to save.
|
||||
if e.e.partial() && e.e.unknown(e.plugged, e.e.bindings) {
|
||||
if e.e.partial() && e.e.unknownRef(e.plugged, e.e.bindings) {
|
||||
return e.e.saveUnify(ast.NewTerm(e.plugged), e.rterm, e.bindings, e.rbindings, iter)
|
||||
}
|
||||
|
||||
@@ -2468,7 +2490,7 @@ func (e evalTree) enumerate(iter unifyIterator) error {
|
||||
switch doc := doc.(type) {
|
||||
case *ast.Array:
|
||||
for i := range doc.Len() {
|
||||
k := ast.InternedIntNumberTerm(i)
|
||||
k := ast.InternedTerm(i)
|
||||
err := e.e.biunify(k, e.ref[e.pos], e.bindings, e.bindings, func() error {
|
||||
return e.next(iter, k)
|
||||
})
|
||||
@@ -2609,13 +2631,14 @@ type evalVirtual struct {
|
||||
func (e evalVirtual) eval(iter unifyIterator) error {
|
||||
|
||||
ir, err := e.e.getRules(e.plugged[:e.pos+1], nil)
|
||||
defer ast.IndexResultPool.Put(ir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Partial evaluation of ordered rules is not supported currently. Save the
|
||||
// expression and continue. This could be revisited in the future.
|
||||
if len(ir.Else) > 0 && e.e.unknown(e.ref, e.bindings) {
|
||||
if len(ir.Else) > 0 && e.e.unknownRef(e.ref, e.bindings) {
|
||||
return e.e.saveUnify(ast.NewTerm(e.ref), e.rterm, e.bindings, e.rbindings, iter)
|
||||
}
|
||||
|
||||
@@ -3425,7 +3448,7 @@ func (e evalVirtualComplete) eval(iter unifyIterator) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
if !e.e.unknown(e.ref, e.bindings) {
|
||||
if !e.e.unknownRef(e.ref, e.bindings) {
|
||||
return e.evalValue(iter, e.ir.EarlyExit)
|
||||
}
|
||||
|
||||
@@ -3434,7 +3457,7 @@ func (e evalVirtualComplete) eval(iter unifyIterator) error {
|
||||
if e.ir.Default != nil {
|
||||
// If inlining has been disabled for the rterm, and the default rule has a 'false' result value,
|
||||
// the default value is inconsequential, and support does not need to be generated.
|
||||
if !(e.ir.Default.Head.Value.Equal(ast.InternedBooleanTerm(false)) && e.e.inliningControl.Disabled(e.rterm.Value, false)) {
|
||||
if !(e.ir.Default.Head.Value.Equal(ast.InternedTerm(false)) && e.e.inliningControl.Disabled(e.rterm.Value, false)) {
|
||||
// If the other term is not constant OR it's equal to the default value, then
|
||||
// a support rule must be produced as the default value _may_ be required. On
|
||||
// the other hand, if the other term is constant (i.e., it does not require
|
||||
@@ -3752,7 +3775,7 @@ func (e evalTerm) enumerate(iter unifyIterator) error {
|
||||
// win across most policies. Those cases are however much more complex, as we need to deal with
|
||||
// any type on either side, not just int/var as is the case here.
|
||||
for i := range v.Len() {
|
||||
a := ast.InternedIntNumberTerm(i)
|
||||
a := ast.InternedTerm(i)
|
||||
b := e.ref[e.pos]
|
||||
|
||||
if _, ok := b.Value.(ast.Var); ok {
|
||||
|
||||
+1
-1
@@ -57,7 +57,7 @@ func builtinGlobMatch(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return iter(ast.InternedBooleanTerm(m))
|
||||
return iter(ast.InternedTerm(m))
|
||||
}
|
||||
|
||||
func globCompileAndMatch(bctx BuiltinContext, id, pattern, match string, delimiters []rune) (bool, error) {
|
||||
|
||||
+12
-12
@@ -331,7 +331,7 @@ func builtinGraphQLParseAndVerify(bctx BuiltinContext, operands []*ast.Term, ite
|
||||
var err error
|
||||
|
||||
unverified := ast.ArrayTerm(
|
||||
ast.InternedBooleanTerm(false),
|
||||
ast.InternedTerm(false),
|
||||
ast.NewTerm(ast.NewObject()),
|
||||
ast.NewTerm(ast.NewObject()),
|
||||
)
|
||||
@@ -404,7 +404,7 @@ func builtinGraphQLParseAndVerify(bctx BuiltinContext, operands []*ast.Term, ite
|
||||
|
||||
// Construct return value.
|
||||
verified := ast.ArrayTerm(
|
||||
ast.InternedBooleanTerm(true),
|
||||
ast.InternedTerm(true),
|
||||
ast.NewTerm(queryResult),
|
||||
ast.NewTerm(querySchema),
|
||||
)
|
||||
@@ -482,10 +482,10 @@ func builtinGraphQLIsValid(bctx BuiltinContext, operands []*ast.Term, iter func(
|
||||
queryDoc, err = objectToQueryDocument(x)
|
||||
default:
|
||||
// Error if wrong type.
|
||||
return iter(ast.InternedBooleanTerm(false))
|
||||
return iter(ast.InternedTerm(false))
|
||||
}
|
||||
if err != nil {
|
||||
return iter(ast.InternedBooleanTerm(false))
|
||||
return iter(ast.InternedTerm(false))
|
||||
}
|
||||
|
||||
schemaCacheKey, schema := cacheGetSchema(bctx, operands[1])
|
||||
@@ -497,26 +497,26 @@ func builtinGraphQLIsValid(bctx BuiltinContext, operands []*ast.Term, iter func(
|
||||
schemaDoc, err = objectToSchemaDocument(x)
|
||||
default:
|
||||
// Error if wrong type.
|
||||
return iter(ast.InternedBooleanTerm(false))
|
||||
return iter(ast.InternedTerm(false))
|
||||
}
|
||||
if err != nil {
|
||||
return iter(ast.InternedBooleanTerm(false))
|
||||
return iter(ast.InternedTerm(false))
|
||||
}
|
||||
|
||||
// Validate the query against the schema, erroring if there's an issue.
|
||||
schema, err = convertSchema(schemaDoc)
|
||||
if err != nil {
|
||||
return iter(ast.InternedBooleanTerm(false))
|
||||
return iter(ast.InternedTerm(false))
|
||||
}
|
||||
cacheInsertSchema(bctx, schemaCacheKey, schema)
|
||||
}
|
||||
|
||||
if err := validateQuery(schema, queryDoc); err != nil {
|
||||
return iter(ast.InternedBooleanTerm(false))
|
||||
return iter(ast.InternedTerm(false))
|
||||
}
|
||||
|
||||
// If we got this far, the GraphQL query passed validation.
|
||||
return iter(ast.InternedBooleanTerm(true))
|
||||
return iter(ast.InternedTerm(true))
|
||||
}
|
||||
|
||||
func builtinGraphQLSchemaIsValid(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
@@ -535,10 +535,10 @@ func builtinGraphQLSchemaIsValid(bctx BuiltinContext, operands []*ast.Term, iter
|
||||
schemaDoc, err = objectToSchemaDocument(x)
|
||||
default:
|
||||
// Error if wrong type.
|
||||
return iter(ast.InternedBooleanTerm(false))
|
||||
return iter(ast.InternedTerm(false))
|
||||
}
|
||||
if err != nil {
|
||||
return iter(ast.InternedBooleanTerm(false))
|
||||
return iter(ast.InternedTerm(false))
|
||||
}
|
||||
// Validate the schema, this determines the result
|
||||
// and whether there is a schema to cache
|
||||
@@ -548,7 +548,7 @@ func builtinGraphQLSchemaIsValid(bctx BuiltinContext, operands []*ast.Term, iter
|
||||
}
|
||||
}
|
||||
|
||||
return iter(ast.InternedBooleanTerm(err == nil))
|
||||
return iter(ast.InternedTerm(err == nil))
|
||||
}
|
||||
|
||||
// Insert Schema into cache
|
||||
|
||||
+32
-11
@@ -14,6 +14,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"mime"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
@@ -95,7 +96,7 @@ var (
|
||||
allowedKeys = ast.NewSet()
|
||||
keyCache = make(map[string]*ast.Term, len(allowedKeyNames))
|
||||
cacheableCodes = ast.NewSet()
|
||||
requiredKeys = ast.NewSet(ast.InternedStringTerm("method"), ast.InternedStringTerm("url"))
|
||||
requiredKeys = ast.NewSet(ast.InternedTerm("method"), ast.InternedTerm("url"))
|
||||
httpSendLatencyMetricKey = "rego_builtin_http_send"
|
||||
httpSendInterQueryCacheHits = httpSendLatencyMetricKey + "_interquery_cache_hits"
|
||||
)
|
||||
@@ -161,19 +162,19 @@ func generateRaiseErrorResult(err error) *ast.Term {
|
||||
switch err.(type) {
|
||||
case *url.Error:
|
||||
errObj = ast.NewObject(
|
||||
ast.Item(ast.InternedStringTerm("code"), httpSendNetworkErrTerm),
|
||||
ast.Item(ast.InternedStringTerm("message"), ast.StringTerm(err.Error())),
|
||||
ast.Item(ast.InternedTerm("code"), httpSendNetworkErrTerm),
|
||||
ast.Item(ast.InternedTerm("message"), ast.StringTerm(err.Error())),
|
||||
)
|
||||
default:
|
||||
errObj = ast.NewObject(
|
||||
ast.Item(ast.InternedStringTerm("code"), httpSendInternalErrTerm),
|
||||
ast.Item(ast.InternedStringTerm("message"), ast.StringTerm(err.Error())),
|
||||
ast.Item(ast.InternedTerm("code"), httpSendInternalErrTerm),
|
||||
ast.Item(ast.InternedTerm("message"), ast.StringTerm(err.Error())),
|
||||
)
|
||||
}
|
||||
|
||||
return ast.ObjectTerm(
|
||||
ast.Item(ast.InternedStringTerm("status_code"), ast.InternedIntNumberTerm(0)),
|
||||
ast.Item(ast.InternedStringTerm("error"), ast.NewTerm(errObj)),
|
||||
ast.Item(ast.InternedTerm("status_code"), ast.InternedTerm(0)),
|
||||
ast.Item(ast.InternedTerm("error"), ast.NewTerm(errObj)),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -755,6 +756,26 @@ func executeHTTPRequest(req *http.Request, client *http.Client, inputReqObj ast.
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func isJSONType(header http.Header) bool {
|
||||
t, _, err := mime.ParseMediaType(header.Get("Content-Type"))
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
mediaType := strings.Split(t, "/")
|
||||
if len(mediaType) != 2 {
|
||||
return false
|
||||
}
|
||||
|
||||
if mediaType[0] == "application" {
|
||||
if mediaType[1] == "json" || strings.HasSuffix(mediaType[1], "+json") {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func isContentType(header http.Header, typ ...string) bool {
|
||||
for _, t := range typ {
|
||||
if strings.Contains(header.Get("Content-Type"), t) {
|
||||
@@ -962,7 +983,7 @@ func (c *interQueryCache) checkHTTPSendInterQueryCache() (ast.Value, error) {
|
||||
|
||||
// insertIntoHTTPSendInterQueryCache inserts given key and value in the inter-query cache
|
||||
func insertIntoHTTPSendInterQueryCache(bctx BuiltinContext, key ast.Value, resp *http.Response, respBody []byte, cacheParams *forceCacheParams) error {
|
||||
if resp == nil || (!forceCaching(cacheParams) && !canStore(resp.Header)) || !cacheableCodes.Contains(ast.InternedIntNumberTerm(resp.StatusCode)) {
|
||||
if resp == nil || (!forceCaching(cacheParams) && !canStore(resp.Header)) || !cacheableCodes.Contains(ast.InternedTerm(resp.StatusCode)) {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1006,7 +1027,7 @@ func createKeys() {
|
||||
|
||||
func createCacheableHTTPStatusCodes() {
|
||||
for _, element := range cacheableHTTPStatusCodes {
|
||||
cacheableCodes.Add(ast.InternedIntNumberTerm(element))
|
||||
cacheableCodes.Add(ast.InternedTerm(element))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1383,7 +1404,7 @@ func prepareASTResult(headers http.Header, forceJSONDecode, forceYAMLDecode bool
|
||||
// an error will not be returned. Instead, the "body" field
|
||||
// in the result will be null.
|
||||
switch {
|
||||
case forceJSONDecode || isContentType(headers, "application/json"):
|
||||
case forceJSONDecode || isJSONType(headers):
|
||||
_ = util.UnmarshalJSON(body, &resultBody)
|
||||
case forceYAMLDecode || isContentType(headers, "application/yaml", "application/x-yaml"):
|
||||
_ = util.Unmarshal(body, &resultBody)
|
||||
@@ -1548,7 +1569,7 @@ func (c *intraQueryCache) InsertIntoCache(value *http.Response) (ast.Value, erro
|
||||
return nil, handleHTTPSendErr(c.bctx, err)
|
||||
}
|
||||
|
||||
if cacheableCodes.Contains(ast.InternedIntNumberTerm(value.StatusCode)) {
|
||||
if cacheableCodes.Contains(ast.InternedTerm(value.StatusCode)) {
|
||||
insertIntoHTTPSendCache(c.bctx, c.key, result)
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -44,7 +44,7 @@ func astValueToJSONSchemaLoader(value ast.Value) (gojsonschema.JSONLoader, error
|
||||
}
|
||||
|
||||
func newResultTerm(valid bool, data *ast.Term) *ast.Term {
|
||||
return ast.ArrayTerm(ast.InternedBooleanTerm(valid), data)
|
||||
return ast.ArrayTerm(ast.InternedTerm(valid), data)
|
||||
}
|
||||
|
||||
// builtinJSONSchemaVerify accepts 1 argument which can be string or object and checks if it is valid JSON schema.
|
||||
|
||||
+24
-20
@@ -20,7 +20,7 @@ var one = big.NewInt(1)
|
||||
|
||||
func builtinNumbersRange(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
if canGenerateCheapRange(operands) {
|
||||
return generateCheapRange(operands, iter)
|
||||
return generateCheapRange(operands, 1, iter)
|
||||
}
|
||||
|
||||
x, err := builtins.BigIntOperand(operands[0].Value, 1)
|
||||
@@ -42,6 +42,13 @@ func builtinNumbersRange(bctx BuiltinContext, operands []*ast.Term, iter func(*a
|
||||
}
|
||||
|
||||
func builtinNumbersRangeStep(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
if canGenerateCheapRangeStep(operands) {
|
||||
step, _ := builtins.IntOperand(operands[2].Value, 3)
|
||||
if step <= 0 {
|
||||
return errors.New("numbers.range_step: step must be a positive number above zero")
|
||||
}
|
||||
return generateCheapRange(operands, step, iter)
|
||||
}
|
||||
|
||||
x, err := builtins.BigIntOperand(operands[0].Value, 1)
|
||||
if err != nil {
|
||||
@@ -84,7 +91,18 @@ func canGenerateCheapRange(operands []*ast.Term) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func generateCheapRange(operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
func canGenerateCheapRangeStep(operands []*ast.Term) bool {
|
||||
if canGenerateCheapRange(operands) {
|
||||
step, err := builtins.IntOperand(operands[1].Value, 3)
|
||||
if err == nil && ast.HasInternedIntNumberTerm(step) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func generateCheapRange(operands []*ast.Term, step int, iter func(*ast.Term) error) error {
|
||||
x, err := builtins.IntOperand(operands[0].Value, 1)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -95,28 +113,15 @@ func generateCheapRange(operands []*ast.Term, iter func(*ast.Term) error) error
|
||||
return err
|
||||
}
|
||||
|
||||
step := 1
|
||||
|
||||
if len(operands) > 2 {
|
||||
stepOp, err := builtins.IntOperand(operands[2].Value, 3)
|
||||
if err == nil {
|
||||
step = stepOp
|
||||
}
|
||||
}
|
||||
|
||||
if step <= 0 {
|
||||
return errors.New("numbers.range_step: step must be a positive number above zero")
|
||||
}
|
||||
|
||||
terms := make([]*ast.Term, 0, y+1)
|
||||
|
||||
if x <= y {
|
||||
for i := x; i <= y; i += step {
|
||||
terms = append(terms, ast.InternedIntNumberTerm(i))
|
||||
terms = append(terms, ast.InternedTerm(i))
|
||||
}
|
||||
} else {
|
||||
for i := x; i >= y; i -= step {
|
||||
terms = append(terms, ast.InternedIntNumberTerm(i))
|
||||
terms = append(terms, ast.InternedTerm(i))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,7 +129,6 @@ func generateCheapRange(operands []*ast.Term, iter func(*ast.Term) error) error
|
||||
}
|
||||
|
||||
func generateRange(bctx BuiltinContext, x *big.Int, y *big.Int, step *big.Int, funcName string) (*ast.Term, error) {
|
||||
|
||||
cmp := x.Cmp(y)
|
||||
|
||||
comp := func(i *big.Int, y *big.Int) bool { return i.Cmp(y) <= 0 }
|
||||
@@ -167,7 +171,7 @@ func builtinRandIntn(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.T
|
||||
}
|
||||
|
||||
if n == 0 {
|
||||
return iter(ast.InternedIntNumberTerm(0))
|
||||
return iter(ast.InternedTerm(0))
|
||||
}
|
||||
|
||||
if n < 0 {
|
||||
@@ -184,7 +188,7 @@ func builtinRandIntn(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.T
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
result := ast.InternedIntNumberTerm(r.Intn(n))
|
||||
result := ast.InternedTerm(r.Intn(n))
|
||||
bctx.Cache.Put(key, result)
|
||||
|
||||
return iter(result)
|
||||
|
||||
+1
-1
@@ -400,7 +400,7 @@ func (q *Query) PartialRun(ctx context.Context) (partials []ast.Body, support []
|
||||
saveSet: newSaveSet(q.unknowns, b, q.instr),
|
||||
saveStack: newSaveStack(),
|
||||
saveSupport: newSaveSupport(),
|
||||
saveNamespace: ast.InternedStringTerm(q.partialNamespace),
|
||||
saveNamespace: ast.InternedTerm(q.partialNamespace),
|
||||
skipSaveNamespace: q.skipSaveNamespace,
|
||||
inliningControl: &inliningControl{
|
||||
shallow: q.shallowInlining,
|
||||
|
||||
+7
-7
@@ -25,15 +25,15 @@ func builtinRegexIsValid(_ BuiltinContext, operands []*ast.Term, iter func(*ast.
|
||||
|
||||
s, err := builtins.StringOperand(operands[0].Value, 1)
|
||||
if err != nil {
|
||||
return iter(ast.InternedBooleanTerm(false))
|
||||
return iter(ast.InternedTerm(false))
|
||||
}
|
||||
|
||||
_, err = regexp.Compile(string(s))
|
||||
if err != nil {
|
||||
return iter(ast.InternedBooleanTerm(false))
|
||||
return iter(ast.InternedTerm(false))
|
||||
}
|
||||
|
||||
return iter(ast.InternedBooleanTerm(true))
|
||||
return iter(ast.InternedTerm(true))
|
||||
}
|
||||
|
||||
func builtinRegexMatch(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
@@ -49,7 +49,7 @@ func builtinRegexMatch(bctx BuiltinContext, operands []*ast.Term, iter func(*ast
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return iter(ast.InternedBooleanTerm(re.MatchString(string(s2))))
|
||||
return iter(ast.InternedTerm(re.MatchString(string(s2))))
|
||||
}
|
||||
|
||||
func builtinRegexMatchTemplate(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
@@ -79,7 +79,7 @@ func builtinRegexMatchTemplate(_ BuiltinContext, operands []*ast.Term, iter func
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return iter(ast.InternedBooleanTerm(re.MatchString(string(match))))
|
||||
return iter(ast.InternedTerm(re.MatchString(string(match))))
|
||||
}
|
||||
|
||||
func builtinRegexSplit(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
@@ -177,7 +177,7 @@ func builtinGlobsMatch(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Te
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return iter(ast.InternedBooleanTerm(ne))
|
||||
return iter(ast.InternedTerm(ne))
|
||||
}
|
||||
|
||||
func builtinRegexFind(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
@@ -264,7 +264,7 @@ func builtinRegexReplace(bctx BuiltinContext, operands []*ast.Term, iter func(*a
|
||||
return iter(operands[0])
|
||||
}
|
||||
|
||||
return iter(ast.InternedStringTerm(res))
|
||||
return iter(ast.InternedTerm(res))
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ func builtinOPARuntime(bctx BuiltinContext, _ []*ast.Term, iter func(*ast.Term)
|
||||
return iter(ast.InternedEmptyObject)
|
||||
}
|
||||
|
||||
if bctx.Runtime.Get(ast.InternedStringTerm("config")) != nil {
|
||||
if bctx.Runtime.Get(ast.InternedTerm("config")) != nil {
|
||||
iface, err := ast.ValueToInterface(bctx.Runtime.Value, nothingResolver)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
+3
-3
@@ -34,13 +34,13 @@ func builtinSemVerCompare(_ BuiltinContext, operands []*ast.Term, iter func(*ast
|
||||
|
||||
result := versionA.Compare(*versionB)
|
||||
|
||||
return iter(ast.InternedIntNumberTerm(result))
|
||||
return iter(ast.InternedTerm(result))
|
||||
}
|
||||
|
||||
func builtinSemVerIsValid(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
versionString, err := builtins.StringOperand(operands[0].Value, 1)
|
||||
if err != nil {
|
||||
return iter(ast.InternedBooleanTerm(false))
|
||||
return iter(ast.InternedTerm(false))
|
||||
}
|
||||
|
||||
result := true
|
||||
@@ -50,7 +50,7 @@ func builtinSemVerIsValid(_ BuiltinContext, operands []*ast.Term, iter func(*ast
|
||||
result = false
|
||||
}
|
||||
|
||||
return iter(ast.InternedBooleanTerm(result))
|
||||
return iter(ast.InternedTerm(result))
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
||||
+121
-74
@@ -51,7 +51,7 @@ func builtinAnyPrefixMatch(_ BuiltinContext, operands []*ast.Term, iter func(*as
|
||||
return builtins.NewOperandTypeErr(2, b, "string", "set", "array")
|
||||
}
|
||||
|
||||
return iter(ast.InternedBooleanTerm(anyStartsWithAny(strs, prefixes)))
|
||||
return iter(ast.InternedTerm(anyStartsWithAny(strs, prefixes)))
|
||||
}
|
||||
|
||||
func builtinAnySuffixMatch(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
@@ -91,7 +91,7 @@ func builtinAnySuffixMatch(_ BuiltinContext, operands []*ast.Term, iter func(*as
|
||||
return builtins.NewOperandTypeErr(2, b, "string", "set", "array")
|
||||
}
|
||||
|
||||
return iter(ast.InternedBooleanTerm(anyStartsWithAny(strsReversed, suffixesReversed)))
|
||||
return iter(ast.InternedTerm(anyStartsWithAny(strsReversed, suffixesReversed)))
|
||||
}
|
||||
|
||||
func anyStartsWithAny(strs []string, prefixes []string) bool {
|
||||
@@ -148,63 +148,110 @@ func builtinFormatInt(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Ter
|
||||
f := builtins.NumberToFloat(input)
|
||||
i, _ := f.Int(nil)
|
||||
|
||||
return iter(ast.InternedStringTerm(fmt.Sprintf(format, i)))
|
||||
return iter(ast.InternedTerm(fmt.Sprintf(format, i)))
|
||||
}
|
||||
|
||||
func builtinConcat(b BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
|
||||
func builtinConcat(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
join, err := builtins.StringOperand(operands[0].Value, 1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var strs []string
|
||||
|
||||
switch b := operands[1].Value.(type) {
|
||||
case *ast.Array:
|
||||
var l int
|
||||
for i := range b.Len() {
|
||||
s, ok := b.Elem(i).Value.(ast.String)
|
||||
if !ok {
|
||||
return builtins.NewOperandElementErr(2, operands[1].Value, b.Elem(i).Value, "string")
|
||||
}
|
||||
l += len(string(s))
|
||||
}
|
||||
|
||||
if b.Len() == 1 {
|
||||
return iter(b.Elem(0))
|
||||
}
|
||||
|
||||
strs = make([]string, 0, l)
|
||||
for i := range b.Len() {
|
||||
strs = append(strs, string(b.Elem(i).Value.(ast.String)))
|
||||
}
|
||||
|
||||
case ast.Set:
|
||||
var l int
|
||||
terms := b.Slice()
|
||||
for i := range terms {
|
||||
s, ok := terms[i].Value.(ast.String)
|
||||
if !ok {
|
||||
return builtins.NewOperandElementErr(2, operands[1].Value, terms[i].Value, "string")
|
||||
}
|
||||
l += len(string(s))
|
||||
}
|
||||
|
||||
if b.Len() == 1 {
|
||||
return iter(b.Slice()[0])
|
||||
}
|
||||
|
||||
strs = make([]string, 0, l)
|
||||
for i := range b.Len() {
|
||||
strs = append(strs, string(terms[i].Value.(ast.String)))
|
||||
}
|
||||
|
||||
default:
|
||||
return builtins.NewOperandTypeErr(2, operands[1].Value, "set", "array")
|
||||
// fast path for empty or single string array/set, allocates no memory
|
||||
if term, ok := zeroOrOneStringTerm(operands[1].Value); ok {
|
||||
return iter(term)
|
||||
}
|
||||
|
||||
return iter(ast.InternedStringTerm(strings.Join(strs, string(join))))
|
||||
// NOTE(anderseknert):
|
||||
// More or less Go's strings.Join implementation, but where we avoid
|
||||
// creating an intermediate []string slice to pass to that function,
|
||||
// as that's expensive (3.5x more space allocated). Instead we build
|
||||
// the string directly using a strings.Builder to concatenate the string
|
||||
// values from the array/set with the separator.
|
||||
n := 0
|
||||
switch b := operands[1].Value.(type) {
|
||||
case *ast.Array:
|
||||
l := b.Len()
|
||||
for i := range l {
|
||||
s, ok := b.Elem(i).Value.(ast.String)
|
||||
if !ok {
|
||||
return builtins.NewOperandElementErr(2, b, b.Elem(i).Value, "string")
|
||||
}
|
||||
n += len(s)
|
||||
}
|
||||
sep := string(join)
|
||||
n += len(sep) * (l - 1)
|
||||
var sb strings.Builder
|
||||
sb.Grow(n)
|
||||
sb.WriteString(string(b.Elem(0).Value.(ast.String)))
|
||||
if sep == "" {
|
||||
for i := 1; i < l; i++ {
|
||||
sb.WriteString(string(b.Elem(i).Value.(ast.String)))
|
||||
}
|
||||
} else if len(sep) == 1 {
|
||||
// when the separator is a single byte, sb.WriteByte is substantially faster
|
||||
bsep := sep[0]
|
||||
for i := 1; i < l; i++ {
|
||||
sb.WriteByte(bsep)
|
||||
sb.WriteString(string(b.Elem(i).Value.(ast.String)))
|
||||
}
|
||||
} else {
|
||||
// for longer separators, there is no such difference between WriteString and Write
|
||||
for i := 1; i < l; i++ {
|
||||
sb.WriteString(sep)
|
||||
sb.WriteString(string(b.Elem(i).Value.(ast.String)))
|
||||
}
|
||||
}
|
||||
return iter(ast.InternedTerm(sb.String()))
|
||||
case ast.Set:
|
||||
for _, v := range b.Slice() {
|
||||
s, ok := v.Value.(ast.String)
|
||||
if !ok {
|
||||
return builtins.NewOperandElementErr(2, b, v.Value, "string")
|
||||
}
|
||||
n += len(s)
|
||||
}
|
||||
sep := string(join)
|
||||
l := b.Len()
|
||||
n += len(sep) * (l - 1)
|
||||
var sb strings.Builder
|
||||
sb.Grow(n)
|
||||
for i, v := range b.Slice() {
|
||||
sb.WriteString(string(v.Value.(ast.String)))
|
||||
if i < l-1 {
|
||||
sb.WriteString(sep)
|
||||
}
|
||||
}
|
||||
return iter(ast.InternedTerm(sb.String()))
|
||||
}
|
||||
|
||||
return builtins.NewOperandTypeErr(2, operands[1].Value, "set", "array")
|
||||
}
|
||||
|
||||
func zeroOrOneStringTerm(a ast.Value) (*ast.Term, bool) {
|
||||
switch b := a.(type) {
|
||||
case *ast.Array:
|
||||
if b.Len() == 0 {
|
||||
return ast.InternedEmptyString, true
|
||||
}
|
||||
if b.Len() == 1 {
|
||||
e := b.Elem(0)
|
||||
if _, ok := e.Value.(ast.String); ok {
|
||||
return e, true
|
||||
}
|
||||
}
|
||||
case ast.Set:
|
||||
if b.Len() == 0 {
|
||||
return ast.InternedEmptyString, true
|
||||
}
|
||||
if b.Len() == 1 {
|
||||
e := b.Slice()[0]
|
||||
if _, ok := e.Value.(ast.String); ok {
|
||||
return e, true
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func runesEqual(a, b []rune) bool {
|
||||
@@ -237,7 +284,7 @@ func builtinIndexOf(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term)
|
||||
// this is a false positive in the indexAlloc rule that thinks
|
||||
// we're converting byte arrays to strings
|
||||
//nolint:gocritic
|
||||
return iter(ast.InternedIntNumberTerm(strings.Index(string(base), string(search))))
|
||||
return iter(ast.InternedTerm(strings.Index(string(base), string(search))))
|
||||
}
|
||||
|
||||
baseRunes := []rune(string(base))
|
||||
@@ -247,14 +294,14 @@ func builtinIndexOf(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term)
|
||||
for i, r := range baseRunes {
|
||||
if len(baseRunes) >= i+searchLen {
|
||||
if r == searchRunes[0] && runesEqual(baseRunes[i:i+searchLen], searchRunes) {
|
||||
return iter(ast.InternedIntNumberTerm(i))
|
||||
return iter(ast.InternedTerm(i))
|
||||
}
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return iter(ast.InternedIntNumberTerm(-1))
|
||||
return iter(ast.InternedTerm(-1))
|
||||
}
|
||||
|
||||
func builtinIndexOfN(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
@@ -279,7 +326,7 @@ func builtinIndexOfN(_ BuiltinContext, operands []*ast.Term, iter func(*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.InternedIntNumberTerm(i))
|
||||
arr = append(arr, ast.InternedTerm(i))
|
||||
}
|
||||
} else {
|
||||
break
|
||||
@@ -323,7 +370,7 @@ func builtinSubstring(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Ter
|
||||
}
|
||||
|
||||
if length < 0 {
|
||||
return iter(ast.InternedStringTerm(sbase[startIndex:]))
|
||||
return iter(ast.InternedTerm(sbase[startIndex:]))
|
||||
}
|
||||
|
||||
if startIndex == 0 && length >= len(sbase) {
|
||||
@@ -331,7 +378,7 @@ func builtinSubstring(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Ter
|
||||
}
|
||||
|
||||
upto := min(len(sbase), startIndex+length)
|
||||
return iter(ast.InternedStringTerm(sbase[startIndex:upto]))
|
||||
return iter(ast.InternedTerm(sbase[startIndex:upto]))
|
||||
}
|
||||
|
||||
if startIndex == 0 && length >= utf8.RuneCountInString(sbase) {
|
||||
@@ -352,7 +399,7 @@ func builtinSubstring(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Ter
|
||||
s = string(runes[startIndex:upto])
|
||||
}
|
||||
|
||||
return iter(ast.InternedStringTerm(s))
|
||||
return iter(ast.InternedTerm(s))
|
||||
}
|
||||
|
||||
func isASCII(s string) bool {
|
||||
@@ -375,7 +422,7 @@ func builtinContains(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term
|
||||
return err
|
||||
}
|
||||
|
||||
return iter(ast.InternedBooleanTerm(strings.Contains(string(s), string(substr))))
|
||||
return iter(ast.InternedTerm(strings.Contains(string(s), string(substr))))
|
||||
}
|
||||
|
||||
func builtinStringCount(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
@@ -393,7 +440,7 @@ func builtinStringCount(_ BuiltinContext, operands []*ast.Term, iter func(*ast.T
|
||||
searchTerm := string(substr)
|
||||
count := strings.Count(baseTerm, searchTerm)
|
||||
|
||||
return iter(ast.InternedIntNumberTerm(count))
|
||||
return iter(ast.InternedTerm(count))
|
||||
}
|
||||
|
||||
func builtinStartsWith(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
@@ -407,7 +454,7 @@ func builtinStartsWith(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Te
|
||||
return err
|
||||
}
|
||||
|
||||
return iter(ast.InternedBooleanTerm(strings.HasPrefix(string(s), string(prefix))))
|
||||
return iter(ast.InternedTerm(strings.HasPrefix(string(s), string(prefix))))
|
||||
}
|
||||
|
||||
func builtinEndsWith(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
@@ -421,7 +468,7 @@ func builtinEndsWith(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term
|
||||
return err
|
||||
}
|
||||
|
||||
return iter(ast.InternedBooleanTerm(strings.HasSuffix(string(s), string(suffix))))
|
||||
return iter(ast.InternedTerm(strings.HasSuffix(string(s), string(suffix))))
|
||||
}
|
||||
|
||||
func builtinLower(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
@@ -437,7 +484,7 @@ func builtinLower(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) e
|
||||
return iter(operands[0])
|
||||
}
|
||||
|
||||
return iter(ast.InternedStringTerm(low))
|
||||
return iter(ast.InternedTerm(low))
|
||||
}
|
||||
|
||||
func builtinUpper(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
@@ -453,7 +500,7 @@ func builtinUpper(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) e
|
||||
return iter(operands[0])
|
||||
}
|
||||
|
||||
return iter(ast.InternedStringTerm(upp))
|
||||
return iter(ast.InternedTerm(upp))
|
||||
}
|
||||
|
||||
func builtinSplit(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
@@ -475,7 +522,7 @@ func builtinSplit(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) e
|
||||
arr := make([]*ast.Term, len(elems))
|
||||
|
||||
for i := range elems {
|
||||
arr[i] = ast.InternedStringTerm(elems[i])
|
||||
arr[i] = ast.InternedTerm(elems[i])
|
||||
}
|
||||
|
||||
return iter(ast.ArrayTerm(arr...))
|
||||
@@ -502,7 +549,7 @@ func builtinReplace(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term)
|
||||
return iter(operands[0])
|
||||
}
|
||||
|
||||
return iter(ast.InternedStringTerm(replaced))
|
||||
return iter(ast.InternedTerm(replaced))
|
||||
}
|
||||
|
||||
func builtinReplaceN(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
@@ -532,7 +579,7 @@ func builtinReplaceN(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term
|
||||
oldnewArr = append(oldnewArr, string(keyVal), string(strVal))
|
||||
}
|
||||
|
||||
return iter(ast.InternedStringTerm(strings.NewReplacer(oldnewArr...).Replace(string(s))))
|
||||
return iter(ast.InternedTerm(strings.NewReplacer(oldnewArr...).Replace(string(s))))
|
||||
}
|
||||
|
||||
func builtinTrim(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
@@ -551,7 +598,7 @@ func builtinTrim(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) er
|
||||
return iter(operands[0])
|
||||
}
|
||||
|
||||
return iter(ast.InternedStringTerm(strings.Trim(string(s), string(c))))
|
||||
return iter(ast.InternedTerm(strings.Trim(string(s), string(c))))
|
||||
}
|
||||
|
||||
func builtinTrimLeft(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
@@ -570,7 +617,7 @@ func builtinTrimLeft(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term
|
||||
return iter(operands[0])
|
||||
}
|
||||
|
||||
return iter(ast.InternedStringTerm(trimmed))
|
||||
return iter(ast.InternedTerm(trimmed))
|
||||
}
|
||||
|
||||
func builtinTrimPrefix(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
@@ -589,7 +636,7 @@ func builtinTrimPrefix(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Te
|
||||
return iter(operands[0])
|
||||
}
|
||||
|
||||
return iter(ast.InternedStringTerm(trimmed))
|
||||
return iter(ast.InternedTerm(trimmed))
|
||||
}
|
||||
|
||||
func builtinTrimRight(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
@@ -608,7 +655,7 @@ func builtinTrimRight(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Ter
|
||||
return iter(operands[0])
|
||||
}
|
||||
|
||||
return iter(ast.InternedStringTerm(trimmed))
|
||||
return iter(ast.InternedTerm(trimmed))
|
||||
}
|
||||
|
||||
func builtinTrimSuffix(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
@@ -627,7 +674,7 @@ func builtinTrimSuffix(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Te
|
||||
return iter(operands[0])
|
||||
}
|
||||
|
||||
return iter(ast.InternedStringTerm(trimmed))
|
||||
return iter(ast.InternedTerm(trimmed))
|
||||
}
|
||||
|
||||
func builtinTrimSpace(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
@@ -641,7 +688,7 @@ func builtinTrimSpace(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Ter
|
||||
return iter(operands[0])
|
||||
}
|
||||
|
||||
return iter(ast.InternedStringTerm(trimmed))
|
||||
return iter(ast.InternedTerm(trimmed))
|
||||
}
|
||||
|
||||
func builtinSprintf(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
@@ -689,7 +736,7 @@ func builtinSprintf(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term)
|
||||
}
|
||||
}
|
||||
|
||||
return iter(ast.InternedStringTerm(fmt.Sprintf(string(s), args...)))
|
||||
return iter(ast.InternedTerm(fmt.Sprintf(string(s), args...)))
|
||||
}
|
||||
|
||||
func builtinReverse(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
@@ -698,7 +745,7 @@ func builtinReverse(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term)
|
||||
return err
|
||||
}
|
||||
|
||||
return iter(ast.InternedStringTerm(reverseString(string(s))))
|
||||
return iter(ast.InternedTerm(reverseString(string(s))))
|
||||
}
|
||||
|
||||
func reverseString(str string) string {
|
||||
|
||||
+4
-4
@@ -216,22 +216,22 @@ func builtinObjectSubset(_ BuiltinContext, operands []*ast.Term, iter func(*ast.
|
||||
|
||||
if ok, superObj, subObj := bothObjects(superTerm, subTerm); ok {
|
||||
// Both operands are objects.
|
||||
return iter(ast.InternedBooleanTerm(objectSubset(superObj, subObj)))
|
||||
return iter(ast.InternedTerm(objectSubset(superObj, subObj)))
|
||||
}
|
||||
|
||||
if ok, superSet, subSet := bothSets(superTerm, subTerm); ok {
|
||||
// Both operands are sets.
|
||||
return iter(ast.InternedBooleanTerm(setSubset(superSet, subSet)))
|
||||
return iter(ast.InternedTerm(setSubset(superSet, subSet)))
|
||||
}
|
||||
|
||||
if ok, superArray, subArray := bothArrays(superTerm, subTerm); ok {
|
||||
// Both operands are sets.
|
||||
return iter(ast.InternedBooleanTerm(arraySubset(superArray, subArray)))
|
||||
return iter(ast.InternedTerm(arraySubset(superArray, subArray)))
|
||||
}
|
||||
|
||||
if ok, superArray, subSet := arraySet(superTerm, subTerm); ok {
|
||||
// Super operand is array and sub operand is set
|
||||
return iter(ast.InternedBooleanTerm(arraySetSubset(superArray, subSet)))
|
||||
return iter(ast.InternedTerm(arraySetSubset(superArray, subSet)))
|
||||
}
|
||||
|
||||
return builtins.ErrOperand("both arguments object.subset must be of the same type or array and set")
|
||||
|
||||
+4
-4
@@ -128,7 +128,7 @@ func builtinDate(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) er
|
||||
}
|
||||
year, month, day := t.Date()
|
||||
|
||||
return iter(ast.ArrayTerm(ast.InternedIntNumberTerm(year), ast.InternedIntNumberTerm(int(month)), ast.InternedIntNumberTerm(day)))
|
||||
return iter(ast.ArrayTerm(ast.InternedTerm(year), ast.InternedTerm(int(month)), ast.InternedTerm(day)))
|
||||
}
|
||||
|
||||
func builtinClock(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
@@ -137,7 +137,7 @@ func builtinClock(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) e
|
||||
return err
|
||||
}
|
||||
hour, minute, second := t.Clock()
|
||||
result := ast.NewArray(ast.InternedIntNumberTerm(hour), ast.InternedIntNumberTerm(minute), ast.InternedIntNumberTerm(second))
|
||||
result := ast.NewArray(ast.InternedTerm(hour), ast.InternedTerm(minute), ast.InternedTerm(second))
|
||||
return iter(ast.NewTerm(result))
|
||||
}
|
||||
|
||||
@@ -238,8 +238,8 @@ func builtinDiff(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) er
|
||||
}
|
||||
// END REDISTRIBUTION FROM APACHE 2.0 LICENSED PROJECT
|
||||
|
||||
return iter(ast.ArrayTerm(ast.InternedIntNumberTerm(year), ast.InternedIntNumberTerm(month), ast.InternedIntNumberTerm(day),
|
||||
ast.InternedIntNumberTerm(hour), ast.InternedIntNumberTerm(min), ast.InternedIntNumberTerm(sec)))
|
||||
return iter(ast.ArrayTerm(ast.InternedTerm(year), ast.InternedTerm(month), ast.InternedTerm(day),
|
||||
ast.InternedTerm(hour), ast.InternedTerm(min), ast.InternedTerm(sec)))
|
||||
}
|
||||
|
||||
func tzTime(a ast.Value) (t time.Time, lay string, err error) {
|
||||
|
||||
+21
-21
@@ -75,7 +75,7 @@ func builtinJWTDecode(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Ter
|
||||
return fmt.Errorf("JWT payload had invalid encoding: %v", err)
|
||||
}
|
||||
|
||||
if cty := token.decodedHeader.Get(ast.InternedStringTerm("cty")); cty != nil {
|
||||
if cty := token.decodedHeader.Get(ast.InternedTerm("cty")); cty != nil {
|
||||
ctyVal := string(cty.Value.(ast.String))
|
||||
// It is possible for the contents of a token to be another
|
||||
// token as a result of nested signing or encryption. To handle
|
||||
@@ -128,7 +128,7 @@ func builtinJWTVerifyRS256(bctx BuiltinContext, operands []*ast.Term, iter func(
|
||||
signature)
|
||||
})
|
||||
if err == nil {
|
||||
return iter(ast.InternedBooleanTerm(result))
|
||||
return iter(ast.InternedTerm(result))
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -143,7 +143,7 @@ func builtinJWTVerifyRS384(bctx BuiltinContext, operands []*ast.Term, iter func(
|
||||
signature)
|
||||
})
|
||||
if err == nil {
|
||||
return iter(ast.InternedBooleanTerm(result))
|
||||
return iter(ast.InternedTerm(result))
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -158,7 +158,7 @@ func builtinJWTVerifyRS512(bctx BuiltinContext, operands []*ast.Term, iter func(
|
||||
signature)
|
||||
})
|
||||
if err == nil {
|
||||
return iter(ast.InternedBooleanTerm(result))
|
||||
return iter(ast.InternedTerm(result))
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -174,7 +174,7 @@ func builtinJWTVerifyPS256(bctx BuiltinContext, operands []*ast.Term, iter func(
|
||||
nil)
|
||||
})
|
||||
if err == nil {
|
||||
return iter(ast.InternedBooleanTerm(result))
|
||||
return iter(ast.InternedTerm(result))
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -190,7 +190,7 @@ func builtinJWTVerifyPS384(bctx BuiltinContext, operands []*ast.Term, iter func(
|
||||
nil)
|
||||
})
|
||||
if err == nil {
|
||||
return iter(ast.InternedBooleanTerm(result))
|
||||
return iter(ast.InternedTerm(result))
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -206,7 +206,7 @@ func builtinJWTVerifyPS512(bctx BuiltinContext, operands []*ast.Term, iter func(
|
||||
nil)
|
||||
})
|
||||
if err == nil {
|
||||
return iter(ast.InternedBooleanTerm(result))
|
||||
return iter(ast.InternedTerm(result))
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -226,7 +226,7 @@ func builtinJWTVerifyRSA(bctx BuiltinContext, jwt ast.Value, keyStr ast.Value, h
|
||||
func builtinJWTVerifyES256(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
result, err := builtinJWTVerify(bctx, operands[0].Value, operands[1].Value, sha256.New, verifyES)
|
||||
if err == nil {
|
||||
return iter(ast.InternedBooleanTerm(result))
|
||||
return iter(ast.InternedTerm(result))
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -235,7 +235,7 @@ func builtinJWTVerifyES256(bctx BuiltinContext, operands []*ast.Term, iter func(
|
||||
func builtinJWTVerifyES384(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
result, err := builtinJWTVerify(bctx, operands[0].Value, operands[1].Value, sha512.New384, verifyES)
|
||||
if err == nil {
|
||||
return iter(ast.InternedBooleanTerm(result))
|
||||
return iter(ast.InternedTerm(result))
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -244,7 +244,7 @@ func builtinJWTVerifyES384(bctx BuiltinContext, operands []*ast.Term, iter func(
|
||||
func builtinJWTVerifyES512(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
result, err := builtinJWTVerify(bctx, operands[0].Value, operands[1].Value, sha512.New, verifyES)
|
||||
if err == nil {
|
||||
return iter(ast.InternedBooleanTerm(result))
|
||||
return iter(ast.InternedTerm(result))
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -439,7 +439,7 @@ func builtinJWTVerifyHS(bctx BuiltinContext, operands []*ast.Term, hashF func()
|
||||
}
|
||||
|
||||
if found, _, _, valid := getTokenFromCache(bctx, jwt, astSecret); found {
|
||||
return iter(ast.InternedBooleanTerm(valid))
|
||||
return iter(ast.InternedTerm(valid))
|
||||
}
|
||||
|
||||
// Decode the JSON Web Token
|
||||
@@ -465,7 +465,7 @@ func builtinJWTVerifyHS(bctx BuiltinContext, operands []*ast.Term, hashF func()
|
||||
|
||||
putTokenInCache(bctx, jwt, astSecret, nil, nil, valid)
|
||||
|
||||
return iter(ast.InternedBooleanTerm(valid))
|
||||
return iter(ast.InternedTerm(valid))
|
||||
}
|
||||
|
||||
// -- Full JWT verification and decoding --
|
||||
@@ -993,7 +993,7 @@ func builtinJWTDecodeVerify(bctx BuiltinContext, operands []*ast.Term, iter func
|
||||
}
|
||||
|
||||
unverified := ast.ArrayTerm(
|
||||
ast.InternedBooleanTerm(false),
|
||||
ast.InternedTerm(false),
|
||||
ast.InternedEmptyObject,
|
||||
ast.InternedEmptyObject,
|
||||
)
|
||||
@@ -1010,8 +1010,8 @@ func builtinJWTDecodeVerify(bctx BuiltinContext, operands []*ast.Term, iter func
|
||||
|
||||
// FIXME: optimize
|
||||
k, _ := b.Filter(ast.NewObject(
|
||||
ast.Item(ast.InternedStringTerm("secret"), ast.InternedEmptyObject),
|
||||
ast.Item(ast.InternedStringTerm("cert"), ast.InternedEmptyObject),
|
||||
ast.Item(ast.InternedTerm("secret"), ast.InternedEmptyObject),
|
||||
ast.Item(ast.InternedTerm("cert"), ast.InternedEmptyObject),
|
||||
))
|
||||
|
||||
if found, th, tp, validSignature := getTokenFromCache(bctx, a, k); found {
|
||||
@@ -1117,7 +1117,7 @@ func builtinJWTDecodeVerify(bctx BuiltinContext, operands []*ast.Term, iter func
|
||||
// Check registered claim names against constraints or environment
|
||||
// RFC7159 4.1.1 iss
|
||||
if constraints.iss != "" {
|
||||
if iss := payload.Get(ast.InternedStringTerm("iss")); iss != nil {
|
||||
if iss := payload.Get(ast.InternedTerm("iss")); iss != nil {
|
||||
issVal := string(iss.Value.(ast.String))
|
||||
if constraints.iss != issVal {
|
||||
return iter(unverified)
|
||||
@@ -1127,7 +1127,7 @@ func builtinJWTDecodeVerify(bctx BuiltinContext, operands []*ast.Term, iter func
|
||||
}
|
||||
}
|
||||
// RFC7159 4.1.3 aud
|
||||
if aud := payload.Get(ast.InternedStringTerm("aud")); aud != nil {
|
||||
if aud := payload.Get(ast.InternedTerm("aud")); aud != nil {
|
||||
if !constraints.validAudience(aud.Value) {
|
||||
return iter(unverified)
|
||||
}
|
||||
@@ -1137,7 +1137,7 @@ func builtinJWTDecodeVerify(bctx BuiltinContext, operands []*ast.Term, iter func
|
||||
}
|
||||
}
|
||||
// RFC7159 4.1.4 exp
|
||||
if exp := payload.Get(ast.InternedStringTerm("exp")); exp != nil {
|
||||
if exp := payload.Get(ast.InternedTerm("exp")); exp != nil {
|
||||
switch v := exp.Value.(type) {
|
||||
case ast.Number:
|
||||
// constraints.time is in nanoseconds but exp Value is in seconds
|
||||
@@ -1150,7 +1150,7 @@ func builtinJWTDecodeVerify(bctx BuiltinContext, operands []*ast.Term, iter func
|
||||
}
|
||||
}
|
||||
// RFC7159 4.1.5 nbf
|
||||
if nbf := payload.Get(ast.InternedStringTerm("nbf")); nbf != nil {
|
||||
if nbf := payload.Get(ast.InternedTerm("nbf")); nbf != nil {
|
||||
switch v := nbf.Value.(type) {
|
||||
case ast.Number:
|
||||
// constraints.time is in nanoseconds but nbf Value is in seconds
|
||||
@@ -1164,7 +1164,7 @@ func builtinJWTDecodeVerify(bctx BuiltinContext, operands []*ast.Term, iter func
|
||||
}
|
||||
|
||||
verified := ast.ArrayTerm(
|
||||
ast.InternedBooleanTerm(true),
|
||||
ast.InternedTerm(true),
|
||||
ast.NewTerm(header),
|
||||
ast.NewTerm(payload),
|
||||
)
|
||||
@@ -1218,7 +1218,7 @@ func validateJWTHeader(h string) (ast.Object, error) {
|
||||
// won't support it for now.
|
||||
// This code checks which kind of JWT we are dealing with according to
|
||||
// RFC 7516 Section 9: https://tools.ietf.org/html/rfc7516#section-9
|
||||
if header.Get(ast.InternedStringTerm("enc")) != nil {
|
||||
if header.Get(ast.InternedTerm("enc")) != nil {
|
||||
return nil, errors.New("JWT is a JWE object, which is not supported")
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -533,7 +533,7 @@ func builtinTrace(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term
|
||||
}
|
||||
|
||||
if !bctx.TraceEnabled {
|
||||
return iter(ast.InternedBooleanTerm(true))
|
||||
return iter(ast.InternedTerm(true))
|
||||
}
|
||||
|
||||
evt := Event{
|
||||
@@ -548,7 +548,7 @@ func builtinTrace(bctx BuiltinContext, operands []*ast.Term, iter func(*ast.Term
|
||||
bctx.QueryTracers[i].TraceEvent(evt)
|
||||
}
|
||||
|
||||
return iter(ast.InternedBooleanTerm(true))
|
||||
return iter(ast.InternedTerm(true))
|
||||
}
|
||||
|
||||
func rewrite(event *Event) *Event {
|
||||
|
||||
+14
-14
@@ -11,63 +11,63 @@ import (
|
||||
func builtinIsNumber(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
switch operands[0].Value.(type) {
|
||||
case ast.Number:
|
||||
return iter(ast.InternedBooleanTerm(true))
|
||||
return iter(ast.InternedTerm(true))
|
||||
default:
|
||||
return iter(ast.InternedBooleanTerm(false))
|
||||
return iter(ast.InternedTerm(false))
|
||||
}
|
||||
}
|
||||
|
||||
func builtinIsString(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
switch operands[0].Value.(type) {
|
||||
case ast.String:
|
||||
return iter(ast.InternedBooleanTerm(true))
|
||||
return iter(ast.InternedTerm(true))
|
||||
default:
|
||||
return iter(ast.InternedBooleanTerm(false))
|
||||
return iter(ast.InternedTerm(false))
|
||||
}
|
||||
}
|
||||
|
||||
func builtinIsBoolean(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
switch operands[0].Value.(type) {
|
||||
case ast.Boolean:
|
||||
return iter(ast.InternedBooleanTerm(true))
|
||||
return iter(ast.InternedTerm(true))
|
||||
default:
|
||||
return iter(ast.InternedBooleanTerm(false))
|
||||
return iter(ast.InternedTerm(false))
|
||||
}
|
||||
}
|
||||
|
||||
func builtinIsArray(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
switch operands[0].Value.(type) {
|
||||
case *ast.Array:
|
||||
return iter(ast.InternedBooleanTerm(true))
|
||||
return iter(ast.InternedTerm(true))
|
||||
default:
|
||||
return iter(ast.InternedBooleanTerm(false))
|
||||
return iter(ast.InternedTerm(false))
|
||||
}
|
||||
}
|
||||
|
||||
func builtinIsSet(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
switch operands[0].Value.(type) {
|
||||
case ast.Set:
|
||||
return iter(ast.InternedBooleanTerm(true))
|
||||
return iter(ast.InternedTerm(true))
|
||||
default:
|
||||
return iter(ast.InternedBooleanTerm(false))
|
||||
return iter(ast.InternedTerm(false))
|
||||
}
|
||||
}
|
||||
|
||||
func builtinIsObject(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
switch operands[0].Value.(type) {
|
||||
case ast.Object:
|
||||
return iter(ast.InternedBooleanTerm(true))
|
||||
return iter(ast.InternedTerm(true))
|
||||
default:
|
||||
return iter(ast.InternedBooleanTerm(false))
|
||||
return iter(ast.InternedTerm(false))
|
||||
}
|
||||
}
|
||||
|
||||
func builtinIsNull(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
switch operands[0].Value.(type) {
|
||||
case ast.Null:
|
||||
return iter(ast.InternedBooleanTerm(true))
|
||||
return iter(ast.InternedTerm(true))
|
||||
default:
|
||||
return iter(ast.InternedBooleanTerm(false))
|
||||
return iter(ast.InternedTerm(false))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+7
-7
@@ -13,19 +13,19 @@ import (
|
||||
func builtinTypeName(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
switch operands[0].Value.(type) {
|
||||
case ast.Null:
|
||||
return iter(ast.InternedStringTerm("null"))
|
||||
return iter(ast.InternedTerm("null"))
|
||||
case ast.Boolean:
|
||||
return iter(ast.InternedStringTerm("boolean"))
|
||||
return iter(ast.InternedTerm("boolean"))
|
||||
case ast.Number:
|
||||
return iter(ast.InternedStringTerm("number"))
|
||||
return iter(ast.InternedTerm("number"))
|
||||
case ast.String:
|
||||
return iter(ast.InternedStringTerm("string"))
|
||||
return iter(ast.InternedTerm("string"))
|
||||
case *ast.Array:
|
||||
return iter(ast.InternedStringTerm("array"))
|
||||
return iter(ast.InternedTerm("array"))
|
||||
case ast.Object:
|
||||
return iter(ast.InternedStringTerm("object"))
|
||||
return iter(ast.InternedTerm("object"))
|
||||
case ast.Set:
|
||||
return iter(ast.InternedStringTerm("set"))
|
||||
return iter(ast.InternedTerm("set"))
|
||||
}
|
||||
|
||||
return errors.New("illegal value")
|
||||
|
||||
+2
-2
@@ -57,7 +57,7 @@ func walk(filter, path *ast.Array, input *ast.Term, iter func(*ast.Term) error)
|
||||
switch v := input.Value.(type) {
|
||||
case *ast.Array:
|
||||
for i := range v.Len() {
|
||||
if err := walk(filter, pathAppend(path, ast.InternedIntNumberTerm(i)), v.Elem(i), iter); err != nil {
|
||||
if err := walk(filter, pathAppend(path, ast.InternedTerm(i)), v.Elem(i), iter); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -89,7 +89,7 @@ func walkNoPath(input *ast.Term, iter func(*ast.Term) error) error {
|
||||
}
|
||||
|
||||
inputArray := input.Value.(*ast.Array)
|
||||
value := inputArray.Get(ast.InternedIntNumberTerm(1)).Value
|
||||
value := inputArray.Get(ast.InternedTerm(1)).Value
|
||||
|
||||
switch v := value.(type) {
|
||||
case ast.Object:
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ import (
|
||||
"runtime/debug"
|
||||
)
|
||||
|
||||
var Version = "1.5.1"
|
||||
var Version = "1.6.0"
|
||||
|
||||
// GoVersion is the version of Go this was built with
|
||||
var GoVersion = runtime.Version()
|
||||
|
||||
+9
@@ -164,6 +164,15 @@ func ErrorPathf(path ast.Path, message string, args ...interface{}) *Error {
|
||||
}
|
||||
|
||||
func ErrorPosf(pos *ast.Position, message string, args ...interface{}) *Error {
|
||||
if pos == nil {
|
||||
return ErrorLocf(
|
||||
"",
|
||||
-1,
|
||||
-1,
|
||||
message,
|
||||
args...,
|
||||
)
|
||||
}
|
||||
return ErrorLocf(
|
||||
pos.Src.Name,
|
||||
pos.Line,
|
||||
|
||||
+1
-2
@@ -1,7 +1,6 @@
|
||||
package parser
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/vektah/gqlparser/v2/ast"
|
||||
@@ -106,7 +105,7 @@ func (p *parser) next() lexer.Token {
|
||||
// Increment the token count before reading the next token
|
||||
p.tokenCount++
|
||||
if p.maxTokenLimit != 0 && p.tokenCount > p.maxTokenLimit {
|
||||
p.err = fmt.Errorf("exceeded token limit of %d", p.maxTokenLimit)
|
||||
p.err = gqlerror.Errorf("exceeded token limit of %d", p.maxTokenLimit)
|
||||
return p.prev
|
||||
}
|
||||
if p.peeked {
|
||||
|
||||
Vendored
+2
-2
@@ -1114,7 +1114,7 @@ github.com/onsi/gomega/matchers/support/goraph/edge
|
||||
github.com/onsi/gomega/matchers/support/goraph/node
|
||||
github.com/onsi/gomega/matchers/support/goraph/util
|
||||
github.com/onsi/gomega/types
|
||||
# github.com/open-policy-agent/opa v1.5.1
|
||||
# github.com/open-policy-agent/opa v1.6.0
|
||||
## explicit; go 1.23.8
|
||||
github.com/open-policy-agent/opa/ast
|
||||
github.com/open-policy-agent/opa/ast/json
|
||||
@@ -1889,7 +1889,7 @@ github.com/unrolled/secure/cspbuilder
|
||||
# github.com/urfave/cli/v2 v2.27.7
|
||||
## explicit; go 1.18
|
||||
github.com/urfave/cli/v2
|
||||
# github.com/vektah/gqlparser/v2 v2.5.26
|
||||
# github.com/vektah/gqlparser/v2 v2.5.28
|
||||
## explicit; go 1.22
|
||||
github.com/vektah/gqlparser/v2/ast
|
||||
github.com/vektah/gqlparser/v2/gqlerror
|
||||
|
||||
Reference in New Issue
Block a user