diff --git a/src/etc/testcases/taskdefs/ant.xml b/src/etc/testcases/taskdefs/ant.xml
index cc62d2ea1..5d3ce07d6 100644
--- a/src/etc/testcases/taskdefs/ant.xml
+++ b/src/etc/testcases/taskdefs/ant.xml
@@ -162,4 +162,11 @@
test2 is ${test2}
test1.x is ${test1.x}
+
+
+
+
+
+
+
diff --git a/src/main/org/apache/tools/ant/Project.java b/src/main/org/apache/tools/ant/Project.java
index e308286a4..ea358e941 100644
--- a/src/main/org/apache/tools/ant/Project.java
+++ b/src/main/org/apache/tools/ant/Project.java
@@ -1589,8 +1589,7 @@ public class Project {
* Must not be null
.
* @param targets A map of names to targets (String to Target).
* Must not be null
.
- * @return a vector of strings with the names of the targets in
- * sorted order.
+ * @return a vector of Target objects in sorted order.
* @exception BuildException if there is a cyclic dependency among the
* targets, or if a named target does not exist.
*/
@@ -2096,4 +2095,4 @@ public class Project {
// is private/protected.
}
}
-}
\ No newline at end of file
+}
diff --git a/src/main/org/apache/tools/ant/Target.java b/src/main/org/apache/tools/ant/Target.java
index 69cf71ff7..d82ee5568 100644
--- a/src/main/org/apache/tools/ant/Target.java
+++ b/src/main/org/apache/tools/ant/Target.java
@@ -255,6 +255,22 @@ public class Target implements TaskContainer {
}
}
+ /**
+ * Does this target depend on the named target?
+ *
+ * @since Ant 1.6
+ */
+ public boolean dependsOn(String other) {
+ if (getProject() != null) {
+ List l = getProject().topoSort(getName(),
+ getProject().getTargets());
+ int myIdx = l.indexOf(this);
+ int otherIdx = l.indexOf(getProject().getTargets().get(other));
+ return myIdx >= otherIdx;
+ }
+ return false;
+ }
+
/**
* Sets the "if" condition to test on execution. This is the
* name of a property to test for existence - if the property
diff --git a/src/main/org/apache/tools/ant/taskdefs/Ant.java b/src/main/org/apache/tools/ant/taskdefs/Ant.java
index 2d7b00d19..19738e5f3 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Ant.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Ant.java
@@ -68,6 +68,7 @@ import org.apache.tools.ant.DefaultLogger;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.ProjectComponent;
import org.apache.tools.ant.ProjectHelper;
+import org.apache.tools.ant.Target;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.PropertySet;
import org.apache.tools.ant.util.FileUtils;
@@ -363,7 +364,10 @@ public class Ant extends Task {
if (newProject.getProperty("ant.file")
.equals(getProject().getProperty("ant.file"))
&& getOwningTarget() != null) {
- if (getOwningTarget().getName().equals("")) {
+
+ String owningTargetName = getOwningTarget().getName();
+
+ if (owningTargetName.equals("")) {
if (getTaskName().equals("antcall")) {
throw new BuildException("antcall must not be used at"
+ " the top level.");
@@ -372,9 +376,20 @@ public class Ant extends Task {
+ " top level must not invoke"
+ " its own build file.");
}
- } else if (getOwningTarget().getName().equals(target)) {
+ } else if (owningTargetName.equals(target)) {
throw new BuildException(getTaskName() + " task calling "
+ "its own parent target.");
+ } else {
+ Target other =
+ (Target) getProject().getTargets().get(target);
+ if (other != null && other.dependsOn(owningTargetName)) {
+ throw new BuildException(getTaskName()
+ + " task calling a target"
+ + " that depends on"
+ + " its parent target \'"
+ + owningTargetName
+ + "\'.");
+ }
}
}
diff --git a/src/testcases/org/apache/tools/ant/taskdefs/AntTest.java b/src/testcases/org/apache/tools/ant/taskdefs/AntTest.java
index 0ccb93e83..9dc3d1e5a 100644
--- a/src/testcases/org/apache/tools/ant/taskdefs/AntTest.java
+++ b/src/testcases/org/apache/tools/ant/taskdefs/AntTest.java
@@ -302,6 +302,10 @@ public class AntTest extends BuildFileTest {
assertTrue(getLog().indexOf("test1.x is 1") > -1);
}
+ public void testInfiniteLoopViaDepends() {
+ expectBuildException("infinite-loop-via-depends", "recursive call");
+ }
+
private class BasedirChecker implements BuildListener {
private String[] expectedBasedirs;
private int calls = 0;