bkiers / Liqp

An ANTLR based 'Liquid Template' parser and rendering engine.
MIT License
165 stars 94 forks source link

Strict typing enforcement cannot be fully disabled #304

Closed Hunter-Gong-Attentive closed 4 months ago

Hunter-Gong-Attentive commented 4 months ago

Hello, I am currently running version 0.8.3.3 of this library in my application and when going to upgrade to the more recent 0.9.0.2 that some of our previous logic is now invalid due to these type checks. This appears to be happening even when the withStrictTypedExpressions flag is set to false, and based on the README description of this option, this appears to be a bug.

Steps to reproduce:

When rendering a comparison between a number and a string and withStrictTypedExpressions is set to false

// Throws RuntimeException
String template = "{% if 0 < 'A' %}{% endif %}";
String rendered = new TemplateParser.Builder()
        .withStrictTypedExpressions(false)
        .withFlavor(Flavor.LIQUID)
        .build()
        .parse(template)
        .render();

Expected Behavior: An empty string should be rendered Actual Behavior: RuntimeException is thrown

java.lang.RuntimeException: Cannot compare 0 with A because they are not the same type: liqp.PlainBigDecimal vs java.lang.String
    at liqp.nodes.LtNode.doCompare(LtNode.java:22)
    at liqp.nodes.ComparingExpressionNode.render(ComparingExpressionNode.java:97)
    at liqp.blocks.If.render(If.java:16)
    at liqp.nodes.InsertionNode.render(InsertionNode.java:34)
    at liqp.nodes.BlockNode.render(BlockNode.java:36)

Flag usage elsewhere

This behavior appears to be inconsistent and does not apply to comparison which contain booleans or make non-relative comparisons. It is unclear why these would be intentionally allowed, but the above would not.

IE, these examples both render fine.

// Renders without exception
String template = "{% if 0 < false %}{% endif %}";
String rendered = new TemplateParser.Builder()
        .withStrictTypedExpressions(false)
        .withFlavor(Flavor.LIQUID)
        .build()
        .parse(template)
        .render();
// Renders without exception
String template = "{% if 0 == 'A' %}{% endif %}";
String rendered = new TemplateParser.Builder()
        .withStrictTypedExpressions(false)
        .withFlavor(Flavor.LIQUID)
        .build()
        .parse(template)
        .render();
msangel commented 4 months ago

Will work on this. Thanks!

Hunter-Gong-Attentive commented 4 months ago

Was looking into this and I think the solution may be as simple as this here https://github.com/bkiers/Liqp/pull/305

msangel commented 4 months ago

@Hunter-Gong-Attentive nice work! Merged and new version 0.9.0.3 released with it (requires some time to became publicly available)