summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2019-07-14 01:37:36 +0000
committerOri Bernstein <ori@eigenstate.org>2019-07-14 01:37:36 +0000
commit77246bfe1b9f147b1b255e811fb8b2032c49dc9e (patch)
tree52137f1982d5593dd7ef4c028b3cac57a38b1d03 /lib
parent34d97453258079f514c3297f88663fc23ff6e080 (diff)
downloadmc-77246bfe1b9f147b1b255e811fb8b2032c49dc9e.tar.gz
Fix crash with large shifts in bigint.
Diffstat (limited to 'lib')
-rw-r--r--lib/std/bigint.myr28
-rw-r--r--lib/std/test/bigint.myr8
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