diff --git a/sjsonnet/src/sjsonnet/Evaluator.scala b/sjsonnet/src/sjsonnet/Evaluator.scala index 5f99b43b..5dd31baf 100644 --- a/sjsonnet/src/sjsonnet/Evaluator.scala +++ b/sjsonnet/src/sjsonnet/Evaluator.scala @@ -894,9 +894,10 @@ class Evaluator( val ll = visitExprAsDouble(e.lhs).toSafeLong(pos) val rr = visitExprAsDouble(e.rhs).toSafeLong(pos) if (rr < 0) Error.fail("Shift by negative exponent", pos) - if (rr >= 1 && math.abs(ll) >= (1L << (63 - rr))) + val masked = (rr % 64).toInt + if (masked >= 1 && math.abs(ll) >= (1L << (63 - masked))) Error.fail("Numeric value outside safe integer range for bitwise operation", pos) - (ll << rr).toDouble + (ll << masked).toDouble case Expr.BinaryOp.OP_>> => val ll = visitExprAsDouble(e.lhs).toSafeLong(pos) val rr = visitExprAsDouble(e.rhs).toSafeLong(pos) diff --git a/sjsonnet/test/resources/new_test_suite/leftshift_fast_path_masking.jsonnet b/sjsonnet/test/resources/new_test_suite/leftshift_fast_path_masking.jsonnet new file mode 100644 index 00000000..7ffe5f75 --- /dev/null +++ b/sjsonnet/test/resources/new_test_suite/leftshift_fast_path_masking.jsonnet @@ -0,0 +1,9 @@ +std.assertEqual((1 << 64) * 1, 1) && +std.assertEqual(((1 << 64) + 0) * 1, 1) && +std.assertEqual((1 << 65) * 1, 2) && +std.assertEqual((1 << 128) * 1, 1) && +std.assertEqual((0 << 128) * 1, 0) && +std.assertEqual(((-1) << 64) * 1, -1) && +std.assertEqual(((-2) << 65) * 1, -4) && +std.assertEqual(((-3) << 128) * 1, -3) && +true diff --git a/sjsonnet/test/resources/new_test_suite/leftshift_fast_path_masking.jsonnet.golden b/sjsonnet/test/resources/new_test_suite/leftshift_fast_path_masking.jsonnet.golden new file mode 100644 index 00000000..27ba77dd --- /dev/null +++ b/sjsonnet/test/resources/new_test_suite/leftshift_fast_path_masking.jsonnet.golden @@ -0,0 +1 @@ +true