diff --git a/sjsonnet/src-jvm-native/sjsonnet/SjsonnetMainBase.scala b/sjsonnet/src-jvm-native/sjsonnet/SjsonnetMainBase.scala index 4b97d65e..d6444943 100644 --- a/sjsonnet/src-jvm-native/sjsonnet/SjsonnetMainBase.scala +++ b/sjsonnet/src-jvm-native/sjsonnet/SjsonnetMainBase.scala @@ -195,6 +195,21 @@ object SjsonnetMainBase { Left("ERROR: cannot use --no-trailing-newline with --yaml-stream") else Right(()) } + _ <- { + if (config.maxStack < 1) Left(s"ERROR: invalid --max-stack value: ${config.maxStack}") + else Right(()) + } + _ <- { + if (config.maxTrace < 0) Left(s"ERROR: invalid --max-trace value: ${config.maxTrace}") + else Right(()) + } + _ <- { + if (config.maxParserRecursionDepth < 0) + Left( + s"ERROR: invalid --max-parser-recursion-depth value: ${config.maxParserRecursionDepth}" + ) + else Right(()) + } file <- Right(config.file) debugStats = if (config.debugStats.value) { val s = new DebugStats; statsToReport = s; s } diff --git a/sjsonnet/test/src-jvm/sjsonnet/MainTests.scala b/sjsonnet/test/src-jvm/sjsonnet/MainTests.scala index 1c01cfb1..2c348bd7 100644 --- a/sjsonnet/test/src-jvm/sjsonnet/MainTests.scala +++ b/sjsonnet/test/src-jvm/sjsonnet/MainTests.scala @@ -147,6 +147,47 @@ object MainTests extends TestSuite { assert(err.contains("Max stack frames exceeded.")) } + test("maxStackRejectsNonPositiveValues") { + val (zeroRes, zeroOut, zeroErr) = runMain("--exec", "1", "--max-stack", "0") + assert(zeroRes == 1) + assert(zeroOut.isEmpty) + assert(zeroErr.contains("ERROR: invalid --max-stack value: 0")) + assert(!zeroErr.contains("Max stack frames exceeded.")) + + val (negativeRes, negativeOut, negativeErr) = runMain("--exec", "1", "--max-stack", "-1") + assert(negativeRes == 1) + assert(negativeOut.isEmpty) + assert(negativeErr.contains("ERROR: invalid --max-stack value: -1")) + assert(!negativeErr.contains("Max stack frames exceeded.")) + } + + test("maxTraceRejectsNegativeValues") { + val (res, out, err) = runMain("--exec", "error 'x'", "--max-trace", "-1") + assert(res == 1) + assert(out.isEmpty) + assert(err.contains("ERROR: invalid --max-trace value: -1")) + assert(!err.contains("sjsonnet.Error")) + } + + test("maxParserRecursionDepthRejectsNegativeValues") { + val (res, out, err) = runMain("--exec", "1", "--max-parser-recursion-depth", "-1") + assert(res == 1) + assert(out.isEmpty) + assert(err.contains("ERROR: invalid --max-parser-recursion-depth value: -1")) + assert(!err.contains("Parsing exceeded maximum recursion depth of -1")) + } + + test("maxParserRecursionDepthZeroAllowsNonRecursiveExpressions") { + val (res, out, err) = runMain("--exec", "1", "--max-parser-recursion-depth", "0") + assert((res, out, err) == ((0, "1\n", ""))) + + val (nestedRes, nestedOut, nestedErr) = + runMain("--exec", "[1]", "--max-parser-recursion-depth", "0") + assert(nestedRes == 1) + assert(nestedOut.isEmpty) + assert(nestedErr.contains("Parsing exceeded maximum recursion depth of 0")) + } + test("maxStackDoesNotCountTailRecursiveCalls") { val (res, out, err) = runMain( "--exec",