diff --git a/src/main/java/liqp/exceptions/IncompatibleTypeComparisonException.java b/src/main/java/liqp/exceptions/IncompatibleTypeComparisonException.java new file mode 100644 index 00000000..59ccd88f --- /dev/null +++ b/src/main/java/liqp/exceptions/IncompatibleTypeComparisonException.java @@ -0,0 +1,20 @@ +package liqp.exceptions; + +public class IncompatibleTypeComparisonException extends RuntimeException { + private static final long serialVersionUID = 1L; + private final Object a; + private final Object b; + + public IncompatibleTypeComparisonException(Object a, Object b) { + super(); + this.a = a; + this.b = b; + } + + @Override + public String getMessage() { + String aType = a == null ? "null" : a.getClass().getName(); + String bType = b == null ? "null" : b.getClass().getName(); + return "Cannot compare " + a + " with " + b + " because they are not the same type: " + aType + " vs " + bType; + } +} diff --git a/src/main/java/liqp/nodes/GtEqNode.java b/src/main/java/liqp/nodes/GtEqNode.java index e4dfc10b..4432b3e1 100644 --- a/src/main/java/liqp/nodes/GtEqNode.java +++ b/src/main/java/liqp/nodes/GtEqNode.java @@ -1,5 +1,7 @@ package liqp.nodes; +import liqp.exceptions.IncompatibleTypeComparisonException; + public class GtEqNode extends ComparingExpressionNode { public GtEqNode(LNode lhs, LNode rhs) { @@ -14,8 +16,10 @@ Object doCompare(Object a, Object b, boolean strictTypedExpressions) { } else if (b instanceof Comparable && b.getClass().isInstance(a)) { return ((Comparable) b).compareTo(a) < 0; } - String aType = a == null ? "null" : a.getClass().getName(); - String bType = b == null ? "null" : b.getClass().getName(); - throw new RuntimeException("Cannot compare " + a + " with " + b + " because they are not the same type: " + aType + " vs " + bType); + + if (strictTypedExpressions) { + throw new IncompatibleTypeComparisonException(a, b); + } + return false; } } diff --git a/src/main/java/liqp/nodes/GtNode.java b/src/main/java/liqp/nodes/GtNode.java index 74123bda..c6006034 100644 --- a/src/main/java/liqp/nodes/GtNode.java +++ b/src/main/java/liqp/nodes/GtNode.java @@ -1,5 +1,7 @@ package liqp.nodes; +import liqp.exceptions.IncompatibleTypeComparisonException; + import java.util.Optional; public class GtNode extends ComparingExpressionNode { @@ -18,9 +20,10 @@ Object doCompare(Object a, Object b, boolean strictTypedExpressions) { return ((Comparable) b).compareTo(a) <= 0; } - String aType = a == null ? "null" : a.getClass().getName(); - String bType = b == null ? "null" : b.getClass().getName(); - throw new RuntimeException("Cannot compare " + a + " with " + b + " because they are not the same type: " + aType + " vs " + bType); + if (strictTypedExpressions) { + throw new IncompatibleTypeComparisonException(a, b); + } + return false; } } diff --git a/src/main/java/liqp/nodes/LtEqNode.java b/src/main/java/liqp/nodes/LtEqNode.java index 1320e376..66a45861 100644 --- a/src/main/java/liqp/nodes/LtEqNode.java +++ b/src/main/java/liqp/nodes/LtEqNode.java @@ -1,5 +1,7 @@ package liqp.nodes; +import liqp.exceptions.IncompatibleTypeComparisonException; + import java.util.Optional; public class LtEqNode extends ComparingExpressionNode { @@ -17,8 +19,9 @@ Object doCompare(Object a, Object b, boolean strictTypedExpressions) { return ((Comparable) b).compareTo(a) > 0; } - String aType = a == null ? "null" : a.getClass().getName(); - String bType = b == null ? "null" : b.getClass().getName(); - throw new RuntimeException("Cannot compare " + a + " with " + b + " because they are not the same type: " + aType + " vs " + bType); + if (strictTypedExpressions) { + throw new IncompatibleTypeComparisonException(a, b); + } + return false; } } diff --git a/src/main/java/liqp/nodes/LtNode.java b/src/main/java/liqp/nodes/LtNode.java index e8e0d26a..c3cfb712 100644 --- a/src/main/java/liqp/nodes/LtNode.java +++ b/src/main/java/liqp/nodes/LtNode.java @@ -1,5 +1,7 @@ package liqp.nodes; +import liqp.exceptions.IncompatibleTypeComparisonException; + import java.util.Optional; public class LtNode extends ComparingExpressionNode { @@ -17,8 +19,10 @@ Object doCompare(Object a, Object b, boolean strictTypedExpressions) { } else if (b instanceof Comparable && b.getClass().isInstance(a)) { return ((Comparable) b).compareTo(a) >= 0; } - String aType = a == null ? "null" : a.getClass().getName(); - String bType = b == null ? "null" : b.getClass().getName(); - throw new RuntimeException("Cannot compare " + a + " with " + b + " because they are not the same type: " + aType + " vs " + bType); + + if (strictTypedExpressions) { + throw new IncompatibleTypeComparisonException(a, b); + } + return false; } } diff --git a/src/test/java/liqp/nodes/GtEqNodeTest.java b/src/test/java/liqp/nodes/GtEqNodeTest.java index a6d1df92..69b58044 100644 --- a/src/test/java/liqp/nodes/GtEqNodeTest.java +++ b/src/test/java/liqp/nodes/GtEqNodeTest.java @@ -80,4 +80,18 @@ public void testComparableTypes() { value = TemplateParser.DEFAULT.parse("{% if a >= c %}yes{% else %}no{% endif %}").render(data); assertEquals("no", value); } + + @Test + public void testStrictModeDisabled() { + String[][] tests = { + {"{% if 0 >= 'A' %}yes{% else %}no{% endif %}", "no"}, + {"{% if 'A' >= 0 %}yes{% else %}no{% endif %}", "no"}, + {"{% if false >= 1 %}yes{% else %}no{% endif %}", "no"}, + }; + TemplateParser templateParser = new TemplateParser.Builder().withStrictTypedExpressions(false).build(); + for (String[] test : tests) { + String rendered = templateParser.parse(test[0]).render(); + assertThat(rendered, is(test[1])); + } + } } diff --git a/src/test/java/liqp/nodes/GtNodeTest.java b/src/test/java/liqp/nodes/GtNodeTest.java index c336b71c..8cd060e5 100644 --- a/src/test/java/liqp/nodes/GtNodeTest.java +++ b/src/test/java/liqp/nodes/GtNodeTest.java @@ -134,4 +134,18 @@ public void testFilterCompare() { .render(); assertTrue(Boolean.parseBoolean(result)); } + + @Test + public void testStrictModeDisabled() { + String[][] tests = { + {"{% if 0 > 'A' %}yes{% else %}no{% endif %}", "no"}, + {"{% if 'A' > 0 %}yes{% else %}no{% endif %}", "no"}, + {"{% if false > 1 %}yes{% else %}no{% endif %}", "no"}, + }; + TemplateParser templateParser = new TemplateParser.Builder().withStrictTypedExpressions(false).build(); + for (String[] test : tests) { + String rendered = templateParser.parse(test[0]).render(); + assertThat(rendered, is(test[1])); + } + } } diff --git a/src/test/java/liqp/nodes/LtEqNodeTest.java b/src/test/java/liqp/nodes/LtEqNodeTest.java index d84e54de..97aafc2a 100644 --- a/src/test/java/liqp/nodes/LtEqNodeTest.java +++ b/src/test/java/liqp/nodes/LtEqNodeTest.java @@ -80,4 +80,18 @@ public void testComparableTypes() { value = TemplateParser.DEFAULT.parse("{% if a <= c %}yes{% else %}no{% endif %}").render(data); assertEquals("yes", value); } + + @Test + public void testStrictModeDisabled() { + String[][] tests = { + {"{% if 0 <= 'A' %}yes{% else %}no{% endif %}", "no"}, + {"{% if 'A' <= 0 %}yes{% else %}no{% endif %}", "no"}, + {"{% if true <= 0 %}yes{% else %}no{% endif %}", "no"}, + }; + TemplateParser templateParser = new TemplateParser.Builder().withStrictTypedExpressions(false).build(); + for (String[] test : tests) { + String rendered = templateParser.parse(test[0]).render(); + assertThat(rendered, is(test[1])); + } + } } diff --git a/src/test/java/liqp/nodes/LtNodeTest.java b/src/test/java/liqp/nodes/LtNodeTest.java index 657abcd2..f40658de 100644 --- a/src/test/java/liqp/nodes/LtNodeTest.java +++ b/src/test/java/liqp/nodes/LtNodeTest.java @@ -79,4 +79,18 @@ public void testComparableTypes() { value = TemplateParser.DEFAULT.parse("{% if a < c %}yes{% else %}no{% endif %}").render(data); assertEquals("yes", value); } + + @Test + public void testStrictModeDisabled() { + String[][] tests = { + {"{% if 0 < 'A' %}yes{% else %}no{% endif %}", "no"}, + {"{% if 'A' < 0 %}yes{% else %}no{% endif %}", "no"}, + {"{% if true < 0 %}yes{% else %}no{% endif %}", "no"}, + }; + TemplateParser templateParser = new TemplateParser.Builder().withStrictTypedExpressions(false).build(); + for (String[] test : tests) { + String rendered = templateParser.parse(test[0]).render(); + assertThat(rendered, is(test[1])); + } + } }