Skip to content

CompileString hangs on malformed input due to unbounded recursion in unify/completeAllArcs #4231

@pskry

Description

@pskry

What version of CUE are you using (cue version)?

Tested via Go API with cuelang.org/go v0.15.3, Go 1.25.6 darwin/arm64

Does this issue reproduce with the latest stable release?

Yes, confirmed on v0.15.3 (latest as of 2026-01-20).

What did you do?

This input was discovered via fuzzing a CUE-based configuration loader. The string A0:A&A,A:A0:A0:A,A causes CompileString to hang indefinitely.

Minimal reproducer:

package main

import (
      "fmt"
      "cuelang.org/go/cue/cuecontext"
)

func main() {
      input := "A0:A&A,A:A0:A0:A,A"
      ctx := cuecontext.New()
      v := ctx.CompileString(input)
      fmt.Printf("Result: %v, Err: %v\n", v, v.Err())
}

Option A: Build and run the binary (will eventually stack overflow):

go build -o repro . && ./repro

Option B: Build and run with Go test timeout to capture stack trace:

Wrap the reproducer as a test for the timeout to work:

package main

import (
      "testing"
      "cuelang.org/go/cue/cuecontext"
)

func TestRepro(t *testing.T) {
      input := "A0:A&A,A:A0:A0:A,A"
      ctx := cuecontext.New()
      v := ctx.CompileString(input)
      t.Logf("Result: %v, Err: %v", v, v.Err())
}

Then:

go test -run=TestRepro -timeout=3s

This produces the panic:
test timed out after 3s with the full stack trace showing the elided frames.

What did you expect to see?

A CUE compilation error indicating invalid/malformed CUE syntax, returned promptly.

What did you see instead?

The program hangs indefinitely. When forced to terminate with a timeout and stack dump, it reveals ~46,000 stack frames of mutual recursion between (*Vertex).unify and (*nodeContext).completeAllArcs in internal/core/adt.

Stack trace excerpt:
...45995 frames elided...
cuelang.org/go/internal/core/adt.(*Vertex).unify
    .../internal/core/adt/unify.go:334
cuelang.org/go/internal/core/adt.(*nodeContext).completeAllArcs
    .../internal/core/adt/unify.go:614
cuelang.org/go/internal/core/adt.(*Vertex).unify
    .../internal/core/adt/unify.go:334
...

This represents a potential DoS vector for applications that process untrusted CUE input.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions