diff --git a/WHATSNEW b/WHATSNEW index 6a6720983..3b17ff8e5 100644 --- a/WHATSNEW +++ b/WHATSNEW @@ -63,6 +63,20 @@ Changes that could break older environments: set failOnEmptyArchive to false to restore the old behavior. Bugzilla report 35000. + * Ant's family of tasks tries to preserve the existing Unix + permissions when updating archives or copying entries from one + archive to another. + Since not all archiving tools support storing Unix permissions in + the same way that is used by Ant, sometimes the permissions read by + Ant seem to be 0, which means nobody is allowed to do anything to + the file or directory. + If Ant now encounters a permission set of 0 it will assume that + this is not the intended value and instead apply its own default + values. Ant used to create entries with 0 permissions itself. + The family of tasks has a new attribute preservce0permissions + that can be set to restore the old behavior. + Bugzilla Report 42122. + Fixed bugs: ----------- diff --git a/docs/manual/CoreTasks/ear.html b/docs/manual/CoreTasks/ear.html index 4e5b6bf88..071956605 100644 --- a/docs/manual/CoreTasks/ear.html +++ b/docs/manual/CoreTasks/ear.html @@ -185,6 +185,18 @@ to a value other than its default, "add".

(maximum compression/slowest). Since Ant 1.7 No + + preserve0permissions + when updating an archive or adding entries from a + different archive Ant will assume that a Unix permissions value of + 0 (nobody is allowed to do anything to the file/directory) means + that the permissions haven't been stored at all rather than real + permissions and will instead apply its own default values.
+ Set this attribute to true if you really want to preserve the + original permission field.since Ant 1.8.0 + + No, default is false +

Nested elements

diff --git a/docs/manual/CoreTasks/jar.html b/docs/manual/CoreTasks/jar.html index 5d7081855..68cb0c1ec 100644 --- a/docs/manual/CoreTasks/jar.html +++ b/docs/manual/CoreTasks/jar.html @@ -239,6 +239,18 @@ to a value other than its default, "add".

Since Ant 1.7.1 No, defaults to ignore. + + preserve0permissions + when updating an archive or adding entries from a + different archive Ant will assume that a Unix permissions value of + 0 (nobody is allowed to do anything to the file/directory) means + that the permissions haven't been stored at all rather than real + permissions and will instead apply its own default values.
+ Set this attribute to true if you really want to preserve the + original permission field.since Ant 1.8.0 + + No, default is false +

Nested elements

diff --git a/docs/manual/CoreTasks/war.html b/docs/manual/CoreTasks/war.html index bd2b5a731..0315df546 100644 --- a/docs/manual/CoreTasks/war.html +++ b/docs/manual/CoreTasks/war.html @@ -202,6 +202,18 @@ to a value other than its default, "add".

(maximum compression/slowest). Since Ant 1.7 No + + preserve0permissions + when updating an archive or adding entries from a + different archive Ant will assume that a Unix permissions value of + 0 (nobody is allowed to do anything to the file/directory) means + that the permissions haven't been stored at all rather than real + permissions and will instead apply its own default values.
+ Set this attribute to true if you really want to preserve the + original permission field.since Ant 1.8.0 + + No, default is false +

Nested elements

diff --git a/docs/manual/CoreTasks/zip.html b/docs/manual/CoreTasks/zip.html index e2f7e078e..f2e18a80c 100644 --- a/docs/manual/CoreTasks/zip.html +++ b/docs/manual/CoreTasks/zip.html @@ -229,6 +229,18 @@ archive.

(maximum compression/slowest). Since Ant 1.7 No + + preserve0permissions + when updating an archive or adding entries from a + different archive Ant will assume that a Unix permissions value of + 0 (nobody is allowed to do anything to the file/directory) means + that the permissions haven't been stored at all rather than real + permissions and will instead apply its own default values.
+ Set this attribute to true if you really want to preserve the + original permission field.since Ant 1.8.0 + + No, default is false +

Parameters specified as nested elements

