Browse Source

add additional isLeadingPath method that resolves symlinks

master
Stefan Bodewig 7 years ago
parent
commit
6a41d62cb9
2 changed files with 61 additions and 0 deletions
  1. +30
    -0
      src/main/org/apache/tools/ant/util/FileUtils.java
  2. +31
    -0
      src/tests/junit/org/apache/tools/ant/util/FileUtilsTest.java

+ 30
- 0
src/main/org/apache/tools/ant/util/FileUtils.java View File

@@ -1210,6 +1210,36 @@ public class FileUtils {
return p.startsWith(l);
}

/**
* Learn whether one path "leads" another.
*
* @param leading The leading path, must not be null, must be absolute.
* @param path The path to check, must not be null, must be absolute.
* @param resolveSymlinks whether symbolic links shall be resolved
* prior to comparing the paths.
* @return true if path starts with leading; false otherwise.
* @since Ant 1.9.13
* @throws IOException if resolveSymlinks is true and invoking
* getCanonicaPath on either argument throws an exception
*/
public boolean isLeadingPath(File leading, File path, boolean resolveSymlinks)
throws IOException {
if (!resolveSymlinks) {
return isLeadingPath(leading, path);
}
String l = leading.getCanonicalPath();
String p = path.getCanonicalPath();
if (l.equals(p)) {
return true;
}
// ensure that l ends with a /
// so we never think /foo was a parent directory of /foobar
if (!l.endsWith(File.separator)) {
l += File.separator;
}
return p.startsWith(l);
}

/**
* Constructs a <code>file:</code> URI that represents the
* external form of the given pathname.


+ 31
- 0
src/tests/junit/org/apache/tools/ant/util/FileUtilsTest.java View File

@@ -32,6 +32,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeTrue;

/**
@@ -603,6 +604,36 @@ public class FileUtilsTest {
assertFalse(FILE_UTILS.isLeadingPath(new File("/foo"), new File("/foo/../..")));
}

/**
* @see "https://bz.apache.org/bugzilla/show_bug.cgi?id=62502"
*/
@Test
public void isLeadingPathCanonicalVersionCannotBeFooledByTooManyDoubleDots() throws IOException {
assertFalse(FILE_UTILS.isLeadingPath(new File("/foo"), new File("/foo/../../bar"), true));
assertFalse(FILE_UTILS.isLeadingPath(new File("c:\\foo"), new File("c:\\foo\\..\\..\\bar"), true));
assertFalse(FILE_UTILS.isLeadingPath(new File("/foo"), new File("/foo/../.."), true));
}

@Test
public void isLeadingPathCanonicalVersionWorksAsExpectedOnUnix() throws IOException {
assumeFalse("Test doesn't run on DOS", Os.isFamily("dos"));
assertTrue(FILE_UTILS.isLeadingPath(new File("/foo"), new File("/foo/bar"), true));
assertTrue(FILE_UTILS.isLeadingPath(new File("/foo"), new File("/foo/baz/../bar"), true));
assertTrue(FILE_UTILS.isLeadingPath(new File("/foo"), new File("/foo/../foo/bar"), true));
assertFalse(FILE_UTILS.isLeadingPath(new File("/foo"), new File("/foobar"), true));
assertFalse(FILE_UTILS.isLeadingPath(new File("/foo"), new File("/bar"), true));
}

@Test
public void isLeadingPathCanonicalVersionWorksAsExpectedOnDos() throws IOException {
assumeTrue("Test only runs on DOS", Os.isFamily("dos"));
assertTrue(FILE_UTILS.isLeadingPath(new File("C:\\foo"), new File("C:\\foo\\bar"), true));
assertTrue(FILE_UTILS.isLeadingPath(new File("C:\\foo"), new File("C:\\foo\\baz\\..\\bar"), true));
assertTrue(FILE_UTILS.isLeadingPath(new File("C:\\foo"), new File("C:\\foo\\..\\foo\\bar"), true));
assertFalse(FILE_UTILS.isLeadingPath(new File("C:\\foo"), new File("C:\\foobar"), true));
assertFalse(FILE_UTILS.isLeadingPath(new File("C:\\foo"), new File("C:\\bar"), true));
}

/**
* adapt file separators to local conventions
*/


Loading…
Cancel
Save