From 1315e7422a87c808b1ccac103d2cd95c307ed267 Mon Sep 17 00:00:00 2001 From: Christian Rocha Date: Sun, 1 Sep 2024 21:19:53 -0400 Subject: [PATCH] fix(viewport): preempt potential panics when calculating visible lines --- viewport/viewport.go | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/viewport/viewport.go b/viewport/viewport.go index e0a4cc3..7cf71e7 100644 --- a/viewport/viewport.go +++ b/viewport/viewport.go @@ -117,12 +117,17 @@ func (m Model) maxYOffset() int { // visibleLines returns the lines that should currently be visible in the // viewport. func (m Model) visibleLines() (lines []string) { - if len(m.lines) > 0 { - top := max(0, m.YOffset) - bottom := clamp(m.YOffset+m.Height, top, len(m.lines)) - lines = m.lines[top:bottom] + if len(m.lines) == 0 { + return nil } - return lines + top := max(0, m.YOffset) + bottom := min(m.YOffset+m.Height, len(m.lines)) + if top >= bottom { + // Return early, otherwise we'll panic with a slice out of bounds + // error. + return nil + } + return m.lines[top:bottom] } // scrollArea returns the scrollable boundaries for high performance rendering. @@ -233,6 +238,11 @@ func (m *Model) GotoTop() (lines []string) { // GotoBottom sets the viewport to the bottom position. func (m *Model) GotoBottom() (lines []string) { + if len(m.lines) == 0 { + // If there are no lines, we can't go to the bottom...because we're + // already there. + return nil + } m.SetYOffset(m.maxYOffset()) return m.visibleLines() }