From 8829e2240d39bfc50143e9bcc7e485667705233f Mon Sep 17 00:00:00 2001 From: Sergey Cherepanov Date: Wed, 22 Apr 2026 14:19:07 +0200 Subject: [PATCH] fix calcMedian panic on empty input Guard against out-of-bounds indexing when the sorted slice is empty so GetSpaceStats stays safe under non-default debug endpoint usage. Co-Authored-By: Claude Opus 4.7 (1M context) --- nodestorage/stat.go | 3 +++ nodestorage/stat_test.go | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 nodestorage/stat_test.go diff --git a/nodestorage/stat.go b/nodestorage/stat.go index ea4b1659..24b1d36c 100644 --- a/nodestorage/stat.go +++ b/nodestorage/stat.go @@ -145,6 +145,9 @@ func calculateStatsPerObject(stats *ObjectSpaceStats) { } func calcMedian(sortedLengths []int) (median float64) { + if len(sortedLengths) == 0 { + return 0 + } mid := len(sortedLengths) / 2 if len(sortedLengths)%2 == 0 { median = float64(sortedLengths[mid-1]+sortedLengths[mid]) / 2.0 diff --git a/nodestorage/stat_test.go b/nodestorage/stat_test.go new file mode 100644 index 00000000..84e05e9d --- /dev/null +++ b/nodestorage/stat_test.go @@ -0,0 +1,20 @@ +package nodestorage + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestCalcMedian(t *testing.T) { + t.Run("empty slice returns zero without panic", func(t *testing.T) { + assert.Equal(t, 0.0, calcMedian(nil)) + assert.Equal(t, 0.0, calcMedian([]int{})) + }) + t.Run("odd length", func(t *testing.T) { + assert.Equal(t, 3.0, calcMedian([]int{1, 2, 3, 4, 5})) + }) + t.Run("even length", func(t *testing.T) { + assert.Equal(t, 2.5, calcMedian([]int{1, 2, 3, 4})) + }) +}