Merge pull request #17287 from linasm/reject-nan-histogram-custom-bounds

NHCB: Reject custom bucket bounds with NaN value
This commit is contained in:
George Krajcsovits 2025-10-06 18:11:03 +02:00 committed by GitHub
commit fe11cae637
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 26 additions and 0 deletions

View File

@ -38,6 +38,7 @@ var (
ErrHistogramCustomBucketsMismatch = errors.New("histogram custom bounds are too few") ErrHistogramCustomBucketsMismatch = errors.New("histogram custom bounds are too few")
ErrHistogramCustomBucketsInvalid = errors.New("histogram custom bounds must be in strictly increasing order") ErrHistogramCustomBucketsInvalid = errors.New("histogram custom bounds must be in strictly increasing order")
ErrHistogramCustomBucketsInfinite = errors.New("histogram custom bounds must be finite") ErrHistogramCustomBucketsInfinite = errors.New("histogram custom bounds must be finite")
ErrHistogramCustomBucketsNaN = errors.New("histogram custom bounds must not be NaN")
ErrHistogramsIncompatibleSchema = errors.New("cannot apply this operation on histograms with a mix of exponential and custom bucket schemas") ErrHistogramsIncompatibleSchema = errors.New("cannot apply this operation on histograms with a mix of exponential and custom bucket schemas")
ErrHistogramsIncompatibleBounds = errors.New("cannot apply this operation on custom buckets histograms with different custom bounds") ErrHistogramsIncompatibleBounds = errors.New("cannot apply this operation on custom buckets histograms with different custom bounds")
ErrHistogramCustomBucketsZeroCount = errors.New("custom buckets: must have zero count of 0") ErrHistogramCustomBucketsZeroCount = errors.New("custom buckets: must have zero count of 0")
@ -454,6 +455,9 @@ func checkHistogramBuckets[BC BucketCount, IBC InternalBucketCount](buckets []IB
func checkHistogramCustomBounds(bounds []float64, spans []Span, numBuckets int) error { func checkHistogramCustomBounds(bounds []float64, spans []Span, numBuckets int) error {
prev := math.Inf(-1) prev := math.Inf(-1)
for _, curr := range bounds { for _, curr := range bounds {
if math.IsNaN(curr) {
return ErrHistogramCustomBucketsNaN
}
if curr <= prev { if curr <= prev {
return fmt.Errorf("previous bound is %f and current is %f: %w", prev, curr, ErrHistogramCustomBucketsInvalid) return fmt.Errorf("previous bound is %f and current is %f: %w", prev, curr, ErrHistogramCustomBucketsInvalid)
} }

View File

@ -1565,6 +1565,27 @@ func TestHistogramValidation(t *testing.T) {
CustomValues: []float64{1, 2, 3, 4, 5, 6, 7, 8}, CustomValues: []float64{1, 2, 3, 4, 5, 6, 7, 8},
}, },
}, },
"reject custom buckets histogram with non-increasing bound": {
h: &Histogram{
Schema: CustomBucketsSchema,
CustomValues: []float64{0, 0},
},
errMsg: "custom buckets: previous bound is 0.000000 and current is 0.000000: histogram custom bounds must be in strictly increasing order",
},
"reject custom buckets histogram with explicit +Inf bound": {
h: &Histogram{
Schema: CustomBucketsSchema,
CustomValues: []float64{1, math.Inf(1)},
},
errMsg: "custom buckets: last +Inf bound must not be explicitly defined: histogram custom bounds must be finite",
},
"reject custom buckets histogram with NaN bound": {
h: &Histogram{
Schema: CustomBucketsSchema,
CustomValues: []float64{1, math.NaN(), 3},
},
errMsg: "custom buckets: histogram custom bounds must not be NaN",
},
"schema too high": { "schema too high": {
h: &Histogram{ h: &Histogram{
Schema: 10, Schema: 10,

View File

@ -129,6 +129,7 @@ func isHistogramValidationError(err error) bool {
errors.Is(err, histogram.ErrHistogramCustomBucketsMismatch) || errors.Is(err, histogram.ErrHistogramCustomBucketsMismatch) ||
errors.Is(err, histogram.ErrHistogramCustomBucketsInvalid) || errors.Is(err, histogram.ErrHistogramCustomBucketsInvalid) ||
errors.Is(err, histogram.ErrHistogramCustomBucketsInfinite) || errors.Is(err, histogram.ErrHistogramCustomBucketsInfinite) ||
errors.Is(err, histogram.ErrHistogramCustomBucketsNaN) ||
errors.Is(err, histogram.ErrHistogramCustomBucketsZeroCount) || errors.Is(err, histogram.ErrHistogramCustomBucketsZeroCount) ||
errors.Is(err, histogram.ErrHistogramCustomBucketsZeroThresh) || errors.Is(err, histogram.ErrHistogramCustomBucketsZeroThresh) ||
errors.Is(err, histogram.ErrHistogramCustomBucketsNegSpans) || errors.Is(err, histogram.ErrHistogramCustomBucketsNegSpans) ||