pkg/textparse: support null bytes in comments and help

Signed-off-by: Fabian Reinartz <freinartz@google.com>
pull/4162/head
Fabian Reinartz 7 years ago
parent 76a4a46cb0
commit 5fcc5b6028

@ -28,9 +28,8 @@ import (
"unicode/utf8" "unicode/utf8"
"unsafe" "unsafe"
"github.com/prometheus/prometheus/pkg/value"
"github.com/prometheus/prometheus/pkg/labels" "github.com/prometheus/prometheus/pkg/labels"
"github.com/prometheus/prometheus/pkg/value"
) )
type lexer struct { type lexer struct {
@ -122,9 +121,9 @@ func (l *lexer) next() byte {
l.err = io.EOF l.err = io.EOF
return byte(tEOF) 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. // 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++ l.i++
} }
return l.b[l.i] return l.b[l.i]
@ -280,7 +279,8 @@ func (p *Parser) Next() (Entry, error) {
default: default:
return EntryInvalid, parseError("expected text in HELP", t) return EntryInvalid, parseError("expected text in HELP", t)
} }
if t == tType { switch t {
case tType:
switch s := yoloString(p.text); s { switch s := yoloString(p.text); s {
case "counter": case "counter":
p.mtype = MetricTypeCounter p.mtype = MetricTypeCounter
@ -295,6 +295,10 @@ func (p *Parser) Next() (Entry, error) {
default: default:
return EntryInvalid, fmt.Errorf("invalid metric type %q", s) 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 { if t := p.nextToken(); t != tLinebreak {
return EntryInvalid, parseError("linebreak expected after metadata", t) return EntryInvalid, parseError("linebreak expected after metadata", t)

@ -51,6 +51,7 @@ go_goroutines 33 123123
_metric_starting_with_underscore 1 _metric_starting_with_underscore 1
testmetric{_label_starting_with_underscore="foo"} 1 testmetric{_label_starting_with_underscore="foo"} 1
testmetric{label="\"bar\""} 1` testmetric{label="\"bar\""} 1`
input += "\n# HELP metric foo\x00bar"
input += "\nnull_byte_metric{a=\"abc\x00\"} 1" input += "\nnull_byte_metric{a=\"abc\x00\"} 1"
int64p := func(x int64) *int64 { return &x } int64p := func(x int64) *int64 { return &x }
@ -145,6 +146,9 @@ testmetric{label="\"bar\""} 1`
m: "testmetric{label=\"\\\"bar\\\"\"}", m: "testmetric{label=\"\\\"bar\\\"\"}",
v: 1, v: 1,
lset: labels.FromStrings("__name__", "testmetric", "label", `"bar"`), lset: labels.FromStrings("__name__", "testmetric", "label", `"bar"`),
}, {
m: "metric",
help: "foo\x00bar",
}, { }, {
m: "null_byte_metric{a=\"abc\x00\"}", m: "null_byte_metric{a=\"abc\x00\"}",
v: 1, v: 1,

Loading…
Cancel
Save