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]);


Reply via email to