Skip to content

Commit

Permalink
internal/core/adt: fix possible infinte loop for API usage
Browse files Browse the repository at this point in the history
When a Vertex is used as a Conjunct directly and evaluated
as Partial, it was possible that an evaluation loop would
result in an infinite loop.

The solution is to ensure that there is always progress
for a given Vertex and Conjunct, even if there is an
evaluation cycle.

Fixes #2293

Signed-off-by: Marcel van Lohuizen <mpvl@gmail.com>
Change-Id: Ic52ccc31989c7305d257125dfd1dd944b37cdf4c
Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/551056
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
Unity-Result: CUEcueckoo <cueckoo@cuelang.org>
TryBot-Result: CUEcueckoo <cueckoo@cuelang.org>
  • Loading branch information
mpvl committed Mar 16, 2023
1 parent 9954cc2 commit 782cae0
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 1 deletion.
9 changes: 8 additions & 1 deletion internal/core/adt/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,9 @@ func (c *OpContext) Unify(v *Vertex, state VertexStatus) {
func (n *nodeContext) insertConjuncts(state VertexStatus) bool {
// Exit early if we have a concrete value and only need partial results.
if state == Partial {
for _, c := range n.conjuncts {
for n.conjunctsPos < len(n.conjuncts) {
c := n.conjuncts[n.conjunctsPos]
n.conjunctsPos++
if v, ok := c.Elem().(Value); ok && IsConcrete(v) {
n.addValueConjunct(c.Env, v, c.CloseInfo)
}
Expand Down Expand Up @@ -951,6 +953,11 @@ type nodeContext struct {
conjuncts []Conjunct
cyclicConjuncts []cyclicConjunct

// conjunctsPos is an index into conjuncts indicating the next conjunct
// to process. This is used to avoids processing a conjunct twice in some
// cases where there is an evaluation cycle.
conjunctsPos int

// notify is used to communicate errors in cyclic dependencies.
// TODO: also use this to communicate increasingly more concrete values.
notify []*Vertex
Expand Down
11 changes: 11 additions & 0 deletions internal/core/adt/eval_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,3 +155,14 @@ func BenchmarkUnifyAPI(b *testing.B) {
}
}
}

func TestIssue2293(t *testing.T) {
adt.Verbosity = 1

ctx := cuecontext.New()
c := `a: {}, a`
v1 := ctx.CompileString(c)
v2 := ctx.CompileString(c)

v1.Unify(v2)
}

0 comments on commit 782cae0

Please sign in to comment.