diff --git a/pkg/textparse/openmetricsparse.go b/pkg/textparse/openmetricsparse.go index 6cfdd8391..e3c09e97e 100644 --- a/pkg/textparse/openmetricsparse.go +++ b/pkg/textparse/openmetricsparse.go @@ -336,6 +336,9 @@ func (p *OpenMetricsParser) Next() (Entry, error) { if ts, err = parseFloat(yoloString(p.l.buf()[1:])); err != nil { return EntryInvalid, err } + if math.IsNaN(ts) || math.IsInf(ts, 0) { + return EntryInvalid, errors.New("invalid timestamp") + } p.ts = int64(ts * 1000) switch t3 := p.nextToken(); t3 { case tLinebreak: @@ -392,6 +395,9 @@ func (p *OpenMetricsParser) parseComment() error { if ts, err = parseFloat(yoloString(p.l.buf()[1:])); err != nil { return err } + if math.IsNaN(ts) || math.IsInf(ts, 0) { + return errors.New("invalid exemplar timestamp") + } p.exemplarTs = int64(ts * 1000) switch t3 := p.nextToken(); t3 { case tLinebreak: diff --git a/pkg/textparse/openmetricsparse_test.go b/pkg/textparse/openmetricsparse_test.go index 39567650c..9a19a2f4d 100644 --- a/pkg/textparse/openmetricsparse_test.go +++ b/pkg/textparse/openmetricsparse_test.go @@ -504,6 +504,30 @@ func TestOpenMetricsParseErrors(t *testing.T) { input: `{b="c",} 1`, err: `"INVALID" "{" is not a valid start token`, }, + { + input: `a 1 NaN`, + err: `invalid timestamp`, + }, + { + input: `a 1 -Inf`, + err: `invalid timestamp`, + }, + { + input: `a 1 Inf`, + err: `invalid timestamp`, + }, + { + input: "# TYPE hhh histogram\nhhh_bucket{le=\"+Inf\"} 1 # {aa=\"bb\"} 4 NaN", + err: `invalid exemplar timestamp`, + }, + { + input: "# TYPE hhh histogram\nhhh_bucket{le=\"+Inf\"} 1 # {aa=\"bb\"} 4 -Inf", + err: `invalid exemplar timestamp`, + }, + { + input: "# TYPE hhh histogram\nhhh_bucket{le=\"+Inf\"} 1 # {aa=\"bb\"} 4 Inf", + err: `invalid exemplar timestamp`, + }, } for i, c := range cases {