@@ -38,4 +38,9 @@ | |||||
<touch file="${output}/alpha/beta/gamma/gamma.xml"/> | <touch file="${output}/alpha/beta/gamma/gamma.xml"/> | ||||
</target> | </target> | ||||
<target name="symlink-nested-setup" depends="setUp"> | |||||
<symlink link="${output}/alpha/beta/gamma/beta-link" resource="${output}/alpha/beta"/> | |||||
<touch file="${output}/alpha/beta/gamma/gamma.xml"/> | |||||
</target> | |||||
</project> | </project> |
@@ -1258,6 +1258,18 @@ public class DirectoryScanner | |||||
final String name = vpath + newFile; | final String name = vpath + newFile; | ||||
final TokenizedPath newPath = new TokenizedPath(path, newFile); | final TokenizedPath newPath = new TokenizedPath(path, newFile); | ||||
final File file = new File(dir, newFile); | final File file = new File(dir, newFile); | ||||
try { | |||||
// check if it's a filesystem "loop" due to symbolic links | |||||
if (FileUtils.getFileUtils().isLeadingPath(file.getAbsoluteFile(), | |||||
dir.getAbsoluteFile(), true)) { | |||||
continue; | |||||
} | |||||
} catch (IOException e) { | |||||
System.err.println("Failed to determine if " + file + " causes a " + | |||||
"filesystem loop due to symbolic link; continuing"); | |||||
} | |||||
final String[] children = file.list(); | final String[] children = file.list(); | ||||
if (children == null || (children.length == 0 && file.isFile())) { | if (children == null || (children.length == 0 && file.isFile())) { | ||||
if (isIncluded(newPath)) { | if (isIncluded(newPath)) { | ||||
@@ -19,6 +19,7 @@ | |||||
package org.apache.tools.ant.taskdefs; | package org.apache.tools.ant.taskdefs; | ||||
import java.io.File; | import java.io.File; | ||||
import java.io.IOException; | |||||
import java.util.Arrays; | import java.util.Arrays; | ||||
import java.util.Comparator; | import java.util.Comparator; | ||||
import java.util.Iterator; | import java.util.Iterator; | ||||
@@ -771,7 +772,19 @@ public class Delete extends MatchingTask { | |||||
} | } | ||||
for (String s : list) { | for (String s : list) { | ||||
File f = new File(d, s); | File f = new File(d, s); | ||||
if (f.isDirectory()) { | |||||
boolean isFsLoop = false; | |||||
try { | |||||
isFsLoop = SYMLINK_UTILS.isSymbolicLink(f) && | |||||
FileUtils.getFileUtils().isLeadingPath(f.getAbsoluteFile(), | |||||
d.getAbsoluteFile(), true); | |||||
} catch (IOException e) { | |||||
log("Failed to check if " + f + " causes a filesystem loop due to " + | |||||
"symbolic link; continuing"); | |||||
} | |||||
if (f.isDirectory() && !isFsLoop) { | |||||
removeDir(f); | removeDir(f); | ||||
} else { | } else { | ||||
log("Deleting " + f.getAbsolutePath(), quiet ? Project.MSG_VERBOSE : verbosity); | log("Deleting " + f.getAbsolutePath(), quiet ? Project.MSG_VERBOSE : verbosity); | ||||
@@ -132,6 +132,20 @@ public class DirectoryScannerTest { | |||||
new String[] {"alpha/beta/gamma"}); | new String[] {"alpha/beta/gamma"}); | ||||
} | } | ||||
@Test | |||||
public void testAllowRecursiveSymlinks() { | |||||
assumeTrue("Current system does not support Symlinks", supportsSymlinks); | |||||
buildRule.getProject().executeTarget("symlink-nested-setup"); | |||||
DirectoryScanner ds = new DirectoryScanner(); | |||||
ds.setBasedir(new File(buildRule.getProject().getProperty("output"))); | |||||
ds.setIncludes(new String[] {"alpha/beta/gamma/"}); | |||||
ds.scan(); | |||||
compareFiles(ds, new String[] {"alpha/beta/gamma/gamma.xml"}, | |||||
new String[] {"alpha/beta/gamma"}); | |||||
} | |||||
@Test | @Test | ||||
public void testProhibitSymlinks() { | public void testProhibitSymlinks() { | ||||
assumeTrue("Current system does not support Symlinks", supportsSymlinks); | assumeTrue("Current system does not support Symlinks", supportsSymlinks); | ||||