Handle int32 overflow

yes | fzf --tail=10 --preview 'echo "{n}"'
This commit is contained in:
Junegunn Choi 2024-06-05 09:47:05 +09:00
parent 93bbb3032d
commit ef148dfd37
No known key found for this signature in database
GPG Key ID: 254BC280FEF9C627
2 changed files with 27 additions and 8 deletions

View File

@ -1,6 +1,8 @@
package fzf package fzf
import ( import (
"math"
"github.com/junegunn/fzf/src/util" "github.com/junegunn/fzf/src/util"
) )
@ -17,7 +19,7 @@ func (item *Item) Index() int32 {
return item.text.Index 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 { func (item *Item) TrimLength() uint16 {
return item.text.TrimLength() return item.text.TrimLength()

View File

@ -1176,12 +1176,22 @@ func (t *Terminal) UpdateList(merger *Merger, triggerResultEvent bool) {
t.progress = 100 t.progress = 100
t.merger = merger t.merger = merger
if !t.revision.equals(newRevision) { 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) 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) filtered := make(map[int32]selectedItem)
minIndex := merger.minIndex
maxIndex := minIndex + int32(merger.Length())
for k, v := range t.selected { 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 filtered[k] = v
} }
} }
@ -2856,11 +2866,18 @@ func replacePlaceholder(params replacePlaceholderParams) (string, []string) {
replace = func(item *Item) string { replace = func(item *Item) string {
switch { switch {
case flags.number: case flags.number:
n := int(item.text.Index) n := item.text.Index
if n < 0 { if n == minItem.Index() {
return "" // 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: case flags.file:
return item.AsString(params.stripAnsi) return item.AsString(params.stripAnsi)
default: default: