From f5d456f6e716f78b5b350dd30dba956142986cae Mon Sep 17 00:00:00 2001 From: magiccwarss Date: Sat, 7 Nov 2026 16:57:22 +0400 Subject: [PATCH] Require an unquoted identifier immediately before function calls --- jmespath/parser.py | 3 +- tests/compliance/function_name_syntax.json | 72 ++++++++++++++++++++++ 2 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 tests/compliance/function_name_syntax.json diff --git a/jmespath/parser.py b/jmespath/parser.py index cc8e804e..b744b5a6 100644 --- a/jmespath/parser.py +++ b/jmespath/parser.py @@ -282,7 +282,8 @@ def _token_led_and(self, left): return ast.and_expression(left, right) def _token_led_lparen(self, left): - if left['type'] != 'field': + if (left['type'] != 'field' or + self._lookahead(-2) != 'unquoted_identifier'): # 0 - first func arg or closing paren. # -1 - '(' token # -2 - invalid function "name". diff --git a/tests/compliance/function_name_syntax.json b/tests/compliance/function_name_syntax.json new file mode 100644 index 00000000..52e4c9b7 --- /dev/null +++ b/tests/compliance/function_name_syntax.json @@ -0,0 +1,72 @@ +[ + { + "given": { + "foo": 1, + "bar": 2, + "items": [ + { + "foo": 2 + }, + { + "foo": 1 + } + ], + "length": "value" + }, + "cases": [ + { + "expression": "(length)(@)", + "error": "syntax" + }, + { + "expression": "(\"length\")(@)", + "error": "syntax" + }, + { + "expression": "((length))(@)", + "error": "syntax" + }, + { + "expression": "((\"length\"))(@)", + "error": "syntax" + }, + { + "expression": "to_array((length)(@))", + "error": "syntax" + }, + { + "expression": "[(\"length\")(@)]", + "error": "syntax" + }, + { + "expression": "\"length\"(@)", + "error": "syntax" + }, + { + "expression": "length(@)", + "result": 4 + }, + { + "expression": "(length(@))", + "result": 4 + }, + { + "expression": "to_array(length(@))", + "result": [ + 4 + ] + }, + { + "expression": "items[].length(@)", + "result": [ + 1, + 1 + ] + }, + { + "expression": "\"length\"", + "result": "value" + } + ] + } +]