From ef148dfd3765cd78ccdb1840c3e1d74735071ab4 Mon Sep 17 00:00:00 2001 From: Junegunn Choi Date: Wed, 5 Jun 2024 09:47:05 +0900 Subject: [PATCH] Handle int32 overflow yes | fzf --tail=10 --preview 'echo "{n}"' --- src/item.go | 4 +++- src/terminal.go | 31 ++++++++++++++++++++++++------- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/item.go b/src/item.go index cb778cb9..c07d7fff 100644 --- a/src/item.go +++ b/src/item.go @@ -1,6 +1,8 @@ package fzf import ( + "math" + "github.com/junegunn/fzf/src/util" ) @@ -17,7 +19,7 @@ func (item *Item) Index() int32 { return item.text.Index } -var minItem = Item{text: util.Chars{Index: -1}} +var minItem = Item{text: util.Chars{Index: math.MinInt32}} func (item *Item) TrimLength() uint16 { return item.text.TrimLength() diff --git a/src/terminal.go b/src/terminal.go index caa2446e..60cc6f33 100644 --- a/src/terminal.go +++ b/src/terminal.go @@ -1176,12 +1176,22 @@ func (t *Terminal) UpdateList(merger *Merger, triggerResultEvent bool) { t.progress = 100 t.merger = merger if !t.revision.equals(newRevision) { - if !t.revision.compatible(newRevision) { // Reloaded: clear selection + if !t.revision.compatible(newRevision) { + // Reloaded: clear selection t.selected = make(map[int32]selectedItem) - } else { // Trimmed by --tail: filter selection by index + } else { + // Trimmed by --tail: filter selection by index filtered := make(map[int32]selectedItem) + minIndex := merger.minIndex + maxIndex := minIndex + int32(merger.Length()) for k, v := range t.selected { - if k >= merger.minIndex { + var included bool + if maxIndex > minIndex { + included = k >= minIndex && k < maxIndex + } else { // int32 overflow [==> <==] + included = k >= minIndex || k < maxIndex + } + if included { filtered[k] = v } } @@ -2856,11 +2866,18 @@ func replacePlaceholder(params replacePlaceholderParams) (string, []string) { replace = func(item *Item) string { switch { case flags.number: - n := int(item.text.Index) - if n < 0 { - return "" + n := item.text.Index + if n == minItem.Index() { + // NOTE: Item index should normally be positive, but if there's no + // match, it will be set to math.MinInt32, and we don't want to + // show that value. However, int32 can overflow, especially when + // `--tail` is used with an endless input stream, and the index of + // an item actually can be math.MinInt32. In that case, you're + // getting an incorrect value, but we're going to ignore that for + // now. + return "''" } - return strconv.Itoa(n) + return strconv.Itoa(int(n)) case flags.file: return item.AsString(params.stripAnsi) default: