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; + }