From 5fcc5b602834d3bdbe8fcd9619c5810a5a783819 Mon Sep 17 00:00:00 2001 From: Fabian Reinartz Date: Fri, 1 Jun 2018 04:22:32 -0400 Subject: [PATCH] pkg/textparse: support null bytes in comments and help Signed-off-by: Fabian Reinartz --- pkg/textparse/parse.go | 14 +++++++++----- pkg/textparse/parse_test.go | 4 ++++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/pkg/textparse/parse.go b/pkg/textparse/parse.go index ccbca0cae..c8a347ec6 100644 --- a/pkg/textparse/parse.go +++ b/pkg/textparse/parse.go @@ -28,9 +28,8 @@ import ( "unicode/utf8" "unsafe" - "github.com/prometheus/prometheus/pkg/value" - "github.com/prometheus/prometheus/pkg/labels" + "github.com/prometheus/prometheus/pkg/value" ) type lexer struct { @@ -122,9 +121,9 @@ func (l *lexer) next() byte { l.err = io.EOF return byte(tEOF) } - // Lex struggles with null bytes. If we are in a label value, where + // Lex struggles with null bytes. If we are in a label value or help string, where // they are allowed, consume them here immediately. - for l.b[l.i] == 0 && l.state == sLValue { + for l.b[l.i] == 0 && (l.state == sLValue || l.state == sMeta2 || l.state == sComment) { l.i++ } return l.b[l.i] @@ -280,7 +279,8 @@ func (p *Parser) Next() (Entry, error) { default: return EntryInvalid, parseError("expected text in HELP", t) } - if t == tType { + switch t { + case tType: switch s := yoloString(p.text); s { case "counter": p.mtype = MetricTypeCounter @@ -295,6 +295,10 @@ func (p *Parser) Next() (Entry, error) { default: return EntryInvalid, fmt.Errorf("invalid metric type %q", s) } + case tHelp: + if !utf8.Valid(p.text) { + return EntryInvalid, fmt.Errorf("help text is not a valid utf8 string") + } } if t := p.nextToken(); t != tLinebreak { return EntryInvalid, parseError("linebreak expected after metadata", t) diff --git a/pkg/textparse/parse_test.go b/pkg/textparse/parse_test.go index b22cce7a1..3852bfdf1 100644 --- a/pkg/textparse/parse_test.go +++ b/pkg/textparse/parse_test.go @@ -51,6 +51,7 @@ go_goroutines 33 123123 _metric_starting_with_underscore 1 testmetric{_label_starting_with_underscore="foo"} 1 testmetric{label="\"bar\""} 1` + input += "\n# HELP metric foo\x00bar" input += "\nnull_byte_metric{a=\"abc\x00\"} 1" int64p := func(x int64) *int64 { return &x } @@ -145,6 +146,9 @@ testmetric{label="\"bar\""} 1` m: "testmetric{label=\"\\\"bar\\\"\"}", v: 1, lset: labels.FromStrings("__name__", "testmetric", "label", `"bar"`), + }, { + m: "metric", + help: "foo\x00bar", }, { m: "null_byte_metric{a=\"abc\x00\"}", v: 1,