Author: bodewig Date: Thu Aug 4 05:25:28 2011 New Revision: 1153755 URL: http://svn.apache.org/viewvc?rev=1153755&view=rev Log: infrastructure that is going to be needed by ZipFile in order to correctly parse ZIP64 data from the central directory. COMPRESS-149
Modified: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/Zip64ExtendedInformationExtraField.java commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/Zip64ExtendedInformationExtraFieldTest.java Modified: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/Zip64ExtendedInformationExtraField.java URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/Zip64ExtendedInformationExtraField.java?rev=1153755&r1=1153754&r2=1153755&view=diff ============================================================================== --- commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/Zip64ExtendedInformationExtraField.java (original) +++ commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/Zip64ExtendedInformationExtraField.java Thu Aug 4 05:25:28 2011 @@ -85,6 +85,18 @@ public class Zip64ExtendedInformationExt private ZipLong diskStart; /** + * Stored in {@link #parseFromCentralDirectoryData + * parseFromCentralDirectoryData} so it can be reused when ZipFile + * calls {@link #reparseCentralDirectoryData + * reparseCentralDirectoryData}. + * + * <p>Not used for anything else</p> + * + * @since Apache Commons Compress 1.3 + */ + private byte[] rawCentralDirectoryData; + + /** * This constructor should only be used by the code that reads * archives inside of Commons Compress. */ @@ -194,6 +206,10 @@ public class Zip64ExtendedInformationExt public void parseFromCentralDirectoryData(byte[] buffer, int offset, int length) throws ZipException { + // store for processing in reparseCentralDirectoryData + rawCentralDirectoryData = new byte[length]; + System.arraycopy(buffer, offset, rawCentralDirectoryData, 0, length); + // if there is no size information in here, we are screwed and // can only hope things will get resolved by LFH data later // But there are some cases that can be detected @@ -214,6 +230,55 @@ public class Zip64ExtendedInformationExt } /** + * Parses the raw bytes read from the central directory extra + * field with knowledge which fields are expected to be there. + * + * <p>All four fields inside the zip64 extended information extra + * field are optional and only present if their corresponding + * entry inside the central directory contains the correct magic + * value.</p> + */ + public void reparseCentralDirectoryData(boolean hasUncompressedSize, + boolean hasCompressedSize, + boolean hasRelativeHeaderOffset, + boolean hasDiskStart) + throws ZipException { + if (rawCentralDirectoryData != null) { + int expectedLength = (hasUncompressedSize ? DWORD : 0) + + (hasCompressedSize ? DWORD : 0) + + (hasRelativeHeaderOffset ? DWORD : 0) + + (hasDiskStart ? WORD : 0); + if (rawCentralDirectoryData.length != expectedLength) { + throw new ZipException("central directory zip64 extended" + + " information extra field's length" + + " doesn't match central directory" + + " data. Expected length " + + expectedLength + " but is " + + rawCentralDirectoryData.length); + } + int offset = 0; + if (hasUncompressedSize) { + size = new ZipEightByteInteger(rawCentralDirectoryData, offset); + offset += DWORD; + } + if (hasCompressedSize) { + compressedSize = new ZipEightByteInteger(rawCentralDirectoryData, + offset); + offset += DWORD; + } + if (hasRelativeHeaderOffset) { + relativeHeaderOffset = + new ZipEightByteInteger(rawCentralDirectoryData, offset); + offset += DWORD; + } + if (hasDiskStart) { + diskStart = new ZipLong(rawCentralDirectoryData, offset); + offset += WORD; + } + } + } + + /** * The uncompressed size stored in this extra field. */ public ZipEightByteInteger getSize() { Modified: commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/Zip64ExtendedInformationExtraFieldTest.java URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/Zip64ExtendedInformationExtraFieldTest.java?rev=1153755&r1=1153754&r2=1153755&view=diff ============================================================================== --- commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/Zip64ExtendedInformationExtraFieldTest.java (original) +++ commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/Zip64ExtendedInformationExtraFieldTest.java Thu Aug 4 05:25:28 2011 @@ -175,6 +175,31 @@ public class Zip64ExtendedInformationExt assertEquals(DISK, f.getDiskStartNumber()); } + public void testReparseCDSingleEightByteData() throws ZipException { + Zip64ExtendedInformationExtraField f = + new Zip64ExtendedInformationExtraField(); + byte[] b = new byte[8]; + System.arraycopy(SIZE.getBytes(), 0, b, 0, 8); + f.parseFromCentralDirectoryData(b, 0, b.length); + f.reparseCentralDirectoryData(true, false, false, false); + assertEquals(SIZE, f.getSize()); + assertNull(f.getCompressedSize()); + assertNull(f.getRelativeHeaderOffset()); + assertNull(f.getDiskStartNumber()); + f.setSize(null); + f.reparseCentralDirectoryData(false, true, false, false); + assertNull(f.getSize()); + assertEquals(SIZE, f.getCompressedSize()); + assertNull(f.getRelativeHeaderOffset()); + assertNull(f.getDiskStartNumber()); + f.setCompressedSize(null); + f.reparseCentralDirectoryData(false, false, true, false); + assertNull(f.getSize()); + assertNull(f.getCompressedSize()); + assertEquals(SIZE, f.getRelativeHeaderOffset()); + assertNull(f.getDiskStartNumber()); + } + private static void checkSizes(byte[] b) { assertEquals(0x78, b[0]); assertEquals(0x56, b[1]);