diff --git a/src/etc/testcases/taskdefs/nopermissions.zip b/src/etc/testcases/taskdefs/nopermissions.zip new file mode 100644 index 000000000..979ee68b1 Binary files /dev/null and b/src/etc/testcases/taskdefs/nopermissions.zip differ diff --git a/src/etc/testcases/taskdefs/zip.xml b/src/etc/testcases/taskdefs/zip.xml index b6fa1130a..02b26a55f 100644 --- a/src/etc/testcases/taskdefs/zip.xml +++ b/src/etc/testcases/taskdefs/zip.xml @@ -248,6 +248,18 @@
+ + + + + + + + + + + + diff --git a/src/main/org/apache/tools/ant/taskdefs/Zip.java b/src/main/org/apache/tools/ant/taskdefs/Zip.java index 352faf83e..02e49fb9e 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Zip.java +++ b/src/main/org/apache/tools/ant/taskdefs/Zip.java @@ -53,6 +53,7 @@ import org.apache.tools.ant.util.GlobPatternMapper; import org.apache.tools.ant.util.IdentityMapper; import org.apache.tools.ant.util.MergingMapper; import org.apache.tools.ant.util.ResourceUtils; +import org.apache.tools.zip.UnixStat; import org.apache.tools.zip.ZipEntry; import org.apache.tools.zip.ZipExtraField; import org.apache.tools.zip.ZipFile; @@ -139,6 +140,12 @@ public class Zip extends MatchingTask { private int level = ZipOutputStream.DEFAULT_COMPRESSION; + /** + * Assume 0 Unix mode is intentional. + * @since Ant 1.8.0 + */ + private boolean preserve0Permissions = false; + /** * This is the name/location of where to * create the .zip file. @@ -401,6 +408,22 @@ public class Zip extends MatchingTask { roundUp = r; } + /** + * Assume 0 Unix mode is intentional. + * @since Ant 1.8.0 + */ + public void setPreserve0Permissions(boolean b) { + preserve0Permissions = b; + } + + /** + * Assume 0 Unix mode is intentional. + * @since Ant 1.8.0 + */ + public boolean getPreserve0Permissions() { + return preserve0Permissions; + } + /** * validate and build * @throws BuildException on error @@ -774,8 +797,13 @@ public class Zip extends MatchingTask { } if (zf != null) { ZipEntry ze = zf.getEntry(resources[i].getName()); + int unixMode = ze.getUnixMode(); + if ((unixMode == 0 || unixMode == UnixStat.DIR_FLAG) + && !preserve0Permissions) { + unixMode = dirMode; + } addParentDirs(base, name, zOut, prefix, - ze.getUnixMode()); + unixMode); } else { ArchiveResource tr = (ArchiveResource) resources[i]; addParentDirs(base, name, zOut, prefix, @@ -802,10 +830,16 @@ public class Zip extends MatchingTask { InputStream is = null; try { is = zf.getInputStream(ze); + int unixMode = ze.getUnixMode(); + if (zfs.hasFileModeBeenSet() + || ((unixMode == 0 + || unixMode == UnixStat.FILE_FLAG) + && !preserve0Permissions)) { + unixMode = fileMode; + } zipFile(is, zOut, prefix + name, ze.getTime(), zfs.getSrc(getProject()), - zfs.hasFileModeBeenSet() ? fileMode - : ze.getUnixMode()); + unixMode); } finally { doCompress = oldCompress; FileUtils.close(is); diff --git a/src/main/org/apache/tools/zip/ZipEntry.java b/src/main/org/apache/tools/zip/ZipEntry.java index 5bceee0fd..4ea215bd6 100644 --- a/src/main/org/apache/tools/zip/ZipEntry.java +++ b/src/main/org/apache/tools/zip/ZipEntry.java @@ -28,8 +28,8 @@ import java.util.zip.ZipException; */ public class ZipEntry extends java.util.zip.ZipEntry implements Cloneable { - private static final int PLATFORM_UNIX = 3; - private static final int PLATFORM_FAT = 0; + public static final int PLATFORM_UNIX = 3; + public static final int PLATFORM_FAT = 0; private static final int SHORT_MASK = 0xFFFF; private static final int SHORT_SHIFT = 16; @@ -145,7 +145,7 @@ public class ZipEntry extends java.util.zip.ZipEntry implements Cloneable { */ public void setUnixMode(int mode) { // CheckStyle:MagicNumberCheck OFF - no point - setExternalAttributes((mode << 16) + setExternalAttributes((mode << SHORT_SHIFT) // MS-DOS read-only attribute | ((mode & 0200) == 0 ? 1 : 0) // MS-DOS directory flag @@ -160,15 +160,16 @@ public class ZipEntry extends java.util.zip.ZipEntry implements Cloneable { * @since Ant 1.6 */ public int getUnixMode() { - return (int) ((getExternalAttributes() >> SHORT_SHIFT) & SHORT_MASK); + return platform != PLATFORM_UNIX ? 0 : + (int) ((getExternalAttributes() >> SHORT_SHIFT) & SHORT_MASK); } /** * Platform specification to put into the "version made * by" part of the central file header. * - * @return 0 (MS-DOS FAT) unless {@link #setUnixMode setUnixMode} - * has been called, in which case 3 (Unix) will be returned. + * @return PLATFORM_FAT unless {@link #setUnixMode setUnixMode} + * has been called, in which case PLATORM_UNIX will be returned. * * @since Ant 1.5.2 */ diff --git a/src/tests/junit/org/apache/tools/ant/taskdefs/ZipTest.java b/src/tests/junit/org/apache/tools/ant/taskdefs/ZipTest.java index e44ce9053..0fc32e658 100644 --- a/src/tests/junit/org/apache/tools/ant/taskdefs/ZipTest.java +++ b/src/tests/junit/org/apache/tools/ant/taskdefs/ZipTest.java @@ -188,4 +188,35 @@ public class ZipTest extends BuildFileTest { } } } + + public void testRewriteZeroPermissions() throws IOException { + executeTarget("rewriteZeroPermissions"); + org.apache.tools.zip.ZipFile zf = null; + try { + zf = new org.apache.tools.zip.ZipFile(getProject() + .resolveFile("test3.zip")); + org.apache.tools.zip.ZipEntry ze = zf.getEntry("testdir/test.txt"); + assertEquals(UnixStat.FILE_FLAG | 0644, ze.getUnixMode()); + } finally { + if (zf != null) { + zf.close(); + } + } + } + + public void testAcceptZeroPermissions() throws IOException { + executeTarget("acceptZeroPermissions"); + org.apache.tools.zip.ZipFile zf = null; + try { + zf = new org.apache.tools.zip.ZipFile(getProject() + .resolveFile("test3.zip")); + org.apache.tools.zip.ZipEntry ze = zf.getEntry("testdir/test.txt"); + assertEquals(0000, ze.getUnixMode()); + } finally { + if (zf != null) { + zf.close(); + } + } + } + }