From 32a5f9312a28b3e23f32bdac752d0560416f9f07 Mon Sep 17 00:00:00 2001 From: Kevin Brown Date: Fri, 15 May 2020 19:05:42 -0400 Subject: [PATCH] Fix parsing math1 expressions in comparisons When a math1 expression was used in a comparison before, the right side would consume the comparison instead of letting it fall back to the comparison being above it in the AST. This was fixed by restricting the right side of math1 comparisons to be complex operations only, so that is any operation that does not involve a comparison, since it's unlikely that you are looking to do math expressions on the result of a comparison. Additionally, this also allows conditional expressions involving basic operators to consume a complex expression on the left side. Previously they were restricted to only allowing variables on the left side, so this allows for more complex comparisons to be made. Because of the way that conditional expressions with parentheses are consumed, they have been moved to be the last check within conditional expressions. This should help to guard against other conditional expressions which can consume parenthese themselves from being blocked from parsing because the parentheses have already been consumed. In order to make things generally easier to understand, the complex expressions wihch return an actual value (instread of just comparisons) are now grouped together within the grammar. --- grammar.ebnf | 26 ++++++++++++++++++++------ src/jinja2/new_parser.py | 2 +- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/grammar.ebnf b/grammar.ebnf index b1e2295d..4707c162 100644 --- a/grammar.ebnf +++ b/grammar.ebnf @@ -286,16 +286,23 @@ variable_accessor_call_parameter_value conditional_expression = - | complex_expression_powers - | complex_expression_math2 - | concatenate_expression - | complex_expression_math1 | conditional_expression_not | conditional_expression_if | conditional_expression_logical | conditional_expression_operator | conditional_expression_test + | complex_expression + | variable_identifier | conditional_expression_parentheses + ; + +complex_expression + = + | complex_expression_powers + | complex_expression_math2 + | concatenate_expression + | complex_expression_math1 + | complex_expression_parentheses | variable_identifier ; @@ -323,7 +330,7 @@ complex_expression_math1 = left:variable_identifier {SP}* math_operator:complex_expression_math1_operations {SP}* - right:conditional_expression + right:complex_expression ; complex_expression_math1_operations @@ -332,6 +339,13 @@ complex_expression_math1_operations | "-" ; +complex_expression_parentheses + = + "(" {SP}* + complex_expression + {SP}* ")" + ; + conditional_expression_parentheses = "(" {SP}* @:conditional_expression {SP}* ")" @@ -361,7 +375,7 @@ conditional_expression_operator = conditional_expression_operator_in | ( - left:variable_identifier + left:complex_expression {SP}* operator:conditional_expression_operator_operations {SP}* right:conditional_expression ) diff --git a/src/jinja2/new_parser.py b/src/jinja2/new_parser.py index 79b55047..9d78921f 100644 --- a/src/jinja2/new_parser.py +++ b/src/jinja2/new_parser.py @@ -606,7 +606,7 @@ def parse_conditional_expression_operator(ast): '<=': 'lteq', } - expr = parse_variable(ast['left']) + expr = parse_conditional_expression(ast['left']) operator = operand_map.get(ast['operator'], ast['operator']) operands = [] -- 2.47.3