This is an automated email from the ASF dual-hosted git repository.
jaikiran pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ant.git
The following commit(s) were added to refs/heads/master by this push:
new 2dcde6093 bz-66873 correctly create the CEN extra field entry when
zip64Mode=always
2dcde6093 is described below
commit 2dcde60930555cdbc76b285786d1f723b3b9ce16
Author: Jaikiran Pai <[email protected]>
AuthorDate: Tue Aug 8 19:32:16 2023 +0530
bz-66873 correctly create the CEN extra field entry when zip64Mode=always
The fix here has been borrowed from the same fix that was done some years
back in commons-compress https://github.com/apache/commons-compress/pull/10
---
WHATSNEW | 5 +++++
src/etc/testcases/taskdefs/jar.xml | 6 +++++-
src/main/org/apache/tools/zip/ZipOutputStream.java | 17 ++++++++++++-----
.../junit/org/apache/tools/ant/taskdefs/JarTest.java | 18 ++++++++++++++++++
4 files changed, 40 insertions(+), 6 deletions(-)
diff --git a/WHATSNEW b/WHATSNEW
index 4e4252ab1..426e855f2 100644
--- a/WHATSNEW
+++ b/WHATSNEW
@@ -33,6 +33,11 @@ Fixed bugs:
if haltOnFailure was set to false. This is now fixed.
Bugzilla Report 66411
+ * fixes a bug in org.apache.tools.zip.ZipOutputStream where, even
+ when "zip64Mode" is set to "always", ZipOutputStream may not create
+ a CEN extra field data for the entry.
+ Bugzilla Report 66873
+
Other changes:
--------------
diff --git a/src/etc/testcases/taskdefs/jar.xml
b/src/etc/testcases/taskdefs/jar.xml
index 0aaeeefed..4a6238ce5 100644
--- a/src/etc/testcases/taskdefs/jar.xml
+++ b/src/etc/testcases/taskdefs/jar.xml
@@ -294,7 +294,11 @@
<attribute name="Implementation-Vendor" value="Apache Software
Foundation"/>
</manifest>
</jar>
- </target>
+ </target>
+ <target name="testZip64ModeJar" description="tests bz-66873">
+ <mkdir dir="${tmp.dir}"/>
+ <jar destfile="${tmp.dir}/zip64mode.jar" zip64mode="always" basedir="."
includes="jar.xml"/>
+ </target>
</project>
diff --git a/src/main/org/apache/tools/zip/ZipOutputStream.java
b/src/main/org/apache/tools/zip/ZipOutputStream.java
index 9e216d8ca..477e0e16e 100644
--- a/src/main/org/apache/tools/zip/ZipOutputStream.java
+++ b/src/main/org/apache/tools/zip/ZipOutputStream.java
@@ -1227,7 +1227,8 @@ public class ZipOutputStream extends FilterOutputStream {
final boolean needsZip64Extra = hasZip64Extra(ze)
|| ze.getCompressedSize() >= ZIP64_MAGIC
|| ze.getSize() >= ZIP64_MAGIC
- || lfhOffset >= ZIP64_MAGIC;
+ || lfhOffset >= ZIP64_MAGIC
+ || zip64Mode == Zip64Mode.Always;
if (needsZip64Extra && zip64Mode == Zip64Mode.Never) {
// must be the offset that is too big, otherwise an
@@ -1291,7 +1292,8 @@ public class ZipOutputStream extends FilterOutputStream {
// uncompressed length
putLong(ze.getCrc(), buf, CFH_CRC_OFFSET);
if (ze.getCompressedSize() >= ZIP64_MAGIC
- || ze.getSize() >= ZIP64_MAGIC) {
+ || ze.getSize() >= ZIP64_MAGIC
+ || zip64Mode == Zip64Mode.Always) {
ZipLong.ZIP64_MAGIC.putLong(buf, CFH_COMPRESSED_SIZE_OFFSET);
ZipLong.ZIP64_MAGIC.putLong(buf, CFH_ORIGINAL_SIZE_OFFSET);
} else {
@@ -1316,7 +1318,11 @@ public class ZipOutputStream extends FilterOutputStream {
putLong(ze.getExternalAttributes(), buf,
CFH_EXTERNAL_ATTRIBUTES_OFFSET);
// relative offset of LFH
- putLong(Math.min(lfhOffset, ZIP64_MAGIC), buf, CFH_LFH_OFFSET);
+ if (lfhOffset >= ZIP64_MAGIC || zip64Mode == Zip64Mode.Always) {
+ putLong(ZIP64_MAGIC, buf, CFH_LFH_OFFSET);
+ } else {
+ putLong(Math.min(lfhOffset, ZIP64_MAGIC), buf, CFH_LFH_OFFSET);
+ }
// file name
System.arraycopy(name.array(), name.arrayOffset(), buf,
CFH_FILENAME_OFFSET, nameLen);
@@ -1344,7 +1350,8 @@ public class ZipOutputStream extends FilterOutputStream {
if (needsZip64Extra) {
Zip64ExtendedInformationExtraField z64 = getZip64Extra(ze);
if (ze.getCompressedSize() >= ZIP64_MAGIC
- || ze.getSize() >= ZIP64_MAGIC) {
+ || ze.getSize() >= ZIP64_MAGIC
+ || zip64Mode == Zip64Mode.Always) {
z64.setCompressedSize(new
ZipEightByteInteger(ze.getCompressedSize()));
z64.setSize(new ZipEightByteInteger(ze.getSize()));
} else {
@@ -1352,7 +1359,7 @@ public class ZipOutputStream extends FilterOutputStream {
z64.setCompressedSize(null);
z64.setSize(null);
}
- if (lfhOffset >= ZIP64_MAGIC) {
+ if (lfhOffset >= ZIP64_MAGIC || zip64Mode == Zip64Mode.Always) {
z64.setRelativeHeaderOffset(new
ZipEightByteInteger(lfhOffset));
}
ze.setExtra();
diff --git a/src/tests/junit/org/apache/tools/ant/taskdefs/JarTest.java
b/src/tests/junit/org/apache/tools/ant/taskdefs/JarTest.java
index 21cdd6847..737d3a275 100644
--- a/src/tests/junit/org/apache/tools/ant/taskdefs/JarTest.java
+++ b/src/tests/junit/org/apache/tools/ant/taskdefs/JarTest.java
@@ -42,6 +42,7 @@ import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
@@ -453,4 +454,21 @@ public class JarTest {
assertThat(buildRule.getLog(), not(containsString("No
Implementation-Vendor set.")));
}
+ /**
+ * Uses the jar task to create a jar which has zip64mode=always, so that
the zip entries
+ * use zip64 extra field. The jar is expected to be created successfully.
The test then
+ * use {@link ZipFile java.util.zip.ZipFile} API to open that jar file and
the test expects
+ * that it succeeds in doing so.
+ */
+ @Test
+ public void testZip64ModeJar() throws IOException {
+ // invoke the target
+ buildRule.executeTarget("testZip64ModeJar");
+ final File zip64Modejar = new File(getOutputDir(), tempDir +
"zip64mode.jar");
+ // verify the jar can be opened using java.util.zip.ZipFile
+ try (final ZipFile archive = new ZipFile(zip64Modejar)) {
+ final ZipEntry ze = archive.getEntry("jar.xml");
+ assertNotNull("Missing jar.xml in " + zip64Modejar, ze);
+ }
+ }
}