From 463ef212b6ecbf5d6affff51e240772c7edcb86d Mon Sep 17 00:00:00 2001 From: Junegunn Choi Date: Sat, 16 May 2026 17:58:31 +0900 Subject: [PATCH] Reject every() intervals that overflow int32 milliseconds Char is rune (int32). Without an upper bound, secs * 1000 could silently wrap to a non-positive value and panic time.NewTicker. --- src/options.go | 7 +++++-- src/options_test.go | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/options.go b/src/options.go index 0ee6d7fa..0ebca52b 100644 --- a/src/options.go +++ b/src/options.go @@ -1315,8 +1315,11 @@ func parseEveryEvent(arg string) (tui.Event, error) { if secs < 0.01 { secs = 0.01 } - ms := int32(math.Round(secs * 1000)) - return tui.Event{Type: tui.Every, Char: rune(ms)}, nil + ms := math.Round(secs * 1000) + if ms > math.MaxInt32 { + return tui.Event{}, errors.New("every() interval is too large") + } + return tui.Event{Type: tui.Every, Char: rune(int32(ms))}, nil } func parseScheme(str string) (string, []criterion, error) { diff --git a/src/options_test.go b/src/options_test.go index b32dbfef..7e7b4c6e 100644 --- a/src/options_test.go +++ b/src/options_test.go @@ -323,8 +323,8 @@ func TestParseEveryEvent(t *testing.T) { t.Errorf("every(0.001) should floor to 10ms") } - // Reject zero and negatives - for _, bad := range []string{"every(0)", "every(-1)", "every(abc)", "every()"} { + // Reject zero, negatives, and overflow (>= 2^31 ms = ~24.85 days) + for _, bad := range []string{"every(0)", "every(-1)", "every(abc)", "every()", "every(2147484)"} { if _, _, err := parseKeyChords(bad, ""); err == nil { t.Errorf("%s should be rejected", bad) }