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);
+        }
+    }
 }

Reply via email to