Author: bodewig
Date: Thu Jul 28 16:53:32 2011
New Revision: 1151925

URL: http://svn.apache.org/viewvc?rev=1151925&view=rev
Log:
properly write ZIP64 central directories if the number of entries, the size of 
the central directory or its location exceed the ZIP32 limit.  COMPRESS-150

Modified:
    
commons/proper/compress/branches/zip64/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java
    
commons/proper/compress/branches/zip64/src/main/java/org/apache/commons/compress/archivers/zip/ZipConstants.java

Modified: 
commons/proper/compress/branches/zip64/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java
URL: 
http://svn.apache.org/viewvc/commons/proper/compress/branches/zip64/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java?rev=1151925&r1=1151924&r2=1151925&view=diff
==============================================================================
--- 
commons/proper/compress/branches/zip64/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java
 (original)
+++ 
commons/proper/compress/branches/zip64/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java
 Thu Jul 28 16:53:32 2011
@@ -40,6 +40,8 @@ import static org.apache.commons.compres
 import static org.apache.commons.compress.archivers.zip.ZipConstants.DWORD;
 import static org.apache.commons.compress.archivers.zip.ZipConstants.SHORT;
 import static org.apache.commons.compress.archivers.zip.ZipConstants.WORD;
+import static 
org.apache.commons.compress.archivers.zip.ZipConstants.ZIP64_MAGIC;
+import static 
org.apache.commons.compress.archivers.zip.ZipConstants.ZIP64_MAGIC_SHORT;
 import static 
org.apache.commons.compress.archivers.zip.ZipConstants.ZIP64_MIN_VERSION;
 
 /**
@@ -879,13 +881,14 @@ public class ZipArchiveOutputStream exte
         writeOut(ZERO);
 
         // number of entries
-        byte[] num = ZipShort.getBytes(entries.size());
+        byte[] num = ZipShort.getBytes(Math.min(entries.size(),
+                                                ZIP64_MAGIC_SHORT));
         writeOut(num);
         writeOut(num);
 
         // length and location of CD
-        writeOut(ZipLong.getBytes(cdLength));
-        writeOut(ZipLong.getBytes(cdOffset));
+        writeOut(ZipLong.getBytes(Math.min(cdLength, ZIP64_MAGIC)));
+        writeOut(ZipLong.getBytes(Math.min(cdOffset, ZIP64_MAGIC)));
 
         // ZIP file comment
         ByteBuffer data = this.zipEncoding.encode(comment);
@@ -896,12 +899,21 @@ public class ZipArchiveOutputStream exte
     private static final byte[] ONE = ZipLong.getBytes(1L);
 
     /**
-     * Writes the "ZIP64 End of central dir record" and "ZIP64 
End of central dir locator".
+     * Writes the "ZIP64 End of central dir record" and
+     * "ZIP64 End of central dir locator".
      * @throws IOException on error
      * @since Apache Commons Compress 1.3
      */
     protected void writeZip64CentralDirectory() throws IOException {
         if (!hasUsedZip64) {
+            if (cdOffset >= ZIP64_MAGIC || cdLength >= ZIP64_MAGIC
+                || entries.size() >= ZIP64_MAGIC_SHORT) {
+                // actually "will use"
+                hasUsedZip64 = true;
+            }
+        }
+
+        if (!hasUsedZip64) {
             return;
         }
 

Modified: 
commons/proper/compress/branches/zip64/src/main/java/org/apache/commons/compress/archivers/zip/ZipConstants.java
URL: 
http://svn.apache.org/viewvc/commons/proper/compress/branches/zip64/src/main/java/org/apache/commons/compress/archivers/zip/ZipConstants.java?rev=1151925&r1=1151924&r2=1151925&view=diff
==============================================================================
--- 
commons/proper/compress/branches/zip64/src/main/java/org/apache/commons/compress/archivers/zip/ZipConstants.java
 (original)
+++ 
commons/proper/compress/branches/zip64/src/main/java/org/apache/commons/compress/archivers/zip/ZipConstants.java
 Thu Jul 28 16:53:32 2011
@@ -42,4 +42,17 @@ final class ZipConstants {
 
     /** ZIP specification version that introduced ZIP64 */
     static final int ZIP64_MIN_VERSION = 45;
+
+    /**
+     * Value stored in two-byte size and similar fields if ZIP64
+     * extensions are used.
+     */
+    static final int ZIP64_MAGIC_SHORT = 0xFFFF;
+
+    /**
+     * Value stored in four-byte size and similar fields if ZIP64
+     * extensions are used.
+     */
+    static final long ZIP64_MAGIC = 0xFFFFFFFFL;
+
 }


Reply via email to