From f2bd4f87a4e50e28036616a7e58e200c32a8b971 Mon Sep 17 00:00:00 2001 From: Brandon Jaus Date: Fri, 20 Feb 2026 13:30:48 -0600 Subject: [PATCH] fix: validate interval bounds in Union before appending The Union function computes intersection intervals by taking max(start) and min(end) of two intervals. However, when intervals don't actually overlap (e.g., [90,95] and [80,88]), this produces invalid intervals where start > end (e.g., [90,88]). This causes a panic in TotalWhitespace when it tries to slice with invalid bounds: `lines[90:88]` -> "slice bounds out of range [90:88]" The fix validates that start <= end before appending to the result, which correctly handles non-overlapping intervals by excluding them. Added test cases for non-overlapping and adjacent intervals. --- interval/interval.go | 11 +++++++---- interval/interval_test.go | 22 ++++++++++++++++++++++ 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/interval/interval.go b/interval/interval.go index de97ecd..b0d558c 100644 --- a/interval/interval.go +++ b/interval/interval.go @@ -98,10 +98,13 @@ func Union(a []Interval, b []Interval) []Interval { i++ } - result = append(result, Interval{ - Start: start, - End: end, - }) + // Only append if the intervals actually overlap (start <= end) + if start <= end { + result = append(result, Interval{ + Start: start, + End: end, + }) + } } return joinSortedIntervals(result) diff --git a/interval/interval_test.go b/interval/interval_test.go index a52eb6a..92812dc 100644 --- a/interval/interval_test.go +++ b/interval/interval_test.go @@ -77,6 +77,28 @@ func TestUnion(t *testing.T) { {Start: 5, End: 5}, }, }, + { + name: "non-overlapping intervals should produce empty result", + a: []interval.Interval{ + {Start: 90, End: 95}, + }, + b: []interval.Interval{ + {Start: 80, End: 88}, + }, + e: []interval.Interval{}, + }, + { + name: "adjacent but non-overlapping intervals", + a: []interval.Interval{ + {Start: 10, End: 20}, + {Start: 50, End: 60}, + }, + b: []interval.Interval{ + {Start: 21, End: 30}, + {Start: 40, End: 49}, + }, + e: []interval.Interval{}, + }, } for _, tc := range testacses {