update dependencies (#6267)

Signed-off-by: hongming <coder.scala@gmail.com>
This commit is contained in:
hongming
2024-11-06 10:27:06 +08:00
committed by GitHub
parent faf255a084
commit cfebd96a1f
4263 changed files with 341374 additions and 132036 deletions

View File

@@ -17,7 +17,7 @@ import (
"strings"
"unicode/utf8"
"gopkg.in/yaml.v2"
"gopkg.in/yaml.v3"
"github.com/open-policy-agent/opa/ast/internal/scanner"
"github.com/open-policy-agent/opa/ast/internal/tokens"
@@ -30,6 +30,8 @@ var RegoV1CompatibleRef = Ref{VarTerm("rego"), StringTerm("v1")}
// RegoVersion defines the Rego syntax requirements for a module.
type RegoVersion int
const DefaultRegoVersion = RegoVersion(0)
const (
// RegoV0 is the default, original Rego syntax.
RegoV0 RegoVersion = iota
@@ -43,6 +45,33 @@ const (
RegoV1
)
func (v RegoVersion) Int() int {
if v == RegoV1 {
return 1
}
return 0
}
func (v RegoVersion) String() string {
switch v {
case RegoV0:
return "v0"
case RegoV1:
return "v1"
case RegoV0CompatV1:
return "v0v1"
default:
return "unknown"
}
}
func RegoVersionFromInt(i int) RegoVersion {
if i == 1 {
return RegoV1
}
return RegoV0
}
// Note: This state is kept isolated from the parser so that we
// can do efficient shallow copies of these values when doing a
// save() and restore().
@@ -290,6 +319,31 @@ func (p *Parser) Parse() ([]Statement, []*Comment, Errors) {
for k, v := range futureKeywords {
allowedFutureKeywords[k] = v
}
// For sake of error reporting, we still need to check that keywords in capabilities are known,
for _, kw := range p.po.Capabilities.FutureKeywords {
if _, ok := futureKeywords[kw]; !ok {
return nil, nil, Errors{
&Error{
Code: ParseErr,
Message: fmt.Sprintf("illegal capabilities: unknown keyword: %v", kw),
Location: nil,
},
}
}
}
// and that explicitly requested future keywords are known.
for _, kw := range p.po.FutureKeywords {
if _, ok := allowedFutureKeywords[kw]; !ok {
return nil, nil, Errors{
&Error{
Code: ParseErr,
Message: fmt.Sprintf("unknown future keyword: %v", kw),
Location: nil,
},
}
}
}
} else {
for _, kw := range p.po.Capabilities.FutureKeywords {
var ok bool
@@ -582,7 +636,12 @@ func (p *Parser) parseImport() *Import {
path := imp.Path.Value.(Ref)
if !RootDocumentNames.Contains(path[0]) && !FutureRootDocument.Equal(path[0]) && !RegoRootDocument.Equal(path[0]) {
switch {
case RootDocumentNames.Contains(path[0]):
case FutureRootDocument.Equal(path[0]):
case RegoRootDocument.Equal(path[0]):
default:
p.hint("if this is unexpected, try updating OPA")
p.errorf(imp.Path.Location, "unexpected import path, must begin with one of: %v, got: %v",
RootDocumentNames.Union(NewSet(FutureRootDocument, RegoRootDocument)),
path[0])
@@ -654,6 +713,10 @@ func (p *Parser) parseRules() []*Rule {
// p[x] if ... becomes a single-value rule p[x]
if hasIf && !usesContains && len(rule.Head.Ref()) == 2 {
if !rule.Head.Ref()[1].IsGround() && len(rule.Head.Args) == 0 {
rule.Head.Key = rule.Head.Ref()[1]
}
if rule.Head.Value == nil {
rule.Head.generatedValue = true
rule.Head.Value = BooleanTerm(true).SetLocation(rule.Head.Location)
@@ -717,6 +780,8 @@ func (p *Parser) parseRules() []*Rule {
case usesContains:
rule.Body = NewBody(NewExpr(BooleanTerm(true).SetLocation(rule.Location)).SetLocation(rule.Location))
rule.generatedBody = true
rule.Location = rule.Head.Location
return []*Rule{&rule}
default:
@@ -929,12 +994,10 @@ func (p *Parser) parseHead(defaultRule bool) (*Head, bool) {
p.illegal("expected rule value term (e.g., %s[%s] = <VALUE> { ... })", name, head.Key)
}
case tokens.Assign:
s := p.save()
p.scan()
head.Assign = true
head.Value = p.parseTermInfixCall()
if head.Value == nil {
p.restore(s)
switch {
case len(head.Args) > 0:
p.illegal("expected function value term (e.g., %s(...) := <VALUE> { ... })", name)
@@ -2118,6 +2181,7 @@ func (p *Parser) doScan(skipws bool) {
p.s.loc.Col = pos.Col
p.s.loc.Offset = pos.Offset
p.s.loc.Text = p.s.Text(pos.Offset, pos.End)
p.s.loc.Tabs = pos.Tabs
for _, err := range errs {
p.error(p.s.Loc(), err.Message)
@@ -2247,12 +2311,10 @@ type rawAnnotation struct {
Organizations []string `yaml:"organizations"`
RelatedResources []interface{} `yaml:"related_resources"`
Authors []interface{} `yaml:"authors"`
Schemas []rawSchemaAnnotation `yaml:"schemas"`
Schemas []map[string]any `yaml:"schemas"`
Custom map[string]interface{} `yaml:"custom"`
}
type rawSchemaAnnotation map[string]interface{}
type metadataParser struct {
buf *bytes.Buffer
comments []*Comment
@@ -2283,9 +2345,8 @@ func (b *metadataParser) Parse() (*Annotations, error) {
var comment *Comment
match := yamlLineErrRegex.FindStringSubmatch(err.Error())
if len(match) == 2 {
n, err2 := strconv.Atoi(match[1])
index, err2 := strconv.Atoi(match[1])
if err2 == nil {
index := n - 1 // line numbering is 1-based so subtract one from row
if index >= len(b.comments) {
comment = b.comments[len(b.comments)-1]
} else {
@@ -2294,6 +2355,11 @@ func (b *metadataParser) Parse() (*Annotations, error) {
b.loc = comment.Location
}
}
if match == nil && len(b.comments) > 0 {
b.loc = b.comments[0].Location
}
return nil, augmentYamlError(err, b.comments)
}
@@ -2330,7 +2396,7 @@ func (b *metadataParser) Parse() (*Annotations, error) {
if err != nil {
return nil, err
}
case map[interface{}]interface{}:
case map[string]any:
w, err := convertYAMLMapKeyTypes(v, nil)
if err != nil {
return nil, fmt.Errorf("invalid schema definition: %w", err)
@@ -2361,11 +2427,27 @@ func (b *metadataParser) Parse() (*Annotations, error) {
}
result.Location = b.loc
// recreate original text of entire metadata block for location text attribute
sb := strings.Builder{}
sb.WriteString("# METADATA\n")
lines := bytes.Split(b.buf.Bytes(), []byte{'\n'})
for _, line := range lines[:len(lines)-1] {
sb.WriteString("# ")
sb.Write(line)
sb.WriteByte('\n')
}
result.Location.Text = []byte(strings.TrimSuffix(sb.String(), "\n"))
return &result, nil
}
// augmentYamlError augments a YAML error with hints intended to help the user figure out the cause of an otherwise cryptic error.
// These are hints, instead of proper errors, because they are educated guesses, and aren't guaranteed to be correct.
// augmentYamlError augments a YAML error with hints intended to help the user figure out the cause of an otherwise
// cryptic error. These are hints, instead of proper errors, because they are educated guesses, and aren't guaranteed
// to be correct.
func augmentYamlError(err error, comments []*Comment) error {
// Adding hints for when key/value ':' separator isn't suffixed with a legal YAML space symbol
for _, comment := range comments {
@@ -2398,10 +2480,11 @@ func augmentYamlError(err error, comments []*Comment) error {
return err
}
func unwrapPair(pair map[string]interface{}) (k string, v interface{}) {
for k, v = range pair {
func unwrapPair(pair map[string]interface{}) (string, interface{}) {
for k, v := range pair {
return k, v
}
return
return "", nil
}
var errInvalidSchemaRef = fmt.Errorf("invalid schema reference")
@@ -2518,11 +2601,11 @@ func parseAuthorString(s string) (*AuthorAnnotation, error) {
return &AuthorAnnotation{Name: name, Email: email}, nil
}
func convertYAMLMapKeyTypes(x interface{}, path []string) (interface{}, error) {
func convertYAMLMapKeyTypes(x any, path []string) (any, error) {
var err error
switch x := x.(type) {
case map[interface{}]interface{}:
result := make(map[string]interface{}, len(x))
case map[any]any:
result := make(map[string]any, len(x))
for k, v := range x {
str, ok := k.(string)
if !ok {
@@ -2534,7 +2617,7 @@ func convertYAMLMapKeyTypes(x interface{}, path []string) (interface{}, error) {
}
}
return result, nil
case []interface{}:
case []any:
for i := range x {
x[i], err = convertYAMLMapKeyTypes(x[i], append(path, fmt.Sprintf("%d", i)))
if err != nil {
@@ -2556,6 +2639,11 @@ var futureKeywords = map[string]tokens.Token{
"if": tokens.If,
}
func IsFutureKeyword(s string) bool {
_, ok := futureKeywords[s]
return ok
}
func (p *Parser) futureImport(imp *Import, allowedFutureKeywords map[string]tokens.Token) {
path := imp.Path.Value.(Ref)
@@ -2608,15 +2696,16 @@ func (p *Parser) regoV1Import(imp *Import) {
return
}
if p.po.RegoVersion == RegoV1 {
// We're parsing for Rego v1, where the 'rego.v1' import is a no-op.
path := imp.Path.Value.(Ref)
// v1 is only valid option
if len(path) == 1 || !path[1].Equal(RegoV1CompatibleRef[1]) || len(path) > 2 {
p.errorf(imp.Path.Location, "invalid import `%s`, must be `%s`", path, RegoV1CompatibleRef)
return
}
path := imp.Path.Value.(Ref)
if len(path) == 1 || !path[1].Equal(RegoV1CompatibleRef[1]) || len(path) > 2 {
p.errorf(imp.Path.Location, "invalid import, must be `%s`", RegoV1CompatibleRef)
if p.po.RegoVersion == RegoV1 {
// We're parsing for Rego v1, where the 'rego.v1' import is a no-op.
return
}