diff --git a/pkg/history/history.go b/pkg/history/history.go index 1200de810..51633e599 100644 --- a/pkg/history/history.go +++ b/pkg/history/history.go @@ -1,8 +1,8 @@ package history import ( - "bufio" "encoding/json" + "io" "os" "path/filepath" "slices" @@ -215,24 +215,18 @@ func (h *History) load() error { defer f.Close() var all []string - scanner := bufio.NewScanner(f) - for scanner.Scan() { - line := scanner.Text() - if line == "" { - continue - } - + dec := json.NewDecoder(f) + for { var message string - if err := json.Unmarshal([]byte(line), &message); err != nil { + if err := dec.Decode(&message); err != nil { + if err == io.EOF { + break + } continue } all = append(all, message) } - if err := scanner.Err(); err != nil { - return err - } - // Deduplicate keeping the latest occurrence of each message seen := make(map[string]bool) for i := len(all) - 1; i >= 0; i-- { diff --git a/pkg/history/history_test.go b/pkg/history/history_test.go index d12b9cc95..861eb126f 100644 --- a/pkg/history/history_test.go +++ b/pkg/history/history_test.go @@ -417,3 +417,28 @@ func TestHistory_SetCurrent(t *testing.T) { h.SetCurrent(2) assert.Empty(t, h.Next()) } + +func TestHistory_VeryLongMessage(t *testing.T) { + tmpDir := t.TempDir() + + h, err := New(WithBaseDir(tmpDir)) + require.NoError(t, err) + + // Create a message longer than bufio.Scanner's default 64KB limit + longMessage := make([]byte, 100*1024) // 100KB + for i := range longMessage { + longMessage[i] = 'a' + byte(i%26) + } + longStr := string(longMessage) + + require.NoError(t, h.Add(longStr)) + require.NoError(t, h.Add("short message after")) + + // Reload history from disk + h2, err := New(WithBaseDir(tmpDir)) + require.NoError(t, err) + + require.Len(t, h2.Messages, 2) + assert.Equal(t, longStr, h2.Messages[0]) + assert.Equal(t, "short message after", h2.Messages[1]) +}