Skip to content

Commit

Permalink
Support UTF-8 label matchers: Do not allow unquoted escape sequences (#…
Browse files Browse the repository at this point in the history
…3571)

* Do not allow unquoted escape sequences

This commit updates the matchers parser to reject unquoted
openmetrics escape sequences. As an example, foo=bar\n
will no longer parse, and must instead be written as
foo="bar\n". This avoids an issue where the input is valid
in both the matchers and classic parsers, but results
in two different parsings.

---------

Signed-off-by: George Robinson <[email protected]>
  • Loading branch information
grobinson-grafana authored Oct 30, 2023
1 parent 8512285 commit b5b5a1d
Show file tree
Hide file tree
Showing 4 changed files with 12 additions and 5 deletions.
8 changes: 4 additions & 4 deletions matchers/compat/parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ func TestFallbackMatcherParser(t *testing.T) {
expected: mustNewMatcher(t, labels.MatchEqual, "foo🙂", "bar"),
}, {
name: "is accepted in old parser but not new",
input: "foo=!bar",
expected: mustNewMatcher(t, labels.MatchEqual, "foo", "!bar"),
input: "foo=!bar\\n",
expected: mustNewMatcher(t, labels.MatchEqual, "foo", "!bar\n"),
}, {
name: "is accepted in neither",
input: "foo!bar",
Expand Down Expand Up @@ -81,10 +81,10 @@ func TestFallbackMatchersParser(t *testing.T) {
},
}, {
name: "is accepted in old parser but not new",
input: "{foo=!bar,bar=$baz}",
input: "{foo=!bar,bar=$baz\\n}",
expected: labels.Matchers{
mustNewMatcher(t, labels.MatchEqual, "foo", "!bar"),
mustNewMatcher(t, labels.MatchEqual, "bar", "$baz"),
mustNewMatcher(t, labels.MatchEqual, "bar", "$baz\n"),
},
}, {
name: "is accepted in neither",
Expand Down
3 changes: 3 additions & 0 deletions matchers/compliance/compliance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ func TestCompliance(t *testing.T) {
m, _ := labels.NewMatcher(labels.MatchEqual, "foo", "\\t")
return append(ms, m)
}(),
skip: true,
},
{
input: `{foo=bar\t}`,
Expand All @@ -84,6 +85,7 @@ func TestCompliance(t *testing.T) {
m, _ := labels.NewMatcher(labels.MatchEqual, "foo", "bar\\t")
return append(ms, m)
}(),
skip: true,
},
{
input: `{foo=bar\}`,
Expand All @@ -92,6 +94,7 @@ func TestCompliance(t *testing.T) {
m, _ := labels.NewMatcher(labels.MatchEqual, "foo", "bar\\")
return append(ms, m)
}(),
skip: true,
},
{
input: `{foo=bar\\}`,
Expand Down
2 changes: 1 addition & 1 deletion matchers/parse/lexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const (
)

func isReserved(r rune) bool {
return unicode.IsSpace(r) || strings.ContainsRune("{}!=~,\"'`", r)
return unicode.IsSpace(r) || strings.ContainsRune("{}!=~,\\\"'`", r)
}

// expectedError is returned when the next rune does not match what is expected.
Expand Down
4 changes: 4 additions & 0 deletions matchers/parse/parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,10 @@ func TestMatchers(t *testing.T) {
name: "invalid escape sequence",
input: "{foo=\"bar\\w\"}",
error: "5:12: \"bar\\w\": invalid input",
}, {
name: "no unquoted escape sequences",
input: "{foo=bar\\n}",
error: "8:9: \\: invalid input: expected a comma or close brace",
}}

for _, test := range tests {
Expand Down

0 comments on commit b5b5a1d

Please sign in to comment.