Author: bodewig
Date: Sat Aug 13 03:48:25 2011
New Revision: 1157312

URL: http://svn.apache.org/viewvc?rev=1157312&view=rev
Log:
It seems WinZip uses 'version needed to extract' from the central directory 
entry to parse the local file header ignoring the 'version' stored in the LFH.  
Make sure the two values agree, which they did not in 'Always' mode.

Modified:
    
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java
    
commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/Zip64SupportIT.java

Modified: 
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java
URL: 
http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java?rev=1157312&r1=1157311&r2=1157312&view=diff
==============================================================================
--- 
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java
 (original)
+++ 
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java
 Sat Aug 13 03:48:25 2011
@@ -384,7 +384,7 @@ public class ZipArchiveOutputStream exte
      * any entry has initially been unknown and create an archive
      * identical to {@link Zip64Mode#Never Never} otherwise.  {@link
      * Zip64Mode#Always Always} will create an archive that is at
-     * least 20 bytes per entry bigger than the one {@link
+     * least 24 bytes per entry bigger than the one {@link
      * Zip64Mode#Never Never} would create.</p>
      *
      * <p>Defaults to {@link Zip64Mode#AsNeeded AsNeeded} unless
@@ -1016,7 +1016,8 @@ public class ZipArchiveOutputStream exte
         written += WORD;
 
         final long lfhOffset = offsets.get(ze).longValue();
-        final boolean needsZip64Extra = ze.getCompressedSize() >= ZIP64_MAGIC
+        final boolean needsZip64Extra = hasZip64Extra(ze)
+            || ze.getCompressedSize() >= ZIP64_MAGIC
             || ze.getSize() >= ZIP64_MAGIC
             || lfhOffset >= ZIP64_MAGIC;
 
@@ -1121,8 +1122,7 @@ public class ZipArchiveOutputStream exte
 
     /**
      * If the entry needs Zip64 extra information inside the central
-     * director then configure its data, otherwise remove it if one is
-     * present.
+     * directory then configure its data.
      */
     private void handleZip64Extra(ZipArchiveEntry ze, long lfhOffset,
                                   boolean needsZip64Extra) {
@@ -1141,11 +1141,6 @@ public class ZipArchiveOutputStream exte
                 z64.setRelativeHeaderOffset(new 
ZipEightByteInteger(lfhOffset));
             }
             ze.setExtra();
-        } else if (hasZip64Extra(ze)) {
-            // added to LFH but not really needed, probably because of
-            // Zip64Mode.Always
-            ze.removeExtraField(Zip64ExtendedInformationExtraField.HEADER_ID);
-            ze.setExtra();
         }
     }
 

Modified: 
commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/Zip64SupportIT.java
URL: 
http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/Zip64SupportIT.java?rev=1157312&r1=1157311&r2=1157312&view=diff
==============================================================================
--- 
commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/Zip64SupportIT.java
 (original)
+++ 
commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/Zip64SupportIT.java
 Sat Aug 13 03:48:25 2011
@@ -326,7 +326,10 @@ public class Zip64SupportIT {
                     // skip first two entries
                     a.skipBytes(2 * 47 /* CD entry of file with
                                           file name length 1 and no
-                                          extra data */);
+                                          extra data */
+                                + 2 * (mode == Zip64Mode.Always ? 4 : 0)
+                                /* empty ZIP64 extra fields if mode is Always 
*/
+                                );
 
                     // grab third entry, verify offset is
                     // 0xFFFFFFFF and it has a ZIP64 extended
@@ -1449,8 +1452,7 @@ public class Zip64SupportIT {
                     final long end = getLengthAndPositionAtCentralDirectory(a);
 
                     // grab first CF entry, verify sizes are 1e6 and it
-                    // has no ZIP64 extended information extra field
-                    // at all
+                    // has an empty ZIP64 extended information extra field
                     byte[] header = new byte[12];
                     a.readFully(header);
                     assertArrayEquals(new byte[] {
@@ -1459,7 +1461,7 @@ public class Zip64SupportIT {
                             // version made by
                             45, 0,
                             // version needed to extract
-                            10, 0,
+                            45, 0,
                             // GPB (EFS bit)
                             0, 8,
                             // method
@@ -1480,7 +1482,7 @@ public class Zip64SupportIT {
                             // file name length
                             1, 0,
                             // extra field length
-                            0, 0,
+                            4, 0,
                             // comment length
                             0, 0,
                             // disk number
@@ -1494,6 +1496,15 @@ public class Zip64SupportIT {
                             (byte) '0'
                         }, rest);
 
+                    byte[] extra = new byte[4];
+                    a.readFully(extra);
+                    assertArrayEquals(new byte[] {
+                            // Header-ID
+                            1, 0,
+                            // size of extra
+                            0, 0,
+                        }, extra);
+
                     // and now validate local file header: this one
                     // has a ZIP64 extra field as the mode was
                     // Always
@@ -1530,7 +1541,7 @@ public class Zip64SupportIT {
                             (byte) '0'
                         }, rest);
 
-                    byte[] extra = new byte[20];
+                    extra = new byte[20];
                     a.readFully(extra);
                     assertArrayEquals(new byte[] {
                             // Header-ID
@@ -1775,7 +1786,7 @@ public class Zip64SupportIT {
 
                     long cfhPos = a.getFilePointer();
                     // grab first entry, verify sizes are not
-                    // 0xFFFFFFF and it has no ZIP64 extended
+                    // 0xFFFFFFF and it has an empty ZIP64 extended
                     // information extra field
                     byte[] header = new byte[12];
                     a.readFully(header);
@@ -1785,7 +1796,7 @@ public class Zip64SupportIT {
                             // version made by
                             45, 0,
                             // version needed to extract
-                            20, 0,
+                            45, 0,
                             // GPB (EFS + Data Descriptor)
                             8, 8,
                             // method
@@ -1810,7 +1821,7 @@ public class Zip64SupportIT {
                             // file name length
                             1, 0,
                             // extra field length
-                            0, 0,
+                            4, 0,
                             // comment length
                             0, 0,
                             // disk number
@@ -1823,6 +1834,14 @@ public class Zip64SupportIT {
                             // file name
                             (byte) '0'
                         }, rest);
+                    byte[] extra = new byte[4];
+                    a.readFully(extra);
+                    assertArrayEquals(new byte[] {
+                            // Header-ID
+                            1, 0,
+                            // size of extra
+                            0, 0,
+                        }, extra);
 
                     // validate data descriptor
                     a.seek(cfhPos - 24);
@@ -1877,7 +1896,7 @@ public class Zip64SupportIT {
                             (byte) '0'
                         }, rest);
 
-                    byte[] extra = new byte[20];
+                    extra = new byte[20];
                     a.readFully(extra);
                     assertArrayEquals(new byte[] {
                             // Header-ID
@@ -2124,7 +2143,7 @@ public class Zip64SupportIT {
 
                     long cfhPos = a.getFilePointer();
                     // grab first CD entry, verify sizes are not
-                    // 0xFFFFFFFF and it has a no ZIP64 extended
+                    // 0xFFFFFFFF and it has a an empty ZIP64 extended
                     // information extra field
                     byte[] header = new byte[12];
                     a.readFully(header);
@@ -2134,7 +2153,7 @@ public class Zip64SupportIT {
                             // version made by
                             45, 0,
                             // version needed to extract
-                            10, 0,
+                            45, 0,
                             // GPB (EFS + *no* Data Descriptor)
                             0, 8,
                             // method
@@ -2157,7 +2176,7 @@ public class Zip64SupportIT {
                             // file name length
                             1, 0,
                             // extra field length
-                            0, 0,
+                            4, 0,
                             // comment length
                             0, 0,
                             // disk number
@@ -2170,6 +2189,14 @@ public class Zip64SupportIT {
                             // file name
                             (byte) '0'
                         }, rest);
+                    byte[] extra = new byte[4];
+                    a.readFully(extra);
+                    assertArrayEquals(new byte[] {
+                            // Header-ID
+                            1, 0,
+                            // size of extra
+                            0, 0,
+                        }, extra);
 
                     // and now validate local file header
                     a.seek(0);
@@ -2209,7 +2236,7 @@ public class Zip64SupportIT {
                             (byte) '0'
                         }, rest);
 
-                    byte[] extra = new byte[12];
+                    extra = new byte[12];
                     a.readFully(extra);
                     assertArrayEquals(new byte[] {
                             // Header-ID


Reply via email to