Author: bodewig Date: Fri Jul 29 19:22:48 2011 New Revision: 1152342 URL: http://svn.apache.org/viewvc?rev=1152342&view=rev Log: If the entry has a ZIP64 extra field, sizes inside the data descriptor must be eight bytes long. COMPRESS-150
Modified: commons/proper/compress/branches/zip64/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.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=1152342&r1=1152341&r2=1152342&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 Fri Jul 29 19:22:48 2011 @@ -180,6 +180,11 @@ public class ZipArchiveOutputStream exte private static final byte[] LZERO = {0, 0, 0, 0}; /** + * Helper, a 0 as ZipEightByteInteger. + */ + private static final byte[] DLZERO = {0, 0, 0, 0, 0, 0, 0, 0}; + + /** * Holds the offsets of the LFH starts for each entry. */ private final Map<ZipArchiveEntry, Long> offsets = @@ -467,7 +472,7 @@ public class ZipArchiveOutputStream exte // Size/CRC not required if RandomAccessFile is used if (entry.getMethod() == STORED && raf == null) { - if (entry.getSize() == -1) { + if (entry.getSize() == ArchiveEntry.SIZE_UNKNOWN) { throw new ZipException("uncompressed size is required for" + " STORED method when not writing to a" + " file"); @@ -762,11 +767,16 @@ public class ZipArchiveOutputStream exte } writeOut(DD_SIG); writeOut(ZipLong.getBytes(entry.getCrc())); - writeOut(ZipLong.getBytes(entry.getCompressedSize())); - writeOut(ZipLong.getBytes(entry.getSize())); - // CheckStyle:MagicNumber OFF - written += 16; - // CheckStyle:MagicNumber ON + int sizeFieldSize = WORD; + if (!hasZip64Extra(ze)) { + writeOut(ZipLong.getBytes(entry.getCompressedSize())); + writeOut(ZipLong.getBytes(entry.getSize())); + } else { + sizeFieldSize = DWORD; + writeOut(ZipEightByteInteger.getBytes(entry.getCompressedSize())); + writeOut(ZipEightByteInteger.getBytes(entry.getSize())); + } + written += 2 * WORD + 2 * sizeFieldSize; } /** @@ -784,20 +794,18 @@ public class ZipArchiveOutputStream exte || lfhOffset >= ZIP64_MAGIC; if (needsZip64Extra) { - hasUsedZip64 = true; - Zip64ExtendedInformationExtraField z64 = - (Zip64ExtendedInformationExtraField) - ze.getExtraField(Zip64ExtendedInformationExtraField - .HEADER_ID); - if (z64 == null) { - z64 = new Zip64ExtendedInformationExtraField(); - ze.addExtraField(z64); - } - if (ze.getCompressedSize() >= ZIP64_MAGIC) { + Zip64ExtendedInformationExtraField z64 = getZip64Extra(ze); + if (ze.getCompressedSize() >= ZIP64_MAGIC) { z64.setCompressedSize(new ZipEightByteInteger(ze.getCompressedSize())); + } else { + // reset value that may have been set for LFH + z64.setCompressedSize(null); } if (ze.getSize() >= ZIP64_MAGIC) { z64.setSize(new ZipEightByteInteger(ze.getSize())); + } else { + // reset value that may have been set for LFH + z64.setSize(null); } if (lfhOffset >= ZIP64_MAGIC) { z64.setRelativeHeaderOffset(new ZipEightByteInteger(lfhOffset)); @@ -1099,4 +1107,36 @@ public class ZipArchiveOutputStream exte } return new ZipArchiveEntry(inputFile, entryName); } + + /** + * Get the existing ZIP64 extended information extra field or + * create a new one and add it to the entry. + * + * @since Apache Commons Compress 1.3 + */ + private Zip64ExtendedInformationExtraField + getZip64Extra(ZipArchiveEntry ze) { + hasUsedZip64 = true; + Zip64ExtendedInformationExtraField z64 = + (Zip64ExtendedInformationExtraField) + ze.getExtraField(Zip64ExtendedInformationExtraField + .HEADER_ID); + if (z64 == null) { + z64 = new Zip64ExtendedInformationExtraField(); + ze.addExtraField(z64); + } + return z64; + } + + /** + * Is there a ZIP64 extended information extra field for the + * entry? + * + * @since Apache Commons Compress 1.3 + */ + private boolean hasZip64Extra(ZipArchiveEntry ze) { + return ze.getExtraField(Zip64ExtendedInformationExtraField + .HEADER_ID) + != null; + } }