From 8eee752541563925b099dd7b54f73d341d1e2178 Mon Sep 17 00:00:00 2001 From: Dave Shanley Date: Mon, 18 Jul 2022 18:21:44 -0400 Subject: [PATCH] Fixed a couple of bugs in the pattern function. After running existing configurations through, a couple of glitches appeared. Signed-off-by: Dave Shanley --- functions/core/pattern.go | 34 +++++++++++++++++----------------- functions/core/pattern_test.go | 18 +++++++++--------- rulesets/ruleset_functions.go | 4 +--- 3 files changed, 27 insertions(+), 29 deletions(-) diff --git a/functions/core/pattern.go b/functions/core/pattern.go index b8b55135..a94cd3b5 100644 --- a/functions/core/pattern.go +++ b/functions/core/pattern.go @@ -73,10 +73,22 @@ func (p Pattern) RunRule(nodes []*yaml.Node, context model.RuleFunctionContext) nodes = nodes[0].Content } + var currentField string for x, node := range nodes { if utils.IsNodeMap(node) { continue } + if x%2 == 0 { + + currentField = node.Value + if context.RuleAction.Field != "" { + continue + } + + } + if context.RuleAction.Field != "" && currentField != context.RuleAction.Field { + continue // not what we're looking for. + } if p.match != "" { rx, err := p.getPatternFromCache(p.match, context.Rule) if err != nil { @@ -89,26 +101,14 @@ func (p Pattern) RunRule(nodes []*yaml.Node, context model.RuleFunctionContext) Rule: context.Rule, }) } else { - - // if a field is supplied, use that, if not then use the raw node value. - matchValue := node.Value - if context.RuleAction.Field != "" && x+1 <= len(nodes) { - if x < len(nodes)-1 { - _, fieldValue := utils.FindKeyNode(context.RuleAction.Field, nodes[x+1].Content) - if fieldValue != nil { - matchValue = fieldValue.Value - pathValue = fmt.Sprintf("%s.%s", pathValue, context.RuleAction.Field) - } - } - } - - if !rx.MatchString(matchValue) { + pathValue = fmt.Sprintf("%s.%s", pathValue, currentField) + if !rx.MatchString(node.Value) { results = append(results, model.RuleFunctionResult{ Message: fmt.Sprintf("%s: '%s' does not match the expression '%s'", context.Rule.Description, - matchValue, p.match), + node.Value, p.match), StartNode: node, EndNode: node, - Path: utils.BuildPath(pathValue, []string{node.Value}), + Path: pathValue, Rule: context.Rule, }) } @@ -133,7 +133,7 @@ func (p Pattern) RunRule(nodes []*yaml.Node, context model.RuleFunctionContext) Message: fmt.Sprintf("%s: matches the expression '%s'", context.Rule.Description, p.notMatch), StartNode: node, EndNode: node, - Path: utils.BuildPath(pathValue, []string{node.Value}), + Path: pathValue, Rule: context.Rule, }) } diff --git a/functions/core/pattern_test.go b/functions/core/pattern_test.go index 77dae42d..129fed18 100644 --- a/functions/core/pattern_test.go +++ b/functions/core/pattern_test.go @@ -60,14 +60,14 @@ func TestPattern_RunRule_PatternNothingSupplied(t *testing.T) { func TestPattern_RunRule_PatternNotMatchError(t *testing.T) { sampleYaml := `carpet: "nice-rice"` - path := "$.carpet" + path := "$" nodes, _ := utils.FindNodes([]byte(sampleYaml), path) assert.Len(t, nodes, 1) opts := make(map[string]string) opts["notMatch"] = "[[abc)" - rule := buildCoreTestRule(path, severityError, "pattern", "", opts) + rule := buildCoreTestRule(path, severityError, "pattern", "carpet", opts) ctx := buildCoreTestContextFromRule(model.CastToRuleAction(rule.Then), rule) ctx.Given = path ctx.Rule = &rule @@ -81,14 +81,14 @@ func TestPattern_RunRule_PatternNotMatchError(t *testing.T) { func TestPattern_RunRule_PatternMatchFail(t *testing.T) { sampleYaml := `carpet: "def"` - path := "$.carpet" + path := "$" nodes, _ := utils.FindNodes([]byte(sampleYaml), path) assert.Len(t, nodes, 1) opts := make(map[string]string) opts["match"] = "[abc]+" - rule := buildCoreTestRule(path, severityError, "pattern", "", opts) + rule := buildCoreTestRule(path, severityError, "pattern", "carpet", opts) ctx := buildCoreTestContextFromRule(model.CastToRuleAction(rule.Then), rule) ctx.Given = path ctx.Rule = &rule @@ -102,14 +102,14 @@ func TestPattern_RunRule_PatternMatchFail(t *testing.T) { func TestPattern_RunRule_PatternMatchError(t *testing.T) { sampleYaml := `carpet: "abc"` - path := "$.carpet" + path := "$" nodes, _ := utils.FindNodes([]byte(sampleYaml), path) assert.Len(t, nodes, 1) opts := make(map[string]string) opts["match"] = "([abc]" - rule := buildCoreTestRule(path, severityError, "pattern", "", opts) + rule := buildCoreTestRule(path, severityError, "pattern", "carpet", opts) ctx := buildCoreTestContextFromRule(model.CastToRuleAction(rule.Then), rule) ctx.Given = path ctx.Rule = &rule @@ -123,14 +123,14 @@ func TestPattern_RunRule_PatternMatchError(t *testing.T) { func TestPattern_RunRule_PatternNotMatchFail(t *testing.T) { sampleYaml := `pizza: "cat1"` - path := "$.pizza" + path := "$" nodes, _ := utils.FindNodes([]byte(sampleYaml), path) assert.Len(t, nodes, 1) opts := make(map[string]string) opts["notMatch"] = `\w{3}\d` - rule := buildCoreTestRule(path, severityError, "pattern", "", opts) + rule := buildCoreTestRule(path, severityError, "pattern", "pizza", opts) ctx := buildCoreTestContextFromRule(model.CastToRuleAction(rule.Then), rule) ctx.Given = path ctx.Rule = &rule @@ -160,7 +160,7 @@ func TestPattern_RunRule_UseFieldName(t *testing.T) { def := &Pattern{} res := def.RunRule(nodes, ctx) - assert.Len(t, res, 2) + assert.Len(t, res, 1) } func TestPattern_RunRule_ContainMap(t *testing.T) { diff --git a/rulesets/ruleset_functions.go b/rulesets/ruleset_functions.go index 6abfa2f4..2cdb1f55 100644 --- a/rulesets/ruleset_functions.go +++ b/rulesets/ruleset_functions.go @@ -305,7 +305,6 @@ func GetOAS2HostNotExampleRule() *model.Rule { Type: style, Severity: warn, Then: model.RuleAction{ - Field: "host", Function: "pattern", FunctionOptions: opts, }, @@ -357,7 +356,6 @@ func GetOAS2HostTrailingSlashRule() *model.Rule { Type: style, Severity: warn, Then: model.RuleAction{ - Field: "host", Function: "pattern", FunctionOptions: opts, }, @@ -528,7 +526,7 @@ func GetOperationIdValidInUrlRule() *model.Rule { Id: operationOperationIdValidInUrl, Formats: model.AllFormats, Description: "OperationId must use URL friendly characters", - Given: AllOperationsPath, + Given: "$.paths[*][*]", Resolved: true, RuleCategory: model.RuleCategories[model.CategoryOperations], Recommended: true,