From 0f110eac27c17cf3bdbcfee77bc5b9b4aead9f4e Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Sat, 25 Sep 2021 12:45:23 +0200 Subject: [PATCH] Merge branch 'feature/tarfileset-preserve-symlinks' of https://github.com/mstrap/ant into mstrap-feature/tarfileset-preserve-symlinks --- WHATSNEW | 6 +++++ src/etc/testcases/taskdefs/tar.xml | 8 ++++++ src/etc/testcases/testtarwithsymlinks.tar.gz | Bin 0 -> 199 bytes .../org/apache/tools/ant/taskdefs/Tar.java | 24 ++++++++++++----- .../ant/types/resources/TarResource.java | 21 +++++++++++++++ src/main/org/apache/tools/tar/TarEntry.java | 20 ++++++++++++++ .../apache/tools/ant/taskdefs/TarTest.java | 25 ++++++++++++++++++ 7 files changed, 98 insertions(+), 6 deletions(-) create mode 100644 src/etc/testcases/testtarwithsymlinks.tar.gz diff --git a/WHATSNEW b/WHATSNEW index f3f9ddf0d..7ad9c455d 100644 --- a/WHATSNEW +++ b/WHATSNEW @@ -9,6 +9,12 @@ Fixed bugs: the shorter alias names. Bugzilla Report 65539 +Other changes: +-------------- + + * The tar task now preserves symlinks of nested tarfilesets. + Github Pull Request #142 + Changes from Ant 1.9.15 TO Ant 1.9.16 ===================================== diff --git a/src/etc/testcases/taskdefs/tar.xml b/src/etc/testcases/taskdefs/tar.xml index 2eda0b544..e76b7ad0e 100644 --- a/src/etc/testcases/taskdefs/tar.xml +++ b/src/etc/testcases/taskdefs/tar.xml @@ -197,4 +197,12 @@ + + + + + + + + diff --git a/src/etc/testcases/testtarwithsymlinks.tar.gz b/src/etc/testcases/testtarwithsymlinks.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..782a23727f2a658804abd1f65e07826e59708bd1 GIT binary patch literal 199 zcmb2|=3oE==C@ZJ`I-y_S|6^nboFPD^}79eL59;J=?TAYA4`Z?IJ@c8|6H|&Dn6f1 z`CR9pdg_de;*Jnii_cN%UO69p??wpkF-pp*SrYs1*rd!oTbr-Fy2W>V>Gykc|F6({ zR{u_a`JDS6jMevbp1hy`Gg|n4XGcWfttUBI+dltUx`I18=Pv6uBfs|bv;O!0w?9{Z z{!hH~srufZ@=iZA>I*afAO9M!9XmaBYOVcSn|g?ALF9q@9n8NfUaBx?FfafBo77-p literal 0 HcmV?d00001 diff --git a/src/main/org/apache/tools/ant/taskdefs/Tar.java b/src/main/org/apache/tools/ant/taskdefs/Tar.java index 0d319d1ca..1ab2d3318 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Tar.java +++ b/src/main/org/apache/tools/ant/taskdefs/Tar.java @@ -412,12 +412,7 @@ public class Tar extends MatchingTask { return; } - String prefix = tarFileSet.getPrefix(this.getProject()); - // '/' is appended for compatibility with the zip task. - if (prefix.length() > 0 && !prefix.endsWith("/")) { - prefix = prefix + "/"; - } - vPath = prefix + vPath; + vPath = getCanonicalPrefix(tarFileSet, this.getProject()) + vPath; } preserveLeadingSlashes = tarFileSet.getPreserveLeadingSlashes(); @@ -469,6 +464,14 @@ public class Tar extends MatchingTask { te.setUserId(tr.getUid()); te.setGroupName(tr.getGroup()); te.setGroupId(tr.getGid()); + 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); } } @@ -799,6 +802,15 @@ public class Tar extends MatchingTask { return tfs; } + private static String getCanonicalPrefix(TarFileSet tarFileSet, Project project) { + String prefix = tarFileSet.getPrefix(project); + // '/' is appended for compatibility with the zip task. + if (prefix.isEmpty() || prefix.endsWith("/")) { + return prefix; + } + return prefix += "/"; + } + /** * This is a FileSet with the option to specify permissions * and other attributes. diff --git a/src/main/org/apache/tools/ant/types/resources/TarResource.java b/src/main/org/apache/tools/ant/types/resources/TarResource.java index b906a6527..30114069d 100644 --- a/src/main/org/apache/tools/ant/types/resources/TarResource.java +++ b/src/main/org/apache/tools/ant/types/resources/TarResource.java @@ -26,6 +26,7 @@ import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; import org.apache.tools.ant.types.Resource; import org.apache.tools.ant.util.FileUtils; +import org.apache.tools.tar.TarConstants; import org.apache.tools.tar.TarEntry; import org.apache.tools.tar.TarInputStream; @@ -39,6 +40,8 @@ public class TarResource extends ArchiveResource { private String groupName = ""; private int uid; private int gid; + private byte linkFlag = TarConstants.LF_NORMAL; + private String linkName = ""; /** * Default constructor. @@ -152,6 +155,22 @@ public class TarResource extends ArchiveResource { return gid; } + /** + * @return the link "name" (=path) of this entry; an empty string if this is no link + * @since 1.9.17 + */ + public String getLinkName() { + return linkName; + } + + /** + * @return the link "flag" (=type) of this entry + * @since 1.9.17 + */ + public byte getLinkFlag() { + return linkFlag; + } + /** * fetches information from the named entry inside the archive. */ @@ -191,6 +210,8 @@ public class TarResource extends ArchiveResource { groupName = e.getGroupName(); uid = e.getUserId(); gid = e.getGroupId(); + linkName = e.getLinkName(); + linkFlag = e.getLinkFlag(); } } diff --git a/src/main/org/apache/tools/tar/TarEntry.java b/src/main/org/apache/tools/tar/TarEntry.java index afdd9511e..af0db023b 100644 --- a/src/main/org/apache/tools/tar/TarEntry.java +++ b/src/main/org/apache/tools/tar/TarEntry.java @@ -398,6 +398,26 @@ public class TarEntry implements TarConstants { this.mode = mode; } + /** + * Get this entry's link flag. + * + * @return This entry's link flag. + * @since 1.9.17 + */ + public byte getLinkFlag() { + return linkFlag; + } + + /** + * Set this entry's link flag. + * + * @param link the link flag to use. + * @since 1.9.17 + */ + public void setLinkFlag(byte linkFlag) { + this.linkFlag = linkFlag; + } + /** * Get this entry's link name. * 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 9650dfcfd..f747c423e 100644 --- a/src/tests/junit/org/apache/tools/ant/taskdefs/TarTest.java +++ b/src/tests/junit/org/apache/tools/ant/taskdefs/TarTest.java @@ -20,16 +20,20 @@ package org.apache.tools.ant.taskdefs; import java.io.IOException; import java.io.File; +import java.io.FileInputStream; 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.fail; +import static org.junit.Assert.assertNull; public class TarTest { @@ -206,5 +210,26 @@ public class TarTest { FileUtilities.getFileContents(new File(buildRule.getProject().getProperty("output"), "untar/asf-logo.gif.gz"))); } + @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(); + } + } }