]> git.ipfire.org Git - thirdparty/jinja.git/commitdiff
Fix parsing math1 expressions in comparisons
authorKevin Brown <kevin@kevin-brown.com>
Fri, 15 May 2020 23:05:42 +0000 (19:05 -0400)
committerKevin Brown <kevin@kevin-brown.com>
Fri, 15 May 2020 23:05:42 +0000 (19:05 -0400)
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
src/jinja2/new_parser.py

index b1e2295d05c41b0bb216c3031aff2e9b2a3beff5..4707c1629e891784ea7c7370027202af3127a079 100644 (file)
@@ -286,16 +286,23 @@ variable_accessor_call_parameter_value
 \r
 conditional_expression\r
     =\r
-    | complex_expression_powers\r
-    | complex_expression_math2\r
-    | concatenate_expression\r
-    | complex_expression_math1\r
     | conditional_expression_not\r
     | conditional_expression_if\r
     | conditional_expression_logical\r
     | conditional_expression_operator\r
     | conditional_expression_test\r
+    | complex_expression\r
+    | variable_identifier\r
     | conditional_expression_parentheses\r
+    ;\r
+\r
+complex_expression\r
+    =\r
+    | complex_expression_powers\r
+    | complex_expression_math2\r
+    | concatenate_expression\r
+    | complex_expression_math1\r
+    | complex_expression_parentheses\r
     | variable_identifier\r
     ;\r
 \r
@@ -323,7 +330,7 @@ complex_expression_math1
     =\r
     left:variable_identifier\r
     {SP}* math_operator:complex_expression_math1_operations {SP}*\r
-    right:conditional_expression\r
+    right:complex_expression\r
     ;\r
 \r
 complex_expression_math1_operations\r
@@ -332,6 +339,13 @@ complex_expression_math1_operations
     | "-"\r
     ;\r
 \r
+complex_expression_parentheses\r
+    =\r
+    "(" {SP}*\r
+    complex_expression\r
+    {SP}* ")"\r
+    ;\r
+\r
 conditional_expression_parentheses\r
     =\r
     "(" {SP}* @:conditional_expression {SP}* ")"\r
@@ -361,7 +375,7 @@ conditional_expression_operator
     =\r
     conditional_expression_operator_in\r
     | (\r
-        left:variable_identifier\r
+        left:complex_expression\r
         {SP}* operator:conditional_expression_operator_operations {SP}*\r
         right:conditional_expression\r
     )\r
index 79b550479f7694ecab80a776689e0d744b509f23..9d78921f377a035ba6e8c0370091fd4d406607e4 100644 (file)
@@ -606,7 +606,7 @@ def parse_conditional_expression_operator(ast):
         '<=': 'lteq',\r
     }\r
 \r
-    expr = parse_variable(ast['left'])\r
+    expr = parse_conditional_expression(ast['left'])\r
     operator = operand_map.get(ast['operator'], ast['operator'])\r
     operands = []\r
 \r