diff --git a/WHATSNEW b/WHATSNEW index 826f7e47f..b11d089aa 100644 --- a/WHATSNEW +++ b/WHATSNEW @@ -161,6 +161,11 @@ Fixed bugs: make the exit codes work in environments where 4NT or MKS are installed Bugzilla Report 41039. + * would fail if used via its Java API and the File passed + into the setJar method was not "normalized" (i.e. contained ".." + segments). + Bugzilla Report 50081 + Other changes: -------------- diff --git a/src/main/org/apache/tools/ant/taskdefs/Move.java b/src/main/org/apache/tools/ant/taskdefs/Move.java index 358654fcc..9b01c4093 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Move.java +++ b/src/main/org/apache/tools/ant/taskdefs/Move.java @@ -355,7 +355,7 @@ public class Move extends Copy { + " is a no-op.", Project.MSG_VERBOSE); return true; } - if (!(sourceFile.equals(destFile.getCanonicalFile()) || destFile.delete())) { + if (!(getFileUtils().areSame(sourceFile, destFile) || destFile.delete())) { throw new BuildException("Unable to remove existing file " + destFile); } } diff --git a/src/main/org/apache/tools/ant/taskdefs/SignJar.java b/src/main/org/apache/tools/ant/taskdefs/SignJar.java index 67a4a37e0..3523f35c8 100644 --- a/src/main/org/apache/tools/ant/taskdefs/SignJar.java +++ b/src/main/org/apache/tools/ant/taskdefs/SignJar.java @@ -378,7 +378,7 @@ public class SignJar extends AbstractJarSignerTask { * @throws BuildException */ private void signOneJar(File jarSource, File jarTarget) - throws BuildException { + throws BuildException { File targetFile = jarTarget; @@ -401,12 +401,16 @@ public class SignJar extends AbstractJarSignerTask { addValue(cmd, value); } + try { //DO NOT SET THE -signedjar OPTION if source==dest //unless you like fielding hotspot crash reports - if (!jarSource.equals(targetFile)) { + if (!FILE_UTILS.areSame(jarSource, targetFile)) { addValue(cmd, "-signedjar"); addValue(cmd, targetFile.getPath()); } + } catch (IOException ioex) { + throw new BuildException(ioex); + } if (internalsf) { addValue(cmd, "-internalsf"); diff --git a/src/main/org/apache/tools/ant/util/FileUtils.java b/src/main/org/apache/tools/ant/util/FileUtils.java index 38b82f9dc..073d98b62 100644 --- a/src/main/org/apache/tools/ant/util/FileUtils.java +++ b/src/main/org/apache/tools/ant/util/FileUtils.java @@ -1256,6 +1256,25 @@ public class FileUtils { normalize(f2.getAbsolutePath()).getAbsolutePath()); } + /** + * Are the two File instances pointing to the same object on the + * file system? + * @since Ant 1.8.2 + */ + public boolean areSame(File f1, File f2) throws IOException { + if (f1 == null && f2 == null) { + return true; + } + if (f1 == null || f2 == null) { + return false; + } + File f1Normalized = normalize(f1.getAbsolutePath()); + File f2Normalized = normalize(f2.getAbsolutePath()); + return f1Normalized.equals(f2Normalized) + || f1Normalized.getCanonicalFile().equals(f2Normalized + .getCanonicalFile()); + } + /** * Renames a file, even if that involves crossing file system boundaries. * @@ -1285,8 +1304,7 @@ public class FileUtils { System.err.println("Rename of " + from + " to " + to + " is a no-op."); return; } - if (to.exists() && - !(from.equals(to.getCanonicalFile()) || tryHardToDelete(to))) { + if (to.exists() && !(areSame(from, to) || tryHardToDelete(to))) { throw new IOException("Failed to delete " + to + " while trying to rename " + from); } File parent = to.getParentFile(); diff --git a/src/tests/junit/org/apache/tools/ant/taskdefs/SignJarTest.java b/src/tests/junit/org/apache/tools/ant/taskdefs/SignJarTest.java index 7b819c1da..7c810beef 100644 --- a/src/tests/junit/org/apache/tools/ant/taskdefs/SignJarTest.java +++ b/src/tests/junit/org/apache/tools/ant/taskdefs/SignJarTest.java @@ -106,4 +106,24 @@ public class SignJarTest extends BuildFileTest { } } + /** + * @see https://issues.apache.org/bugzilla/show_bug.cgi?id=50081 + */ + public void testSignUnnormalizedJar() throws Exception { + executeTarget("jar"); + File testJar = new File(getProject().getProperty("test.jar")); + File testJarParent = testJar.getParentFile(); + File f = new File(testJarParent, + "../" + testJarParent.getName() + "/" + + testJar.getName()); + assertFalse(testJar.equals(f)); + assertEquals(testJar.getCanonicalPath(), f.getCanonicalPath()); + SignJar s = new SignJar(); + s.setProject(getProject()); + s.setJar(f); + s.setAlias("testonly"); + s.setStorepass("apacheant"); + s.setKeystore("testkeystore"); + s.execute(); + } }