mirror of
https://github.com/turbot/steampipe.git
synced 2025-12-19 18:12:43 -05:00
* Add test for #4811: query history should have bounded size * Fix #4811: Enforce bounded size for query history Add enforceLimit() helper that ensures history never exceeds HistorySize. Call it from Get(), Push(), and load() to prevent unbounded memory growth even when history is pre-populated from file or direct manipulation.
This commit is contained in:
@@ -38,14 +38,11 @@ func (q *QueryHistory) Push(query string) {
|
||||
return
|
||||
}
|
||||
|
||||
// limit the history length to HistorySize
|
||||
historyLength := len(q.history)
|
||||
if historyLength >= constants.HistorySize {
|
||||
q.history = q.history[historyLength-constants.HistorySize+1:]
|
||||
}
|
||||
|
||||
// append the new entry
|
||||
q.history = append(q.history, query)
|
||||
|
||||
// enforce the size limit after adding
|
||||
q.enforceLimit()
|
||||
}
|
||||
|
||||
// Peek returns the last element of the history stack.
|
||||
@@ -78,11 +75,22 @@ func (q *QueryHistory) Persist() error {
|
||||
return jsonEncoder.Encode(q.history)
|
||||
}
|
||||
|
||||
// Get returns the full history
|
||||
// Get returns the full history, enforcing the size limit
|
||||
func (q *QueryHistory) Get() []string {
|
||||
// Ensure history doesn't exceed the limit before returning
|
||||
q.enforceLimit()
|
||||
return q.history
|
||||
}
|
||||
|
||||
// enforceLimit ensures the history size doesn't exceed HistorySize
|
||||
func (q *QueryHistory) enforceLimit() {
|
||||
historyLength := len(q.history)
|
||||
if historyLength > constants.HistorySize {
|
||||
// Keep only the most recent HistorySize entries
|
||||
q.history = q.history[historyLength-constants.HistorySize:]
|
||||
}
|
||||
}
|
||||
|
||||
// loads up the history from the file where it is persisted
|
||||
func (q *QueryHistory) load() error {
|
||||
path := filepath.Join(filepaths.EnsureInternalDir(), constants.HistoryFile)
|
||||
@@ -103,5 +111,12 @@ func (q *QueryHistory) load() error {
|
||||
if err == io.EOF {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Enforce size limit after loading from file to prevent unbounded growth
|
||||
// in case the file was corrupted or manually edited
|
||||
if err == nil {
|
||||
q.enforceLimit()
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
39
pkg/query/queryhistory/history_test.go
Normal file
39
pkg/query/queryhistory/history_test.go
Normal file
@@ -0,0 +1,39 @@
|
||||
package queryhistory
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/turbot/steampipe/v2/pkg/constants"
|
||||
)
|
||||
|
||||
// TestQueryHistory_BoundedSize tests that query history doesn't grow unbounded.
|
||||
// This test demonstrates bug #4811 where history could grow without limit in memory
|
||||
// during a session, even though Push() limits new additions.
|
||||
//
|
||||
// Bug: #4811
|
||||
func TestQueryHistory_BoundedSize(t *testing.T) {
|
||||
// t.Skip("Test demonstrates bug #4811: query history grows unbounded in memory during session")
|
||||
|
||||
// Simulate a scenario where history is pre-populated (e.g., from a corrupted file or direct manipulation)
|
||||
// This represents the in-memory history during a long-running session
|
||||
oversizedHistory := make([]string, constants.HistorySize+100)
|
||||
for i := 0; i < len(oversizedHistory); i++ {
|
||||
oversizedHistory[i] = fmt.Sprintf("SELECT %d;", i)
|
||||
}
|
||||
|
||||
history := &QueryHistory{history: oversizedHistory}
|
||||
|
||||
// Even with pre-existing oversized history, operations should enforce the limit
|
||||
// Get() should never return more than HistorySize entries
|
||||
retrieved := history.Get()
|
||||
if len(retrieved) > constants.HistorySize {
|
||||
t.Errorf("Get() returned %d entries, exceeds limit %d", len(retrieved), constants.HistorySize)
|
||||
}
|
||||
|
||||
// After any operation, the internal history should be bounded
|
||||
history.Push("SELECT new;")
|
||||
if len(history.history) > constants.HistorySize {
|
||||
t.Errorf("After Push(), history size %d exceeds limit %d", len(history.history), constants.HistorySize)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user