diff options
author | Ori Bernstein <ori@eigenstate.org> | 2019-07-14 01:37:36 +0000 |
---|---|---|
committer | Ori Bernstein <ori@eigenstate.org> | 2019-07-14 01:37:36 +0000 |
commit | 77246bfe1b9f147b1b255e811fb8b2032c49dc9e (patch) | |
tree | 52137f1982d5593dd7ef4c028b3cac57a38b1d03 | |
parent | 34d97453258079f514c3297f88663fc23ff6e080 (diff) | |
download | mc-77246bfe1b9f147b1b255e811fb8b2032c49dc9e.tar.gz |
Fix crash with large shifts in bigint.
-rw-r--r-- | lib/std/bigint.myr | 28 | ||||
-rw-r--r-- | lib/std/test/bigint.myr | 8 |
2 files changed, 24 insertions, 12 deletions
diff --git a/lib/std/bigint.myr b/lib/std/bigint.myr index 8e078cf..6e3d6d8 100644 --- a/lib/std/bigint.myr +++ b/lib/std/bigint.myr @@ -945,18 +945,22 @@ generic bigshri = {a, s off = (s : uint64) / 32 shift = (s : uint64) % 32 - /* blit over the base values */ - for var i = 0; i < a.dig.len - off; i++ - a.dig[i] = a.dig[i + off] - ;; - a.dig = a.dig[:a.dig.len - off] - - /* and shift over by the remainder */ - carry = 0 - for var i = a.dig.len; i > 0; i-- - t = ((a.dig[i - 1] : uint64)) - a.dig[i - 1] = (carry | (t >> shift): uint32) - carry = t << (32 - shift) + if off > a.dig.len + a.dig = a.dig[:0] + else + /* blit over the base values */ + for var i = 0; i < a.dig.len - off; i++ + a.dig[i] = a.dig[i + off] + ;; + a.dig = a.dig[:a.dig.len - off] + + /* and shift over by the remainder */ + carry = 0 + for var i = a.dig.len; i > 0; i-- + t = ((a.dig[i - 1] : uint64)) + a.dig[i - 1] = (carry | (t >> shift): uint32) + carry = t << (32 - shift) + ;; ;; -> trim(a) } diff --git a/lib/std/test/bigint.myr b/lib/std/test/bigint.myr index c87f1f3..77b822f 100644 --- a/lib/std/test/bigint.myr +++ b/lib/std/test/bigint.myr @@ -21,6 +21,7 @@ const main = { [.name = "format-zero", .fn = fmtzero], [.name = "division", .fn = smokediv], [.name = "modulo", .fn = smokemod], + [.name = "shift", .fn = shiftoff], [.name = "add-negatives", .fn = addneg], [.name = "sub-negatives", .fn = subneg], ][:]) @@ -264,6 +265,13 @@ const subneg = {c "0") } +const shiftoff = {c + run(c, std.mk(`Shr ( \ + std.mk(`Val "1"), \ + std.mk(`Val "65"))), \ + "0") +} + const run = {c : testr.ctx#, e : cmd#, res : byte[:] var buf : byte[4096] var v, n |