diff --git a/src/etc/testcases/taskdefs/tar.xml b/src/etc/testcases/taskdefs/tar.xml index b0f99d5b7..08ac2f79a 100644 --- a/src/etc/testcases/taskdefs/tar.xml +++ b/src/etc/testcases/taskdefs/tar.xml @@ -203,4 +203,12 @@ + + + + + + + + diff --git a/src/etc/testcases/testtarwithsymlinks.tar.gz b/src/etc/testcases/testtarwithsymlinks.tar.gz new file mode 100644 index 000000000..782a23727 Binary files /dev/null and b/src/etc/testcases/testtarwithsymlinks.tar.gz differ diff --git a/src/main/org/apache/tools/ant/taskdefs/Tar.java b/src/main/org/apache/tools/ant/taskdefs/Tar.java index 3b5b635eb..1ab537962 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Tar.java +++ b/src/main/org/apache/tools/ant/taskdefs/Tar.java @@ -459,6 +459,14 @@ public class Tar extends MatchingTask { te.setUserId(tr.getLongUid()); te.setGroupName(tr.getGroup()); te.setGroupId(tr.getLongGid()); + String linkName = tr.getLinkName(); + byte linkFlag = tr.getLinkFlag(); + if (linkFlag == TarConstants.LF_LINK && + linkName != null && linkName.length() > 0 && !linkName.startsWith("/")) { + linkName = getCanonicalPrefix(tarFileSet, this.getProject()) + linkName; + } + te.setLinkName(linkName); + te.setLinkFlag(linkFlag); } } diff --git a/src/tests/junit/org/apache/tools/ant/taskdefs/TarTest.java b/src/tests/junit/org/apache/tools/ant/taskdefs/TarTest.java index e37e2b95a..86a6d9beb 100644 --- a/src/tests/junit/org/apache/tools/ant/taskdefs/TarTest.java +++ b/src/tests/junit/org/apache/tools/ant/taskdefs/TarTest.java @@ -19,16 +19,21 @@ package org.apache.tools.ant.taskdefs; import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.IOException; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.BuildFileRule; import org.apache.tools.ant.FileUtilities; +import org.apache.tools.tar.TarEntry; +import org.apache.tools.tar.TarInputStream; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; public class TarTest { @@ -186,4 +191,27 @@ public class TarTest { public void testtestTarFilesetWithReference() { buildRule.executeTarget("testTarFilesetWithReference"); } + + @Test + public void testTarFilesetWithSymlinks() throws IOException { + buildRule.executeTarget("testTarFilesetWithSymlinks"); + final File f = new File(buildRule.getProject().getProperty("output"), "result.tar"); + final TarInputStream tis = new TarInputStream(new FileInputStream(f)); + try { + final TarEntry e1 = tis.getNextEntry(); + assertEquals("pre/dir/file", e1.getName()); + assertEquals("", e1.getLinkName()); + assertEquals(48, e1.getLinkFlag()); + + final TarEntry e2 = tis.getNextEntry(); + assertEquals("pre/sub/file", e2.getName()); + assertEquals("../dir/file", e2.getLinkName()); + assertEquals(50, e2.getLinkFlag()); + + assertNull(tis.getNextEntry()); + } + finally { + tis.close(); + } + } }