From 7757302c3aa230a30770b4ff7a9b033e621c0178 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Wed, 12 Mar 2025 22:04:41 -0400 Subject: [PATCH] big.int: fix negative multi-limb shift right adjust crash --- lib/std/math/big/int.zig | 14 ++++---------- lib/std/math/big/int_test.zig | 9 +++++++++ 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/lib/std/math/big/int.zig b/lib/std/math/big/int.zig index 5e7214b7d9..780930c3de 100644 --- a/lib/std/math/big/int.zig +++ b/lib/std/math/big/int.zig @@ -1096,7 +1096,7 @@ pub const Mutable = struct { /// Asserts there is enough memory to fit the result. The upper bound Limb count is /// `a.limbs.len + (shift / (@sizeOf(Limb) * 8))`. pub fn shiftLeft(r: *Mutable, a: Const, shift: usize) void { - llshl(r.limbs[0..], a.limbs[0..a.limbs.len], shift); + llshl(r.limbs, a.limbs, shift); r.normalize(a.limbs.len + (shift / limb_bits) + 1); r.positive = a.positive; } @@ -1165,7 +1165,7 @@ pub const Mutable = struct { // This shift should not be able to overflow, so invoke llshl and normalize manually // to avoid the extra required limb. - llshl(r.limbs[0..], a.limbs[0..a.limbs.len], shift); + llshl(r.limbs, a.limbs, shift); r.normalize(a.limbs.len + (shift / limb_bits)); r.positive = a.positive; } @@ -1202,17 +1202,11 @@ pub const Mutable = struct { break :nonzero a.limbs[full_limbs_shifted_out] << not_covered != 0; }; - llshr(r.limbs[0..], a.limbs[0..a.limbs.len], shift); + llshr(r.limbs, a.limbs, shift); r.len = a.limbs.len - full_limbs_shifted_out; r.positive = a.positive; - if (nonzero_negative_shiftout) { - if (full_limbs_shifted_out > 0) { - r.limbs[a.limbs.len - full_limbs_shifted_out] = 0; - r.len += 1; - } - r.addScalar(r.toConst(), -1); - } + if (nonzero_negative_shiftout) r.addScalar(r.toConst(), -1); r.normalize(r.len); } diff --git a/lib/std/math/big/int_test.zig b/lib/std/math/big/int_test.zig index 009bef7ef3..069aab5c81 100644 --- a/lib/std/math/big/int_test.zig +++ b/lib/std/math/big/int_test.zig @@ -2191,6 +2191,15 @@ test "shift-right negative" { a.setSign(true); try a.shiftRight(&arg7, 4); try testing.expect(try a.toInt(i16) == -2048); + + var arg8_limbs: [1]Limb = undefined; + var arg8: Mutable = .{ + .limbs = &arg8_limbs, + .len = undefined, + .positive = undefined, + }; + arg8.shiftRight(.{ .limbs = &.{ 1, 1 }, .positive = false }, @bitSizeOf(Limb)); + try testing.expect(arg8.toConst().orderAgainstScalar(-2).compare(.eq)); } test "sat shift-left simple unsigned" {