diff --git a/pkg/jsonpath/parser_test.go b/pkg/jsonpath/parser_test.go index 46996b0..85f9878 100644 --- a/pkg/jsonpath/parser_test.go +++ b/pkg/jsonpath/parser_test.go @@ -158,6 +158,18 @@ func TestParserPropertyNameExtension(t *testing.T) { enabled: false, valid: false, }, + { + name: "Missing closing a filter expression shouldn't crash", + input: "$.paths.*.*[?(!@.servers)", + enabled: false, + valid: false, + }, + { + name: "Missing closing a array crash", + input: "$.paths.*[?@[\"x-my-ignore\"]", + enabled: false, + valid: false, + }, } for _, test := range tests { diff --git a/pkg/jsonpath/token/token.go b/pkg/jsonpath/token/token.go index 948a719..6cf1654 100644 --- a/pkg/jsonpath/token/token.go +++ b/pkg/jsonpath/token/token.go @@ -533,6 +533,9 @@ func (t *Tokenizer) Tokenize() Tokens { t.column++ } + if len(t.stack) > 0 { + t.addToken(ILLEGAL, 1, fmt.Sprintf("unmatched %s", t.stack[len(t.stack)-1].String())) + } return t.tokens } diff --git a/pkg/jsonpath/token/token_test.go b/pkg/jsonpath/token/token_test.go index 459350d..d8c7931 100644 --- a/pkg/jsonpath/token/token_test.go +++ b/pkg/jsonpath/token/token_test.go @@ -413,7 +413,7 @@ func TestTokenizer_categorize(t *testing.T) { {name: "dot child with malformed array subscript", path: "$.child[1:2:3:4]"}, {name: "dot child with array subscript with zero step", path: "$.child[1:2:0]"}, {name: "dot child with non-integer array subscript", path: "$.child[1:2:a]"}, - {name: "dot child with unclosed array subscript", path: "$.child[*"}, + {name: "dot child with unclosed array subscript", path: "$.child[*", illegal: true}, {name: "dot child with missing array subscript", path: "$.child[]", simple: true}, {name: "dot child with embedded space", path: "$.child more", simple: true}, {name: "bracket child", path: "$['child']", simple: true}, @@ -429,7 +429,7 @@ func TestTokenizer_categorize(t *testing.T) { {name: "bracket child with array subscript", path: "$['child'][*]"}, {name: "bracket child with malformed array subscript", path: "$['child'][1:2:3:4]"}, {name: "bracket child with non-integer array subscript", path: "$['child'][1:2:a]"}, - {name: "bracket child with unclosed array subscript", path: "$['child'][*"}, + {name: "bracket child with unclosed array subscript", path: "$['child'][*", illegal: true}, {name: "bracket child with missing array subscript", path: "$['child'][]", simple: true}, {name: "bracket child followed by space", path: "$['child'] ", illegal: true}, {name: "bracket dotted child", path: "$['child1.child2']", simple: true}, @@ -497,7 +497,7 @@ func TestTokenizer_categorize(t *testing.T) { {name: "simple filter with bracket with extra whitespace", path: "$[?( ( @.child ) )]"}, {name: "simple filter with more complex subpath", path: "$[?((@.child[0]))]"}, {name: "missing filter ", path: "$[?()]"}, - {name: "unclosed filter", path: "$[?("}, + {name: "unclosed filter", path: "$[?(", illegal: true}, {name: "filter with missing operator", path: "$[?(@.child @.other)]"}, {name: "filter with malformed term", path: "$[?([)]", illegal: true}, {name: "filter with misplaced open bracket", path: "$[?(@.child ()]", illegal: true}, @@ -564,13 +564,13 @@ func TestTokenizer_categorize(t *testing.T) { {name: "filter conjunction", path: "$[?(@.child&&@.other)]"}, {name: "filter conjunction with literals and whitespace", path: "$[?(@.child == 'x' && -9 == @.other)]"}, {name: "filter conjunction with bracket children", path: "$[?(@['child'][*]&&@['other'])]"}, - {name: "filter invalid leading conjunction", path: "$[?(&&"}, + {name: "filter invalid leading conjunction", path: "$[?(&&", illegal: true}, {name: "filter conjunction with extra whitespace", path: "$[?(@.child && @.other)]"}, {name: "filter disjunction", path: "$[?(@.child||@.other)]"}, - {name: "filter invalid leading disjunction", path: "$[?(||"}, + {name: "filter invalid leading disjunction", path: "$[?(||", illegal: true}, {name: "filter disjunction with extra whitespace", path: "$[?(@.child || @.other)]"}, {name: "simple filter of child", path: "$.child[?(@.child)]"}, - {name: "filter with missing end", path: "$[?(@.child"}, + {name: "filter with missing end", path: "$[?(@.child", illegal: true}, {name: "nested filter (edge case)", path: "$[?(@.y[?(@.z)])]"}, {name: "filter negation", path: "$[?(!@.child)]"}, {name: "filter negation of comparison (edge case)", path: "$[?(!@.child>1)]"},