git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@677597 13f79535-47bb-0310-9956-ffa450edef68master
@@ -63,6 +63,20 @@ Changes that could break older environments: | |||
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: | |||
----------- | |||
@@ -185,6 +185,18 @@ to a value other than its default, <code>"add"</code>.</b></p> | |||
(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> | |||
@@ -239,6 +239,18 @@ to a value other than its default, <code>"add"</code>.</b></p> | |||
<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> | |||
@@ -202,6 +202,18 @@ to a value other than its default, <code>"add"</code>.</b></p> | |||
(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> | |||
@@ -229,6 +229,18 @@ archive.</p> | |||
(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> | |||
@@ -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"/> | |||
@@ -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); | |||
@@ -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 | |||
*/ | |||
@@ -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(); | |||
} | |||
} | |||
} | |||
} |