From 0dd31db8137094ad692e75ba15365e4e0039ae47 Mon Sep 17 00:00:00 2001 From: Joe Elliott Date: Mon, 15 Apr 2024 11:09:14 -0400 Subject: [PATCH] Fix parsing of traceql queries longer than 1024 chars (#3571) * fix really long static vals Signed-off-by: Joe Elliott * protect against long attr names as well Signed-off-by: Joe Elliott --------- Signed-off-by: Joe Elliott --- pkg/traceql/lexer.go | 12 +++++++++++- pkg/traceql/parse_test.go | 25 +++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/pkg/traceql/lexer.go b/pkg/traceql/lexer.go index df98c74e1e0..3bf4374ba2e 100644 --- a/pkg/traceql/lexer.go +++ b/pkg/traceql/lexer.go @@ -270,14 +270,24 @@ func parseQuotedAtrribute(s *scanner.Scanner) (string, error) { } func tryScopeAttribute(l *scanner.Scanner, currentScope int) (int, bool) { + const longestScope = 9 // "resource." is the longest scope + // copy the scanner to avoid advancing if it's not a scope. s := *l str := "" for s.Peek() != scanner.EOF { - if s.Peek() == '.' { + r := s.Peek() + if r == '.' { // we've found a scope attribute str += string(s.Next()) break } + if !isAttributeRune(r) { // we can't have a scope with invalid characters, so just bail + break + } + if len(str) > longestScope { // we can't have a scope longer than the longest scope, so just bail + break + } + str += string(s.Next()) } tok := tokens[str] diff --git a/pkg/traceql/parse_test.go b/pkg/traceql/parse_test.go index 2c043605c85..4ef7d53d9b9 100644 --- a/pkg/traceql/parse_test.go +++ b/pkg/traceql/parse_test.go @@ -1,6 +1,7 @@ package traceql import ( + "fmt" "strings" "testing" "time" @@ -1166,3 +1167,27 @@ func TestHints(t *testing.T) { }) } } + +func TestReallyLongQuery(t *testing.T) { + for i := 1000; i < 1050; i++ { + longVal := strings.Repeat("a", i) + + // static value + query := fmt.Sprintf("{ .a = `%s` }", longVal) + expected := newBinaryOperation(OpEqual, NewAttribute("a"), NewStaticString(longVal)) + + actual, err := Parse(query) + + require.NoError(t, err, "i=%d", i) + require.Equal(t, newRootExpr(newPipeline(newSpansetFilter(expected))), actual, "i=%d", i) + + // attr name + query = fmt.Sprintf("{ .%s = `foo` }", longVal) + expected = newBinaryOperation(OpEqual, NewAttribute(longVal), NewStaticString("foo")) + + actual, err = Parse(query) + + require.NoError(t, err, "i=%d", i) + require.Equal(t, newRootExpr(newPipeline(newSpansetFilter(expected))), actual, "i=%d", i) + } +}