From 9058914c00c80046e0186918f274586c7162382d Mon Sep 17 00:00:00 2001 From: Harris Bisset Date: Sun, 29 Dec 2024 09:52:48 +0000 Subject: [PATCH] fix: parser hangs when a bracket isn't closed (#1005) (#1029) Co-authored-by: harrisbisset Co-authored-by: Harris Bisset Co-authored-by: Adrian Hesketh --- parser/v2/goexpression/parse_test.go | 12 ++++++++++ parser/v2/goexpression/scanner.go | 10 +++++++++ parser/v2/templelementparser_test.go | 33 ++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/parser/v2/goexpression/parse_test.go b/parser/v2/goexpression/parse_test.go index 702b80751..1d0c71c04 100644 --- a/parser/v2/goexpression/parse_test.go +++ b/parser/v2/goexpression/parse_test.go @@ -354,6 +354,18 @@ var expressionTests = []testInput{ name: "string concat", input: `direction + "newest"`, }, + { + name: "function call", + input: `SplitRule(types.GroupMember{ + UserID: uuid.NewString(), + Username: "user me", +}, []types.GroupMember{ + { + UserID: uuid.NewString(), + Username: "user 1", + }, +})`, + }, } func TestExpression(t *testing.T) { diff --git a/parser/v2/goexpression/scanner.go b/parser/v2/goexpression/scanner.go index fb9b8a94c..82ad94a23 100644 --- a/parser/v2/goexpression/scanner.go +++ b/parser/v2/goexpression/scanner.go @@ -82,6 +82,16 @@ func (ep *ExpressionParser) Insert( defer func() { ep.Previous = tok }() + + // If we've reach the end of the file, terminate reading. + if tok == token.EOF { + // If the EOF was reached, but we're not at the top level, we must have an unbalanced expression. + if !ep.isTopLevel() { + return true, ErrUnbalanced{ep.Stack.Pop()} + } + return true, nil + } + // Handle function literals e.g. func() { fmt.Println("Hello") } // By pushing the current depth onto the stack, we prevent stopping // until we've closed the function. diff --git a/parser/v2/templelementparser_test.go b/parser/v2/templelementparser_test.go index 478620dc3..ec5c58492 100644 --- a/parser/v2/templelementparser_test.go +++ b/parser/v2/templelementparser_test.go @@ -449,3 +449,36 @@ func TestTemplElementExpressionParser(t *testing.T) { }) } } + +func TestTemplElementExpressionParserFailures(t *testing.T) { + tests := []struct { + name string + input string + }{ + { + name: "templelement: missing closing brace", + input: `@SplitRule(types.GroupMember{ + UserID: uuid.NewString(), + Username: "user me", +}, []types.GroupMember{ + { + UserID: uuid.NewString(), + Username: "user 1", + }, +`, + }, + } + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + input := parse.NewInput(tt.input) + _, ok, err := templElementExpression.Parse(input) + if err == nil { + t.Fatalf("expected an error") + } + if ok { + t.Fatalf("expected a failure") + } + }) + } +}