diff --git a/pom.xml b/pom.xml index 12017719..053fb073 100644 --- a/pom.xml +++ b/pom.xml @@ -150,6 +150,14 @@ + + org.apache.maven.plugins + maven-compiler-plugin + + 8 + 8 + + diff --git a/src/main/java/de/neuland/jade4j/model/JadeModel.java b/src/main/java/de/neuland/jade4j/model/JadeModel.java index d914ad9c..d99507c7 100644 --- a/src/main/java/de/neuland/jade4j/model/JadeModel.java +++ b/src/main/java/de/neuland/jade4j/model/JadeModel.java @@ -11,8 +11,11 @@ import java.util.Map; import java.util.Set; +import de.neuland.jade4j.exceptions.JadeCompilerException; import de.neuland.jade4j.filter.Filter; import de.neuland.jade4j.parser.node.MixinNode; +import de.neuland.jade4j.parser.node.Node; +import de.neuland.jade4j.template.JadeTemplate; public class JadeModel implements Map { @@ -22,6 +25,10 @@ public class JadeModel implements Map { private Map mixins = new HashMap(); private Map filter = new HashMap(); + // to detect infinite loop + private Map visited = new HashMap(); + private Integer MAX_VISITED = 100; + public JadeModel(Map defaults) { Map rootScope = new HashMap(); scopes.add(rootScope); @@ -50,6 +57,16 @@ public MixinNode getMixin(String name) { return mixins.get(name); } + public void visit(Node node, JadeTemplate template) { + String visitId = node.getFileName()+":"+node.getLineNumber(); + Integer ct = visited.getOrDefault(visitId, 0) +1; + if (ct > MAX_VISITED) { + String error = "Potential infinite loop: "+visitId+" has been visited more then "+MAX_VISITED+" times!"; + throw new JadeCompilerException(node, template.getTemplateLoader(), error); + } + visited.put(visitId, ct); + } + @Override public void clear() { scopes.clear(); diff --git a/src/main/java/de/neuland/jade4j/parser/BlockCommentNode.java b/src/main/java/de/neuland/jade4j/parser/BlockCommentNode.java index 5370894e..f2d5db1c 100644 --- a/src/main/java/de/neuland/jade4j/parser/BlockCommentNode.java +++ b/src/main/java/de/neuland/jade4j/parser/BlockCommentNode.java @@ -9,6 +9,7 @@ public class BlockCommentNode extends CommentNode { @Override public void execute(IndentWriter writer, JadeModel model, JadeTemplate template) throws JadeCompilerException { + model.visit(this, template); if (!isBuffered()) { return; } diff --git a/src/main/java/de/neuland/jade4j/parser/node/BlockNode.java b/src/main/java/de/neuland/jade4j/parser/node/BlockNode.java index 4328a727..d43ae8b6 100644 --- a/src/main/java/de/neuland/jade4j/parser/node/BlockNode.java +++ b/src/main/java/de/neuland/jade4j/parser/node/BlockNode.java @@ -12,6 +12,7 @@ public class BlockNode extends Node { private String mode; public void execute(IndentWriter writer, JadeModel model, JadeTemplate template) throws JadeCompilerException { + model.visit(this, template); for (Node node : getNodes()) { node.execute(writer, model, template); } diff --git a/src/main/java/de/neuland/jade4j/parser/node/ConditionalNode.java b/src/main/java/de/neuland/jade4j/parser/node/ConditionalNode.java index 0efeca9b..167fa0e5 100644 --- a/src/main/java/de/neuland/jade4j/parser/node/ConditionalNode.java +++ b/src/main/java/de/neuland/jade4j/parser/node/ConditionalNode.java @@ -16,6 +16,7 @@ public class ConditionalNode extends Node { @Override public void execute(IndentWriter writer, JadeModel model, JadeTemplate template) throws JadeCompilerException { + model.visit(this, template); for (IfConditionNode conditionNode : this.conditions) { try { if (conditionNode.isDefault() || checkCondition(model, conditionNode.getValue()) ^ conditionNode.isInverse()) { diff --git a/src/main/java/de/neuland/jade4j/parser/node/IfConditionNode.java b/src/main/java/de/neuland/jade4j/parser/node/IfConditionNode.java index ab5dfc03..89f45c89 100644 --- a/src/main/java/de/neuland/jade4j/parser/node/IfConditionNode.java +++ b/src/main/java/de/neuland/jade4j/parser/node/IfConditionNode.java @@ -17,6 +17,7 @@ public IfConditionNode(String condition, int lineNumber) { @Override public void execute(IndentWriter writer, JadeModel model, JadeTemplate template) throws JadeCompilerException { + model.visit(this, template); block.execute(writer, model, template); } diff --git a/src/main/java/de/neuland/jade4j/parser/node/MixinInjectNode.java b/src/main/java/de/neuland/jade4j/parser/node/MixinInjectNode.java index 9b0ca2c1..0ac92275 100644 --- a/src/main/java/de/neuland/jade4j/parser/node/MixinInjectNode.java +++ b/src/main/java/de/neuland/jade4j/parser/node/MixinInjectNode.java @@ -16,6 +16,7 @@ public class MixinInjectNode extends AttributedNode { @Override public void execute(IndentWriter writer, JadeModel model, JadeTemplate template) throws JadeCompilerException { + model.visit(this, template); MixinNode mixin = model.getMixin(getName()); if (mixin == null) { throw new JadeCompilerException(this, template.getTemplateLoader(), "mixin " + getName() + " is not defined"); diff --git a/src/main/java/de/neuland/jade4j/parser/node/TagNode.java b/src/main/java/de/neuland/jade4j/parser/node/TagNode.java index 5d7e7873..e6c8d038 100644 --- a/src/main/java/de/neuland/jade4j/parser/node/TagNode.java +++ b/src/main/java/de/neuland/jade4j/parser/node/TagNode.java @@ -56,6 +56,7 @@ public boolean hasCodeNode() { @Override public void execute(IndentWriter writer, JadeModel model, JadeTemplate template) throws JadeCompilerException { + model.visit(this, template); writer.newline(); writer.append("<"); writer.append(name);