Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

and, or, not, is, and in are not reserved words. #71

Closed
valarauca opened this issue Jul 12, 2022 · 3 comments
Closed

and, or, not, is, and in are not reserved words. #71

valarauca opened this issue Jul 12, 2022 · 3 comments

Comments

@valarauca
Copy link

Description

It seems to be pretty trivial to trick the parser into mistaking keywords for function names.

Reproduction steps

  1. Test string: r#" '{{ a }}' == 'a' and ( '{{ a }}' != 'b' or '{{ a }}' != 'c' ) "#
  2. Basic context!( a => "a" ) and eval with it.
  3. Get the error Error { kind: ImpossibleOperation, details: Some("unknown function and"), name: Some("<expression>"), lineno: 1, source: None }

Give it some context!( a => "a" ) and eval it.

Additional helpful information:

  • Version of minijinja: 0.71.0
  • Version of rustic: 1.62.0
  • Operating system and version: Windows 10

What did you expect

and should be treated like a keyword, per the docs so the parser should understand that it is not just a normal identifier, and shouldn't first identify it as an ident, then try to convert it into a function.

There likely should be different Infix/Suffix/Prefix handling within the parser logic. I also see the project is implementing its own LRParser, I would recommend => lrpar project as it fully re-implements yacc in rust.

@valarauca
Copy link
Author

Appears to be only and and or. I'll try to write up a patch.

@mitsuhiko
Copy link
Owner

I can imagine there being bugs but I am actually not able to reproduce. The following template:

{{ '{{ a }}' == 'a' and ( '{{ a }}' != 'b' or '{{ a }}' != 'c' ) }}

Produces the following AST:

Ok(
    Template {
        children: [
            EmitExpr {
                expr: BinOp {
                    op: ScAnd,
                    left: BinOp {
                        op: Eq,
                        left: Const {
                            value: "{{ a }}",
                        } @ 1:3-1:12,
                        right: Const {
                            value: "a",
                        } @ 1:16-1:19,
                    } @ 1:0-1:19,
                    right: BinOp {
                        op: ScOr,
                        left: BinOp {
                            op: Ne,
                            left: Const {
                                value: "{{ a }}",
                            } @ 1:26-1:35,
                            right: Const {
                                value: "b",
                            } @ 1:39-1:42,
                        } @ 1:24-1:42,
                        right: BinOp {
                            op: Ne,
                            left: Const {
                                value: "{{ a }}",
                            } @ 1:46-1:55,
                            right: Const {
                                value: "c",
                            } @ 1:59-1:62,
                        } @ 1:43-1:62,
                    } @ 1:24-1:62,
                } @ 1:0-1:64,
            } @ 1:0-1:64,
        ],
    } @ 0:0-1:67,
)

Which seems fine? Can you provide a minimal test case that shows this behavior?

@mitsuhiko
Copy link
Owner

I'm unable to reproduce this. Jinja never had keywords and syntax wise it should not be necessary to enforce keywords to avoid ambiguities. The obvious exception is that if you name variables after soft keywords they won't function well in all contexts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants