authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2019-04-26 15:57:47+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-04-26 14:24:35-04:00
log9ec4ccc68f6473ce4f02fc5d2b87ad92e2eb555a
treee11ad31594fe66fcfa449960f4b128ec9315d93e
parent4df2f3d74f140ae6a60dc33d3e0fb7b25f29d5b9

Do not invoke UB in BigInt shr operations

Shifting a value of type T by an amount that's greater or equal to the size of the type itself is UB. Spotted by @tgschultz

2 files changed, 5 insertions(+), 3 deletions(-)

src/bigint.cpp+1-1
...@@ -1395,7 +1395,7 @@ void bigint_shr(BigInt *dest, const BigInt *op1, const BigInt *op2) {...@@ -1395,7 +1395,7 @@ void bigint_shr(BigInt *dest, const BigInt *op1, const BigInt *op2) {
1395 uint64_t shift_amt = bigint_as_unsigned(op2);1395 uint64_t shift_amt = bigint_as_unsigned(op2);
13961396
1397 if (op1->digit_count == 1) {1397 if (op1->digit_count == 1) {
1398 dest->data.digit = op1_digits[0] >> shift_amt;1398 dest->data.digit = (shift_amt < 64) ? op1_digits[0] >> shift_amt : 0;
1399 dest->digit_count = 1;1399 dest->digit_count = 1;
1400 dest->is_negative = op1->is_negative;1400 dest->is_negative = op1->is_negative;
1401 bigint_normalize(dest);1401 bigint_normalize(dest);
test/stage1/behavior/bit_shifting.zig+4-2
...@@ -90,7 +90,9 @@ fn testShardedTable(comptime Key: type, comptime mask_bit_count: comptime_int, c...@@ -90,7 +90,9 @@ fn testShardedTable(comptime Key: type, comptime mask_bit_count: comptime_int, c
90// #222590// #2225
91test "comptime shr of BigInt" {91test "comptime shr of BigInt" {
92 comptime {92 comptime {
93 var n = 0xdeadbeef0000000000000000;93 var n0 = 0xdeadbeef0000000000000000;
94 std.debug.assert(n >> 64 == 0xdeadbeef);94 std.debug.assert(n0 >> 64 == 0xdeadbeef);
95 var n1 = 17908056155735594659;
96 std.debug.assert(n1 >> 64 == 0);
95 }97 }
96}98}