Skip to content

Commit

Permalink
topdown: fix panic in partial eval with ref head rule
Browse files Browse the repository at this point in the history
Fixes open-policy-agent#6027.

Signed-off-by: Stephan Renatus <stephan@styra.com>
  • Loading branch information
srenatus committed Jun 19, 2023
1 parent 304be03 commit 8e7a9fa
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 1 deletion.
6 changes: 5 additions & 1 deletion topdown/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -2503,6 +2503,10 @@ func (e evalVirtualPartial) evalOneRulePreUnify(iter unifyIterator, rule *ast.Ru
}

func (e evalVirtualPartial) evalOneRulePostUnify(iter unifyIterator, rule *ast.Rule) error {
headKey := rule.Head.Key
if headKey == nil {
headKey = rule.Head.Reference[len(rule.Head.Reference)-1]
}

key := e.ref[e.pos+1]
child := e.e.child(rule.Body)
Expand All @@ -2512,7 +2516,7 @@ func (e evalVirtualPartial) evalOneRulePostUnify(iter unifyIterator, rule *ast.R

err := child.eval(func(child *eval) error {
defined = true
return e.e.biunify(rule.Head.Key, key, child.bindings, e.bindings, func() error {
return e.e.biunify(headKey, key, child.bindings, e.bindings, func() error {
return e.evalOneRuleContinue(iter, rule, child)
})
})
Expand Down
19 changes: 19 additions & 0 deletions topdown/topdown_partial_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3320,6 +3320,25 @@ func TestTopDownPartialEval(t *testing.T) {
}`},
wantQueries: []string{`every __local0__1, __local1__1 in input.ys { __local1__1 = input.foo }; x1 = input.foo`},
},
{ // https://github.com/open-policy-agent/opa/issues/6027
note: "ref heads: \"double\" unification, single-value rule",
query: "data.test.foo[input.a][input.b]",
modules: []string{`package test
foo.bar[baz] {
baz := "baz"
}`},
wantQueries: []string{`"bar" = input.a; "baz" = input.b`},
},
{ // https://github.com/open-policy-agent/opa/issues/6027
note: "ref heads: \"double\" unification, multi-value rule",
query: "data.test.foo[input.a][input.b]",
modules: []string{`package test
import future.keywords.contains
foo.bar contains baz {
baz := "baz"
}`},
wantQueries: []string{`"bar" = input.a; "baz" = input.b`},
},
}

ctx := context.Background()
Expand Down

0 comments on commit 8e7a9fa

Please sign in to comment.