From 3bd1fb82ba12b95ddf8f7bde5e511dad848716eb Mon Sep 17 00:00:00 2001 From: Alexander Petrov Date: Fri, 12 Jun 2020 19:42:02 +0100 Subject: [PATCH] Throw an error on negative shifts (#421) Throw an error on negative shifts --- builtins.go | 16 +++++++++------- testdata/bitwise_shift4.golden | 11 ++++++++++- testdata/bitwise_shift5.golden | 1 + testdata/bitwise_shift5.jsonnet | 2 ++ testdata/bitwise_shift6.golden | 10 ++++++++++ testdata/bitwise_shift6.jsonnet | 1 + 6 files changed, 33 insertions(+), 8 deletions(-) create mode 100644 testdata/bitwise_shift5.golden create mode 100644 testdata/bitwise_shift5.jsonnet create mode 100644 testdata/bitwise_shift6.golden create mode 100644 testdata/bitwise_shift6.jsonnet diff --git a/builtins.go b/builtins.go index 87c8fe5..acb20b8 100644 --- a/builtins.go +++ b/builtins.go @@ -844,7 +844,7 @@ var builtinExponent = liftNumeric(func(f float64) float64 { return float64(exponent) }) -func liftBitwise(f func(int64, int64) int64) func(*interpreter, traceElement, value, value) (value, error) { +func liftBitwise(f func(int64, int64) int64, positiveRightArg bool) func(*interpreter, traceElement, value, value) (value, error) { return func(i *interpreter, trace traceElement, xv, yv value) (value, error) { x, err := i.getNumber(xv, trace) if err != nil { @@ -862,16 +862,18 @@ func liftBitwise(f func(int64, int64) int64) func(*interpreter, traceElement, va msg := fmt.Sprintf("Bitwise operator argument %v outside of range [%v, %v]", y.value, int64(math.MinInt64), int64(math.MaxInt64)) return nil, makeRuntimeError(msg, i.getCurrentStackTrace(trace)) } + if positiveRightArg && y.value < 0 { + return nil, makeRuntimeError("Shift by negative exponent.", i.getCurrentStackTrace(trace)) + } return makeDoubleCheck(i, trace, float64(f(int64(x.value), int64(y.value)))) } } -// TODO(sbarzowski) negative shifts -var builtinShiftL = liftBitwise(func(x, y int64) int64 { return x << uint(y%64) }) -var builtinShiftR = liftBitwise(func(x, y int64) int64 { return x >> uint(y%64) }) -var builtinBitwiseAnd = liftBitwise(func(x, y int64) int64 { return x & y }) -var builtinBitwiseOr = liftBitwise(func(x, y int64) int64 { return x | y }) -var builtinBitwiseXor = liftBitwise(func(x, y int64) int64 { return x ^ y }) +var builtinShiftL = liftBitwise(func(x, y int64) int64 { return x << uint(y%64) }, true) +var builtinShiftR = liftBitwise(func(x, y int64) int64 { return x >> uint(y%64) }, true) +var builtinBitwiseAnd = liftBitwise(func(x, y int64) int64 { return x & y }, false) +var builtinBitwiseOr = liftBitwise(func(x, y int64) int64 { return x | y }, false) +var builtinBitwiseXor = liftBitwise(func(x, y int64) int64 { return x ^ y }, false) func builtinObjectFieldsEx(i *interpreter, trace traceElement, objv, includeHiddenV value) (value, error) { obj, err := i.getObject(objv, trace) diff --git a/testdata/bitwise_shift4.golden b/testdata/bitwise_shift4.golden index 573541a..96859c3 100644 --- a/testdata/bitwise_shift4.golden +++ b/testdata/bitwise_shift4.golden @@ -1 +1,10 @@ -0 +RUNTIME ERROR: Shift by negative exponent. +------------------------------------------------- + testdata/bitwise_shift4:1:1-15 $ + +10000 >> (-10) + +------------------------------------------------- + During evaluation + + diff --git a/testdata/bitwise_shift5.golden b/testdata/bitwise_shift5.golden new file mode 100644 index 0000000..ff1352d --- /dev/null +++ b/testdata/bitwise_shift5.golden @@ -0,0 +1 @@ +1099511627776 diff --git a/testdata/bitwise_shift5.jsonnet b/testdata/bitwise_shift5.jsonnet new file mode 100644 index 0000000..5be2236 --- /dev/null +++ b/testdata/bitwise_shift5.jsonnet @@ -0,0 +1,2 @@ +/* 1 << (1000 % 64) */ +1 << 1000 diff --git a/testdata/bitwise_shift6.golden b/testdata/bitwise_shift6.golden new file mode 100644 index 0000000..f68c6bf --- /dev/null +++ b/testdata/bitwise_shift6.golden @@ -0,0 +1,10 @@ +RUNTIME ERROR: Shift by negative exponent. +------------------------------------------------- + testdata/bitwise_shift6:1:1-13 $ + +1 << (0 - 1) + +------------------------------------------------- + During evaluation + + diff --git a/testdata/bitwise_shift6.jsonnet b/testdata/bitwise_shift6.jsonnet new file mode 100644 index 0000000..3a794c8 --- /dev/null +++ b/testdata/bitwise_shift6.jsonnet @@ -0,0 +1 @@ +1 << (0 - 1)