commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bode...@apache.org
Subject svn commit: r1153415 - in /commons/proper/compress/trunk/src: main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java test/java/org/apache/commons/compress/archivers/zip/Zip64SupportTest.java
Date Wed, 03 Aug 2011 09:55:54 GMT
Author: bodewig
Date: Wed Aug  3 09:55:53 2011
New Revision: 1153415

URL: http://svn.apache.org/viewvc?rev=1153415&view=rev
Log:
don't rely on archives to implement ZIP64 correctly when reading the data descriptor.  Works
around a bug in java.util.ZipArchiveOutputStream of Java7, may be useful for other implementations
as well.  COMPRESS-148

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

Modified: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java?rev=1153415&r1=1153414&r2=1153415&view=diff
==============================================================================
--- commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java
(original)
+++ commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java
Wed Aug  3 09:55:53 2011
@@ -457,9 +457,7 @@ public class ZipArchiveInputStream exten
 
             // Pushback any required bytes
             if (diff > 0) {
-                ((PushbackInputStream) in).unread(
-                        buf,  lengthOfLastRead - diff, diff);
-                pushedBackBytes(diff);
+                pushback(buf, lengthOfLastRead - diff, diff);
             }
         }
 
@@ -506,17 +504,29 @@ public class ZipArchiveInputStream exten
             val = new ZipLong(b);
         }
         current.setCrc(val.getValue());
-        if (!usesZip64) {
-            readFully(b);
+
+        // if there is a ZIP64 extra field, sizes are eight bytes
+        // each, otherwise four bytes each.  Unfortunately some
+        // implementations - namely Java7 - use eight bytes without
+        // using a ZIP64 extra field -
+        // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7073588
+
+        // just read 16 bytes and check whether bytes nine to twelve
+        // look like one of the signatures of what could follow a data
+        // descriptor (ignoring archive decryption headers for now).
+        // If so, push back eight bytes and assume sizes are four
+        // bytes, otherwise sizes are eight bytes each.
+        b = new byte[2 * DWORD];
+        readFully(b);
+        ZipLong potentialSig = new ZipLong(b, DWORD);
+        if (potentialSig.equals(ZipLong.CFH_SIG)
+            || potentialSig.equals(ZipLong.LFH_SIG)) {
+            pushback(b, DWORD, DWORD);
             current.setCompressedSize(ZipLong.getValue(b));
-            readFully(b);
-            current.setSize(ZipLong.getValue(b));
+            current.setSize(ZipLong.getValue(b, WORD));
         } else {
-            byte[] b8 = new byte[DWORD];
-            readFully(b8);
-            current.setCompressedSize(ZipEightByteInteger.getLongValue(b8));
-            readFully(b8);
-            current.setSize(ZipEightByteInteger.getLongValue(b8));
+            current.setCompressedSize(ZipEightByteInteger.getLongValue(b));
+            current.setSize(ZipEightByteInteger.getLongValue(b, DWORD));
         }
     }
 
@@ -593,7 +603,7 @@ public class ZipArchiveInputStream exten
                         //   descriptor
                         // * copy the remaining bytes to cache
                         // * read data descriptor
-                        ((PushbackInputStream) in).unread(buf, off + r - readTooMuch, readTooMuch);
+                        pushback(buf, off + r - readTooMuch, readTooMuch);
                         bos.write(buf, 0, i);
                         readDataDescriptor();
                     }
@@ -619,4 +629,10 @@ public class ZipArchiveInputStream exten
         byte[] b = bos.toByteArray();
         lastStoredEntry = new ByteArrayInputStream(b);
     }
+
+    private void pushback(byte[] buf, int offset, int length)
+        throws IOException {
+        ((PushbackInputStream) in).unread(buf, offset, length);
+        pushedBackBytes(length);
+    }
 }

Modified: commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/Zip64SupportTest.java
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/Zip64SupportTest.java?rev=1153415&r1=1153414&r2=1153415&view=diff
==============================================================================
--- commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/Zip64SupportTest.java
(original)
+++ commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/Zip64SupportTest.java
Wed Aug  3 09:55:53 2011
@@ -53,11 +53,7 @@ public class Zip64SupportTest {
 
     @Test public void read5GBOfZerosGeneratedByJava7JarUsingInputStream()
         throws Throwable {
-        // don't check the size in jar case as jar uses 8-Byte values
-        // inside the data descriptor without adding a ZIP64 extra
-        // field, violating the "spec".
-        read5GBOfZerosImpl(get5GBZerosFileGeneratedByJava7Jar(), "5GB_of_Zeros",
-                           false);
+        read5GBOfZerosImpl(get5GBZerosFileGeneratedByJava7Jar(), "5GB_of_Zeros");
     }
 
     @Test public void read100KFilesUsingInputStream() throws Throwable {
@@ -1340,12 +1336,6 @@ public class Zip64SupportTest {
 
     private static void read5GBOfZerosImpl(File f, String expectedName)
         throws IOException {
-        read5GBOfZerosImpl(f, expectedName, true);
-    }
-
-    private static void read5GBOfZerosImpl(File f, String expectedName,
-                                           boolean checkSize)
-        throws IOException {
         FileInputStream fin = new FileInputStream(f);
         ZipArchiveInputStream zin = null;
         try {
@@ -1367,9 +1357,7 @@ public class Zip64SupportTest {
             }
             assertEquals(FIVE_BILLION, read);
             assertNull(zin.getNextZipEntry());
-            if (checkSize) {
-                assertEquals(FIVE_BILLION, zae.getSize());
-            }
+            assertEquals(FIVE_BILLION, zae.getSize());
         } finally {
             if (zin != null) {
                 zin.close();



Mime
View raw message