Skip to content

Commit 34e2b63

Browse files
committed
fix: mask left shifts in numeric fast path
Motivation: Jsonnet interprets shift counts modulo 64, but the numeric fast path validated left shifts using the unmasked count. Expressions routed through outer arithmetic could therefore fail even when the generic evaluator succeeded. Modification: Normalize non-negative left-shift counts modulo 64 before both overflow validation and execution, and add regressions for counts 64, 65, and 128. Result: Numeric fast-path behavior now matches the generic evaluator, go-jsonnet, jrsonnet, and the Jsonnet specification without changing valid count-65 behavior. References: - #1096 - https://jsonnet.org/ref/spec.html
1 parent a638dc4 commit 34e2b63

3 files changed

Lines changed: 10 additions & 2 deletions

File tree

sjsonnet/src/sjsonnet/Evaluator.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -894,9 +894,10 @@ class Evaluator(
894894
val ll = visitExprAsDouble(e.lhs).toSafeLong(pos)
895895
val rr = visitExprAsDouble(e.rhs).toSafeLong(pos)
896896
if (rr < 0) Error.fail("Shift by negative exponent", pos)
897-
if (rr >= 1 && math.abs(ll) >= (1L << (63 - rr)))
897+
val masked = (rr % 64).toInt
898+
if (masked >= 1 && math.abs(ll) >= (1L << (63 - masked)))
898899
Error.fail("Numeric value outside safe integer range for bitwise operation", pos)
899-
(ll << rr).toDouble
900+
(ll << masked).toDouble
900901
case Expr.BinaryOp.OP_>> =>
901902
val ll = visitExprAsDouble(e.lhs).toSafeLong(pos)
902903
val rr = visitExprAsDouble(e.rhs).toSafeLong(pos)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
std.assertEqual((1 << 64) * 1, 1) &&
2+
std.assertEqual(((1 << 64) + 0) * 1, 1) &&
3+
std.assertEqual((1 << 65) * 1, 2) &&
4+
std.assertEqual((1 << 128) * 1, 1) &&
5+
std.assertEqual((0 << 128) * 1, 0) &&
6+
true
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
true

0 commit comments

Comments
 (0)