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
+
+
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);