From 447dc2bb9011078e80acbe3f51135ff1ad2bf163 Mon Sep 17 00:00:00 2001 From: Yuri Pieters Date: Thu, 9 Apr 2020 01:49:42 +0100 Subject: [PATCH 1/3] sort.binarySearch: fix integer underflow (#4980) When the key was smaller than any value in the array, an error was ocurring with the mid being zero and having 1 subtracted from it. --- lib/std/sort.zig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/std/sort.zig b/lib/std/sort.zig index 3447a0576951..91d29dd22dcc 100644 --- a/lib/std/sort.zig +++ b/lib/std/sort.zig @@ -10,16 +10,16 @@ pub fn binarySearch(comptime T: type, key: T, items: []const T, comptime compare return null; var left: usize = 0; - var right: usize = items.len - 1; + var right: usize = items.len; - while (left <= right) { + while (left < right) { // Avoid overflowing in the midpoint calculation const mid = left + (right - left) / 2; // Compare the key with the midpoint element switch (compareFn(key, items[mid])) { .eq => return mid, .gt => left = mid + 1, - .lt => right = mid - 1, + .lt => right = mid, } } From b7e72cc4211d7b06e2b7095f48c579ce1daaf253 Mon Sep 17 00:00:00 2001 From: Yuri Pieters Date: Thu, 9 Apr 2020 02:00:08 +0100 Subject: [PATCH 2/3] sort.binarySearch: test for regresson of #4980 --- lib/std/sort.zig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/std/sort.zig b/lib/std/sort.zig index 91d29dd22dcc..c6dcaac49e15 100644 --- a/lib/std/sort.zig +++ b/lib/std/sort.zig @@ -47,6 +47,10 @@ test "std.sort.binarySearch" { @as(?usize, null), binarySearch(u32, 1, &[_]u32{0}, S.order_u32), ); + testing.expectEqual( + @as(?usize, null), + binarySearch(u32, 0, &[_]u32{1}, S.order_u32), + ); testing.expectEqual( @as(?usize, 4), binarySearch(u32, 5, &[_]u32{ 1, 2, 3, 4, 5 }, S.order_u32), From f5f77089b76be2832640884f14c552c49c9fda1f Mon Sep 17 00:00:00 2001 From: Yuri Pieters Date: Thu, 9 Apr 2020 09:13:47 +0100 Subject: [PATCH 3/3] sort.binarySearch: Remove unneeded edge case check --- lib/std/sort.zig | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/std/sort.zig b/lib/std/sort.zig index c6dcaac49e15..8ed8f2c1c0ec 100644 --- a/lib/std/sort.zig +++ b/lib/std/sort.zig @@ -6,9 +6,6 @@ const math = std.math; const builtin = @import("builtin"); pub fn binarySearch(comptime T: type, key: T, items: []const T, comptime compareFn: fn (lhs: T, rhs: T) math.Order) ?usize { - if (items.len < 1) - return null; - var left: usize = 0; var right: usize = items.len;