Skip to content

Commit 2525bf7

Browse files
Fix various small issues found when I imported all recent error tests (#410)
1 parent f0a585c commit 2525bf7

15 files changed

+77
-137
lines changed

sjsonnet/src/sjsonnet/Evaluator.scala

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,9 @@ class Evaluator(
553553
case (l: Val.Num, r: Val.Num) =>
554554
val ll = l.asSafeLong(pos)
555555
val rr = r.asSafeLong(pos)
556+
if (rr < 0) {
557+
Error.fail("shift by negative exponent", pos)
558+
}
556559
if (rr >= 1 && ll >= (1L << (63 - rr)))
557560
Error.fail("numeric value outside safe integer range for bitwise operation", pos)
558561
else
@@ -563,7 +566,12 @@ class Evaluator(
563566
case Expr.BinaryOp.OP_>> =>
564567
(l, r) match {
565568
case (l: Val.Num, r: Val.Num) =>
566-
Val.Num(pos, (l.asSafeLong(pos) >> r.asSafeLong(pos)).toDouble)
569+
val ll = l.asSafeLong(pos)
570+
val rr = r.asSafeLong(pos)
571+
if (rr < 0) {
572+
Error.fail("shift by negative exponent", pos)
573+
}
574+
Val.Num(pos, (ll >> rr).toDouble)
567575
case _ => fail()
568576
}
569577

sjsonnet/src/sjsonnet/Parser.scala

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -97,16 +97,17 @@ class Parser(
9797
).map(s => Val.Num(s._1, s._2.toDouble))
9898

9999
def escape[$: P]: P[String] = P(escape0 | escape1)
100-
def escape0[$: P]: P[String] = P("\\" ~~ !"u" ~~ AnyChar.!).map {
101-
case "\"" => "\""
102-
case "'" => "\'"
103-
case "\\" => "\\"
104-
case "/" => "/"
105-
case "b" => "\b"
106-
case "f" => "\f"
107-
case "n" => "\n"
108-
case "r" => "\r"
109-
case "t" => "\t"
100+
def escape0[$: P]: P[String] = P("\\" ~~ !"u" ~~ AnyChar.!).flatMapX {
101+
case "\"" => Pass("\"")
102+
case "'" => Pass("\'")
103+
case "\\" => Pass("\\")
104+
case "/" => Pass("/")
105+
case "b" => Pass("\b")
106+
case "f" => Pass("\f")
107+
case "n" => Pass("\n")
108+
case "r" => Pass("\r")
109+
case "t" => Pass("\t")
110+
case s => Fail.opaque(f"Unknown escape sequence in string literal: $s")
110111
}
111112
def escape1[$: P]: P[String] = P("\\u" ~~ CharIn("0-9a-fA-F").repX(min = 4, max = 4).!).map { s =>
112113
Integer.parseInt(s, 16).toChar.toString

sjsonnet/src/sjsonnet/Std.scala

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -534,11 +534,19 @@ class Std(
534534
}
535535

536536
private object DecodeUTF8 extends Val.Builtin1("decodeUTF8", "arr") {
537-
def evalRhs(arr: Lazy, ev: EvalScope, pos: Position): Val =
538-
new Val.Str(
537+
def evalRhs(arr: Lazy, ev: EvalScope, pos: Position): Val = {
538+
for ((v, idx) <- arr.force.asArr.iterator.zipWithIndex) {
539+
if (!v.isInstanceOf[Val.Num] || !v.asDouble.isWhole || v.asInt < 0 || v.asInt > 255) {
540+
throw Error.fail(
541+
f"Element $idx of the provided array was not an integer in range [0,255]"
542+
)
543+
}
544+
}
545+
Val.Str(
539546
pos,
540-
new String(arr.force.asArr.iterator.map(_.cast[Val.Num].value.toByte).toArray, UTF_8)
547+
new String(arr.force.asArr.iterator.map(_.asInt.toByte).toArray, UTF_8)
541548
)
549+
}
542550
}
543551

544552
private object Substr extends Val.Builtin3("substr", "str", "from", "len") {
@@ -1004,8 +1012,14 @@ class Std(
10041012
}
10051013

10061014
private object ParseJson extends Val.Builtin1("parseJson", "str") {
1007-
def evalRhs(str: Lazy, ev: EvalScope, pos: Position): Val =
1008-
ujson.StringParser.transform(str.force.asString, new ValVisitor(pos))
1015+
def evalRhs(str: Lazy, ev: EvalScope, pos: Position): Val = {
1016+
try {
1017+
ujson.StringParser.transform(str.force.asString, new ValVisitor(pos))
1018+
} catch {
1019+
case e: ujson.ParseException =>
1020+
throw Error.fail("Invalid JSON: " + e.getMessage, pos)(ev)
1021+
}
1022+
}
10091023
}
10101024

10111025
private object ParseYaml extends Val.Builtin1("parseYaml", "str") {
@@ -1276,6 +1290,9 @@ class Std(
12761290
Util.slice(pos, ev, indexable, index, _end, _step)
12771291
},
12781292
builtin("makeArray", "sz", "func") { (pos, ev, sz: Int, func: Val.Func) =>
1293+
if (sz < 0) {
1294+
Error.fail(f"std.makeArray requires size >= 0, got $sz")
1295+
}
12791296
Val.Arr(
12801297
pos, {
12811298
val a = new Array[Lazy](sz)

sjsonnet/src/sjsonnet/Val.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,9 @@ object Val {
109109
override def asString: String = value
110110
}
111111
final case class Num(pos: Position, value: Double) extends Literal {
112+
if (value.isInfinite) {
113+
Error.fail("overflow")
114+
}
112115
def prettyName = "number"
113116
override def asInt: Int = value.toInt
114117
override def asLong: Long = value.toLong
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
"\u0011"
1+
sjsonnet.Error: Element 0 of the provided array was not an integer in range [0,255]
2+
at [std.decodeUTF8].(sjsonnet/test/resources/test_suite/error.decodeUTF8_float.jsonnet:1:15)
3+
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
sjsonnet.Error: Expected number, found string
1+
sjsonnet.Error: Element 0 of the provided array was not an integer in range [0,255]
22
at [std.decodeUTF8].(sjsonnet/test/resources/test_suite/error.decodeUTF8_nan.jsonnet:1:15)
33

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
0
1+
sjsonnet.Error: shift by negative exponent
2+
at [BinaryOp >>].(error.negative_shfit.jsonnet:1:8)
3+
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
Infinity
1+
sjsonnet.Error: overflow
2+
at [BinaryOp *].(error.overflow2.jsonnet:17:7)
3+
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
Infinity
1+
sjsonnet.Error: overflow
2+
at [BinaryOp *].(error.overflow2.jsonnet:17:7)
3+
Lines changed: 3 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,3 @@
1-
Exception in thread "main" scala.MatchError: o (of class java.lang.String)
2-
at sjsonnet.Parser.escape0(Parser.scala:109)
3-
at sjsonnet.Parser.escape(Parser.scala:99)
4-
at sjsonnet.Parser.rec$2(Parser.scala:115)
5-
at sjsonnet.Parser.doubleString(Parser.scala:115)
6-
at sjsonnet.Parser.expr2(Parser.scala:349)
7-
at sjsonnet.Parser.expr1(Parser.scala:275)
8-
at sjsonnet.Parser.expr(Parser.scala:211)
9-
at sjsonnet.Parser.document(Parser.scala:567)
10-
at sjsonnet.CachedResolver.$anonfun$2(Importer.scala:218)
11-
at fastparse.SharedPackageDefs.parseInputRaw(SharedPackageDefs.scala:69)
12-
at fastparse.SharedPackageDefs.parseInputRaw$(SharedPackageDefs.scala:6)
13-
at fastparse.package$.parseInputRaw(package.scala:5)
14-
at fastparse.SharedPackageDefs.parse$$anonfun$1(SharedPackageDefs.scala:35)
15-
at fastparse.ParserInputSource$fromParserInput.parseThrough(ParserInput.scala:25)
16-
at fastparse.SharedPackageDefs.parse(SharedPackageDefs.scala:42)
17-
at fastparse.SharedPackageDefs.parse$(SharedPackageDefs.scala:6)
18-
at fastparse.package$.parse(package.scala:5)
19-
at sjsonnet.CachedResolver.parse$$anonfun$1(Importer.scala:216)
20-
at scala.collection.mutable.HashMap.getOrElseUpdate(HashMap.scala:469)
21-
at sjsonnet.DefaultParseCache.getOrElseUpdate(ParseCache.scala:21)
22-
at sjsonnet.CachedResolver.parse(Importer.scala:227)
23-
at sjsonnet.Interpreter.evaluate(Interpreter.scala:175)
24-
at sjsonnet.Interpreter.interpret0(Interpreter.scala:158)
25-
at sjsonnet.SjsonnetMain$.renderNormal$$anonfun$1(SjsonnetMain.scala:157)
26-
at sjsonnet.SjsonnetMain$.writeToFile(SjsonnetMain.scala:131)
27-
at sjsonnet.SjsonnetMain$.renderNormal(SjsonnetMain.scala:155)
28-
at sjsonnet.SjsonnetMain$.mainConfigured(SjsonnetMain.scala:332)
29-
at sjsonnet.SjsonnetMain$.$anonfun$30$$anonfun$1(SjsonnetMain.scala:85)
30-
at scala.util.Either.flatMap(Either.scala:360)
31-
at sjsonnet.SjsonnetMain$.$anonfun$30(SjsonnetMain.scala:84)
32-
at scala.util.Either.flatMap(Either.scala:360)
33-
at sjsonnet.SjsonnetMain$.main0(SjsonnetMain.scala:77)
34-
at sjsonnet.SjsonnetMain$.main(SjsonnetMain.scala:44)
35-
at sjsonnet.SjsonnetMain.main(SjsonnetMain.scala)
1+
sjsonnet.ParseError: Expected "\"":17:2, found "\\o\"\n"
2+
at .(error.parse.string.invalid_escape.jsonnet:17:2)
3+

0 commit comments

Comments
 (0)