Return-Path: X-Original-To: apmail-commons-commits-archive@minotaur.apache.org Delivered-To: apmail-commons-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 6FF72721D for ; Wed, 3 Aug 2011 09:56:35 +0000 (UTC) Received: (qmail 47919 invoked by uid 500); 3 Aug 2011 09:56:34 -0000 Delivered-To: apmail-commons-commits-archive@commons.apache.org Received: (qmail 47224 invoked by uid 500); 3 Aug 2011 09:56:21 -0000 Mailing-List: contact commits-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@commons.apache.org Delivered-To: mailing list commits@commons.apache.org Received: (qmail 47208 invoked by uid 99); 3 Aug 2011 09:56:19 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 03 Aug 2011 09:56:19 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 03 Aug 2011 09:56:16 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 2318623889DA for ; Wed, 3 Aug 2011 09:55:55 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit 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 -0000 To: commits@commons.apache.org From: bodewig@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20110803095555.2318623889DA@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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();