Author: bodewig Date: Thu Jul 17 07:44:30 2008 New Revision: 677597 URL: http://svn.apache.org/viewvc?rev=677597&view=rev Log: don't trust permissions read from another ZIP file blindly. PR 42122.
Added: ant/core/trunk/src/etc/testcases/taskdefs/nopermissions.zip (with props) Modified: ant/core/trunk/WHATSNEW ant/core/trunk/docs/manual/CoreTasks/ear.html ant/core/trunk/docs/manual/CoreTasks/jar.html ant/core/trunk/docs/manual/CoreTasks/war.html ant/core/trunk/docs/manual/CoreTasks/zip.html ant/core/trunk/src/etc/testcases/taskdefs/zip.xml ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Zip.java ant/core/trunk/src/main/org/apache/tools/zip/ZipEntry.java ant/core/trunk/src/tests/junit/org/apache/tools/ant/taskdefs/ZipTest.java Modified: ant/core/trunk/WHATSNEW URL: http://svn.apache.org/viewvc/ant/core/trunk/WHATSNEW?rev=677597&r1=677596&r2=677597&view=diff ============================================================================== --- ant/core/trunk/WHATSNEW (original) +++ ant/core/trunk/WHATSNEW Thu Jul 17 07:44:30 2008 @@ -63,6 +63,20 @@ set failOnEmptyArchive to false to restore the old behavior. Bugzilla report 35000. + * Ant's <zip> 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 <zip> family of tasks has a new attribute preservce0permissions + that can be set to restore the old behavior. + Bugzilla Report 42122. + Fixed bugs: ----------- Modified: ant/core/trunk/docs/manual/CoreTasks/ear.html URL: http://svn.apache.org/viewvc/ant/core/trunk/docs/manual/CoreTasks/ear.html?rev=677597&r1=677596&r2=677597&view=diff ============================================================================== --- ant/core/trunk/docs/manual/CoreTasks/ear.html (original) +++ ant/core/trunk/docs/manual/CoreTasks/ear.html Thu Jul 17 07:44:30 2008 @@ -185,6 +185,18 @@ (maximum compression/slowest). <em>Since Ant 1.7</em></td> <td valign="top" align="center">No</td> </tr> + <tr> + <td valign="top">preserve0permissions</td> + <td valign="top">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.<br/> + Set this attribute to true if you really want to preserve the + original permission field.<em>since Ant 1.8.0</em> + </td> + <td valign="top" align="center">No, default is false</td> + </tr> </table> <h3>Nested elements</h3> Modified: ant/core/trunk/docs/manual/CoreTasks/jar.html URL: http://svn.apache.org/viewvc/ant/core/trunk/docs/manual/CoreTasks/jar.html?rev=677597&r1=677596&r2=677597&view=diff ============================================================================== --- ant/core/trunk/docs/manual/CoreTasks/jar.html (original) +++ ant/core/trunk/docs/manual/CoreTasks/jar.html Thu Jul 17 07:44:30 2008 @@ -239,6 +239,18 @@ <em>Since Ant 1.7.1</em></td> <td valign="top" align="center">No, defaults to <tt>ignore</tt>. </td> </tr> + <tr> + <td valign="top">preserve0permissions</td> + <td valign="top">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.<br/> + Set this attribute to true if you really want to preserve the + original permission field.<em>since Ant 1.8.0</em> + </td> + <td valign="top" align="center">No, default is false</td> + </tr> </table> <h3>Nested elements</h3> Modified: ant/core/trunk/docs/manual/CoreTasks/war.html URL: http://svn.apache.org/viewvc/ant/core/trunk/docs/manual/CoreTasks/war.html?rev=677597&r1=677596&r2=677597&view=diff ============================================================================== --- ant/core/trunk/docs/manual/CoreTasks/war.html (original) +++ ant/core/trunk/docs/manual/CoreTasks/war.html Thu Jul 17 07:44:30 2008 @@ -202,6 +202,18 @@ (maximum compression/slowest). <em>Since Ant 1.7</em></td> <td valign="top" align="center">No</td> </tr> + <tr> + <td valign="top">preserve0permissions</td> + <td valign="top">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.<br/> + Set this attribute to true if you really want to preserve the + original permission field.<em>since Ant 1.8.0</em> + </td> + <td valign="top" align="center">No, default is false</td> + </tr> </table> <h3>Nested elements</h3> Modified: ant/core/trunk/docs/manual/CoreTasks/zip.html URL: http://svn.apache.org/viewvc/ant/core/trunk/docs/manual/CoreTasks/zip.html?rev=677597&r1=677596&r2=677597&view=diff ============================================================================== --- ant/core/trunk/docs/manual/CoreTasks/zip.html (original) +++ ant/core/trunk/docs/manual/CoreTasks/zip.html Thu Jul 17 07:44:30 2008 @@ -229,6 +229,18 @@ (maximum compression/slowest). <em>Since Ant 1.7</em></td> <td valign="top" align="center">No</td> </tr> + <tr> + <td valign="top">preserve0permissions</td> + <td valign="top">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.<br/> + Set this attribute to true if you really want to preserve the + original permission field.<em>since Ant 1.8.0</em> + </td> + <td valign="top" align="center">No, default is false</td> + </tr> </table> <h3>Parameters specified as nested elements</h3> Added: ant/core/trunk/src/etc/testcases/taskdefs/nopermissions.zip URL: http://svn.apache.org/viewvc/ant/core/trunk/src/etc/testcases/taskdefs/nopermissions.zip?rev=677597&view=auto ============================================================================== Binary file - no diff available. Propchange: ant/core/trunk/src/etc/testcases/taskdefs/nopermissions.zip ------------------------------------------------------------------------------ svn:mime-type = application/octet-stream Modified: ant/core/trunk/src/etc/testcases/taskdefs/zip.xml URL: http://svn.apache.org/viewvc/ant/core/trunk/src/etc/testcases/taskdefs/zip.xml?rev=677597&r1=677596&r2=677597&view=diff ============================================================================== --- ant/core/trunk/src/etc/testcases/taskdefs/zip.xml (original) +++ ant/core/trunk/src/etc/testcases/taskdefs/zip.xml Thu Jul 17 07:44:30 2008 @@ -248,6 +248,18 @@ </zip> </target> + <target name="rewriteZeroPermissions"> + <zip destfile="test3.zip"> + <zipfileset src="nopermissions.zip"/> + </zip> + </target> + + <target name="acceptZeroPermissions"> + <zip destfile="test3.zip" preserve0permissions="true"> + <zipfileset src="nopermissions.zip"/> + </zip> + </target> + <target name="cleanup"> <delete file="testLevel.zip"/> <delete file="test3.zip"/> Modified: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Zip.java URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Zip.java?rev=677597&r1=677596&r2=677597&view=diff ============================================================================== --- ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Zip.java (original) +++ ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Zip.java Thu Jul 17 07:44:30 2008 @@ -53,6 +53,7 @@ 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; @@ -140,6 +141,12 @@ 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. * @param zipFile the path of the zipFile @@ -402,6 +409,22 @@ } /** + * 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 @@ } 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 @@ 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); Modified: ant/core/trunk/src/main/org/apache/tools/zip/ZipEntry.java URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/zip/ZipEntry.java?rev=677597&r1=677596&r2=677597&view=diff ============================================================================== --- ant/core/trunk/src/main/org/apache/tools/zip/ZipEntry.java (original) +++ ant/core/trunk/src/main/org/apache/tools/zip/ZipEntry.java Thu Jul 17 07:44:30 2008 @@ -28,8 +28,8 @@ */ 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 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 @@ * @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 [EMAIL PROTECTED] #setUnixMode setUnixMode} - * has been called, in which case 3 (Unix) will be returned. + * @return PLATFORM_FAT unless [EMAIL PROTECTED] #setUnixMode setUnixMode} + * has been called, in which case PLATORM_UNIX will be returned. * * @since Ant 1.5.2 */ Modified: ant/core/trunk/src/tests/junit/org/apache/tools/ant/taskdefs/ZipTest.java URL: http://svn.apache.org/viewvc/ant/core/trunk/src/tests/junit/org/apache/tools/ant/taskdefs/ZipTest.java?rev=677597&r1=677596&r2=677597&view=diff ============================================================================== --- ant/core/trunk/src/tests/junit/org/apache/tools/ant/taskdefs/ZipTest.java (original) +++ ant/core/trunk/src/tests/junit/org/apache/tools/ant/taskdefs/ZipTest.java Thu Jul 17 07:44:30 2008 @@ -188,4 +188,35 @@ } } } + + 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(); + } + } + } + }