Browse Source

Reject scrapes with invalid utf-8 label values.

pull/2869/head
Brian Brazil 8 years ago
parent
commit
a6ca391e6e
  1. 5
      pkg/textparse/lex.l
  2. 5
      pkg/textparse/lex.l.go
  3. 31
      pkg/textparse/parse_test.go
  4. 23
      retrieval/scrape_test.go

5
pkg/textparse/lex.l

@ -18,6 +18,7 @@ import (
"fmt"
"math"
"strconv"
"unicode/utf8"
"github.com/prometheus/prometheus/pkg/value"
)
@ -82,6 +83,10 @@ M [a-zA-Z_:]
l.offsets = append(l.offsets, l.i-1)
<lstateLValue>\"(\\.|[^\\"]|\0)*\" s = lstateLabels
if !utf8.Valid(l.b[l.offsets[len(l.offsets)-1]+2:l.i-1]) {
l.err = fmt.Errorf("Invalid UTF-8 label value.")
return -1
}
l.offsets = append(l.offsets, l.i-1)
<lstateLValue>\'(\\.|[^\\']|\0)*\' s = lstateLabels
l.offsets = append(l.offsets, l.i-1)

5
pkg/textparse/lex.l.go

@ -19,6 +19,7 @@ import (
"fmt"
"math"
"strconv"
"unicode/utf8"
"github.com/prometheus/prometheus/pkg/value"
)
@ -413,6 +414,10 @@ yyrule9: // {S}({L}|{D})*=
yyrule10: // \"(\\.|[^\\"]|\0)*\"
{
s = lstateLabels
if !utf8.Valid(l.b[l.offsets[len(l.offsets)-1]+2 : l.i-1]) {
l.err = fmt.Errorf("Invalid UTF-8 label value.")
return -1
}
l.offsets = append(l.offsets, l.i-1)
goto yystate0
}

31
pkg/textparse/parse_test.go

@ -104,6 +104,37 @@ go_goroutines 33 123123`
}
func TestParseErrors(t *testing.T) {
cases := []struct {
input string
err string
}{
{
input: "a",
err: "no token found",
},
{
input: "a{\xff=\"foo\"} 1\n",
err: "no token found",
},
{
input: "a{b=\"\xff\"} 1\n",
err: "Invalid UTF-8 label value.",
},
{
input: "a true\n",
err: "strconv.ParseFloat: parsing \"true\": invalid syntax",
},
}
for _, c := range cases {
p := New([]byte(c.input))
for p.Next() {
}
require.Equal(t, c.err, p.Err().Error())
}
}
const (
testdataSampleCount = 410
)

23
retrieval/scrape_test.go

@ -844,6 +844,29 @@ func TestScrapeLoopRunReportsTargetDownOnScrapeError(t *testing.T) {
}
}
func TestScrapeLoopRunReportsTargetDownOnInvalidUTF8(t *testing.T) {
var (
scraper = &testScraper{}
reportAppender = &collectResultAppender{}
reportApp = func() storage.Appender { return reportAppender }
)
ctx, cancel := context.WithCancel(context.Background())
sl := newScrapeLoop(ctx, scraper, func() storage.Appender { return nopAppender{} }, reportApp, nil)
scraper.scrapeFunc = func(ctx context.Context, w io.Writer) error {
cancel()
w.Write([]byte("a{l=\"\xff\"} 0\n"))
return nil
}
sl.run(10*time.Millisecond, time.Hour, nil)
if reportAppender.result[0].v != 0 {
t.Fatalf("bad 'up' value; want 0, got %v", reportAppender.result[0].v)
}
}
type errorAppender struct {
collectResultAppender
}

Loading…
Cancel
Save