diff --git a/sjsonnet/src/sjsonnet/Val.scala b/sjsonnet/src/sjsonnet/Val.scala index b5d1ae62..a547efd5 100644 --- a/sjsonnet/src/sjsonnet/Val.scala +++ b/sjsonnet/src/sjsonnet/Val.scala @@ -71,13 +71,18 @@ final class LazyExpr( private var scope: ValScope, private var ev: Evaluator) extends Lazy { + private var evaluating: Boolean = false def value: Val = { if (ev == null) exprOrVal.asInstanceOf[Val] - else { + else if (evaluating) { + Error.fail("Infinite recursion detected (self-referential thunk)") + } else { + evaluating = true val r = ev.visitExpr(exprOrVal.asInstanceOf[Expr])(scope) exprOrVal = r // cache result scope = null.asInstanceOf[sjsonnet.ValScope] // allow GC ev = null // sentinel: marks as computed + evaluating = false r } } diff --git a/sjsonnet/test/resources/new_test_suite/error.self_referential_thunk.jsonnet b/sjsonnet/test/resources/new_test_suite/error.self_referential_thunk.jsonnet new file mode 100644 index 00000000..f566a092 --- /dev/null +++ b/sjsonnet/test/resources/new_test_suite/error.self_referential_thunk.jsonnet @@ -0,0 +1 @@ +local x = x; x diff --git a/sjsonnet/test/resources/new_test_suite/error.self_referential_thunk.jsonnet.golden b/sjsonnet/test/resources/new_test_suite/error.self_referential_thunk.jsonnet.golden new file mode 100644 index 00000000..eb6d47c8 --- /dev/null +++ b/sjsonnet/test/resources/new_test_suite/error.self_referential_thunk.jsonnet.golden @@ -0,0 +1,2 @@ +sjsonnet.Error: Infinite recursion detected (self-referential thunk) + at [].(error.self_referential_thunk.jsonnet:1:7)