Skip to content

Commit a1600af

Browse files
committed
expfmt: fix nil pointer panic when parsing empty braces "{}"
The text exposition parser panics with a nil pointer dereference when it encounters a closing brace before any metric name has been read, e.g. for the input "{}". In startOfLine a leading "{" sets currentMetricIsInsideBraces and jumps straight to label parsing without going through readingMetricName, so currentMF/currentMetric are still nil when startLabelName dereferences currentMetric on the "}" branch. Since TextToMetricFamilies is used to decode untrusted scrape payloads, a malicious or compromised target could crash any consumer that does not wrap the parser in its own recover(). Guard the "}" branch on currentMF == nil and return a parse error, mirroring the existing guard in startLabelValue. currentMF is checked rather than currentMetric because reset only clears currentMF between parses. Introduced in #670. Signed-off-by: Julien Pivotto <291750+roidelapluie@users.noreply.github.com>
1 parent c7fb7bb commit a1600af

2 files changed

Lines changed: 16 additions & 0 deletions

File tree

expfmt/text_parse.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,16 @@ func (p *TextParser) startLabelName() stateFn {
339339
return nil // Unexpected end of input.
340340
}
341341
if p.currentByte == '}' {
342+
if p.currentMF == nil {
343+
// The closing brace was reached before any metric name was read,
344+
// e.g. for the input "{}". There is no metric to attach labels to,
345+
// so this is a malformed exposition. This mirrors the guard in
346+
// startLabelValue. currentMF (not currentMetric) is checked because
347+
// reset only clears currentMF between parses.
348+
p.parseError("invalid metric name")
349+
p.currentLabelPairs = nil
350+
return nil
351+
}
342352
p.currentMetric.Label = append(p.currentMetric.Label, p.currentLabelPairs...)
343353
p.currentLabelPairs = nil
344354
if p.skipBlankTab(); p.err != nil {

expfmt/text_parse_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1332,6 +1332,12 @@ request_duration_microseconds_count 2693
13321332
`,
13331333
errUTF8: `text format parsing error in line 5: negative bucket population for histogram "request_duration_microseconds"`,
13341334
},
1335+
// 47: Empty braces with no metric name (regression test for a nil
1336+
// pointer dereference in startLabelName).
1337+
{
1338+
in: `{} 3.14`,
1339+
errUTF8: "text format parsing error in line 1: invalid metric name",
1340+
},
13351341
}
13361342
for i, scenario := range scenarios {
13371343
parser.scheme = model.UTF8Validation

0 commit comments

Comments
 (0)