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 624D97FE8 for ; Wed, 3 Aug 2011 15:17:19 +0000 (UTC) Received: (qmail 76315 invoked by uid 500); 3 Aug 2011 15:17:19 -0000 Delivered-To: apmail-commons-commits-archive@commons.apache.org Received: (qmail 76198 invoked by uid 500); 3 Aug 2011 15:17:18 -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 76191 invoked by uid 99); 3 Aug 2011 15:17:18 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 03 Aug 2011 15:17:18 +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 15:17:16 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id BC34B238890D for ; Wed, 3 Aug 2011 15:16:56 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1153535 - /commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java Date: Wed, 03 Aug 2011 15:16:56 -0000 To: commits@commons.apache.org From: bodewig@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20110803151656.BC34B238890D@eris.apache.org> Author: bodewig Date: Wed Aug 3 15:16:55 2011 New Revision: 1153535 URL: http://svn.apache.org/viewvc?rev=1153535&view=rev Log: Extract the 'search the archive backwards for a signature' logic so it can be reused to serach for the ZIP64 end of central directory locator Modified: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java Modified: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java?rev=1153535&r1=1153534&r2=1153535&view=diff ============================================================================== --- commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java (original) +++ commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java Wed Aug 3 15:16:55 2011 @@ -34,6 +34,8 @@ import java.util.zip.ZipException; 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; /** * Replacement for java.util.ZipFile. @@ -499,7 +501,7 @@ public class ZipFile { /* zipfile comment length */ + SHORT; private static final int MAX_EOCD_SIZE = MIN_EOCD_SIZE - /* maximum length of zipfile comment */ + 0xFFFF; + /* maximum length of zipfile comment */ + ZIP64_MAGIC_SHORT; private static final int CFD_LOCATOR_OFFSET = /* end of central dir signature */ WORD @@ -519,12 +521,30 @@ public class ZipFile { */ private void positionAtCentralDirectory() throws IOException { + boolean found = tryToLocateSignature(MIN_EOCD_SIZE, MAX_EOCD_SIZE, + ZipArchiveOutputStream.EOCD_SIG); + if (!found) { + throw new ZipException("archive is not a ZIP archive"); + } + archive.skipBytes(CFD_LOCATOR_OFFSET); + byte[] cfdOffset = new byte[WORD]; + archive.readFully(cfdOffset); + archive.seek(ZipLong.getValue(cfdOffset)); + } + + /** + * Searches the archive backwards from minDistance to maxDistance + * for the given signature, positions the RandomaccessFile right + * at the signature if it has been found. + */ + private boolean tryToLocateSignature(long minDistanceFromEnd, + long maxDistanceFromEnd, + byte[] sig) throws IOException { boolean found = false; - long off = archive.length() - MIN_EOCD_SIZE; - long stopSearching = Math.max(0L, archive.length() - MAX_EOCD_SIZE); + long off = archive.length() - minDistanceFromEnd; + long stopSearching = Math.max(0L, archive.length() - maxDistanceFromEnd); if (off >= 0) { archive.seek(off); - byte[] sig = ZipArchiveOutputStream.EOCD_SIG; int curr = archive.read(); while (off >= stopSearching && curr != -1) { if (curr == sig[POS_0]) { @@ -544,13 +564,10 @@ public class ZipFile { curr = archive.read(); } } - if (!found) { - throw new ZipException("archive is not a ZIP archive"); + if (found) { + archive.seek(off); } - archive.seek(off + CFD_LOCATOR_OFFSET); - byte[] cfdOffset = new byte[WORD]; - archive.readFully(cfdOffset); - archive.seek(ZipLong.getValue(cfdOffset)); + return found; } /**