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
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()

View File

@ -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: