authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-04-09 14:58:07-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2020-04-09 14:58:07-04:00
log543031db35ede984b60a00c8f8a7859c6acfebdd
tree9e11d46350f628786c3205ab2ad1d1642fd89e2e
parentf1360bee1ce6096f1c123347313a7d24a0d90650
parentf5f77089b76be2832640884f14c552c49c9fda1f
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #4982 from MageJohn/fix/binarySearch

sort.binarySearch: fix integer underflow (#4980)

1 files changed, 7 insertions(+), 6 deletions(-)

lib/std/sort.zig+7-6
...@@ -6,20 +6,17 @@ const math = std.math;...@@ -6,20 +6,17 @@ const math = std.math;
6const builtin = @import("builtin");6const builtin = @import("builtin");
77
8pub fn binarySearch(comptime T: type, key: T, items: []const T, comptime compareFn: fn (lhs: T, rhs: T) math.Order) ?usize {8pub fn binarySearch(comptime T: type, key: T, items: []const T, comptime compareFn: fn (lhs: T, rhs: T) math.Order) ?usize {
9 if (items.len < 1)
10 return null;
11
12 var left: usize = 0;9 var left: usize = 0;
13 var right: usize = items.len - 1;10 var right: usize = items.len;
1411
15 while (left <= right) {12 while (left < right) {
16 // Avoid overflowing in the midpoint calculation13 // Avoid overflowing in the midpoint calculation
17 const mid = left + (right - left) / 2;14 const mid = left + (right - left) / 2;
18 // Compare the key with the midpoint element15 // Compare the key with the midpoint element
19 switch (compareFn(key, items[mid])) {16 switch (compareFn(key, items[mid])) {
20 .eq => return mid,17 .eq => return mid,
21 .gt => left = mid + 1,18 .gt => left = mid + 1,
22 .lt => right = mid - 1,19 .lt => right = mid,
23 }20 }
24 }21 }
2522
...@@ -47,6 +44,10 @@ test "std.sort.binarySearch" {...@@ -47,6 +44,10 @@ test "std.sort.binarySearch" {
47 @as(?usize, null),44 @as(?usize, null),
48 binarySearch(u32, 1, &[_]u32{0}, S.order_u32),45 binarySearch(u32, 1, &[_]u32{0}, S.order_u32),
49 );46 );
47 testing.expectEqual(
48 @as(?usize, null),
49 binarySearch(u32, 0, &[_]u32{1}, S.order_u32),
50 );
50 testing.expectEqual(51 testing.expectEqual(
51 @as(?usize, 4),52 @as(?usize, 4),
52 binarySearch(u32, 5, &[_]u32{ 1, 2, 3, 4, 5 }, S.order_u32),53 binarySearch(u32, 5, &[_]u32{ 1, 2, 3, 4, 5 }, S.order_u32),