You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ju...@apache.org on 2009/12/13 19:31:55 UTC

svn commit: r890088 - in /commons/proper/compress/trunk/src: main/java/org/apache/commons/compress/archivers/zip/ test/java/org/apache/commons/compress/archivers/ test/java/org/apache/commons/compress/archivers/zip/ test/resources/

Author: jukka
Date: Sun Dec 13 18:31:55 2009
New Revision: 890088

URL: http://svn.apache.org/viewvc?rev=890088&view=rev
Log:
COMPRESS-93: Support for alternative ZIP compression methods

Override the ZipEntry compression method getter and setter in ZipArchiveEntry. This prevents the IllegalArgumentException that was thrown whenever a zip entry with an unsupported compression method was encountered. With this change an IOException is thrown instead only if or when the entry is actually being read or written. In addition, a public ZipArchiveEntry.isSupportedCompressionMethod() method is introduced so client code can choose to explicitly skip reading ZIP entries with unsupported compression methods.

Added:
    commons/proper/compress/trunk/src/test/resources/moby.zip   (with props)
Modified:
    commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveEntry.java
    commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java
    commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java
    commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/ZipTestCase.java
    commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipArchiveEntryTest.java

Modified: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveEntry.java
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveEntry.java?rev=890088&r1=890087&r2=890088&view=diff
==============================================================================
--- commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveEntry.java (original)
+++ commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveEntry.java Sun Dec 13 18:31:55 2009
@@ -37,6 +37,18 @@
     private static final int SHORT_MASK = 0xFFFF;
     private static final int SHORT_SHIFT = 16;
 
+    /**
+     * The {@link java.util.zip.ZipEntry} base class only supports
+     * the compression methods STORED and DEFLATED. We override the
+     * field so that any compression methods can be used.
+     * <p>
+     * The default value -1 means that the method has not been specified.
+     *
+     * @see <a href="https://issues.apache.org/jira/browse/COMPRESS-93"
+     *        >COMPRESS-93</a>
+     */
+    private int method = -1;
+
     private int internalAttributes = 0;
     private int platform = PLATFORM_FAT;
     private long externalAttributes = 0;
@@ -66,6 +78,7 @@
             // initializes extra data to an empty byte array
             setExtra();
         }
+        setMethod(entry.getMethod());
     }
 
     /**
@@ -111,6 +124,43 @@
     }
 
     /**
+     * Checks whether the compression method of this entry is supported,
+     * i.e. whether the content of this entry can be accessed.
+     *
+     * @since Commons Compress 1.1
+     * @see <a href="https://issues.apache.org/jira/browse/COMPRESS-93"
+     *         >COMPRESS-93</a>
+     * @return <code>true</code> if the compression method is known
+     *         and supported, <code>false</code> otherwise
+     */
+    public boolean isSupportedCompressionMethod() {
+        return method == STORED || method == DEFLATED;
+    }
+
+    /**
+     * Returns the compression method of this entry, or -1 if the
+     * compression method has not been specified.
+     *
+     * @return compression method
+     */
+    public int getMethod() {
+        return method;
+    }
+
+    /**
+     * Sets the compression method of this entry.
+     *
+     * @param method compression method
+     */
+    public void setMethod(int method) {
+        if (method < 0) {
+            throw new IllegalArgumentException(
+                    "ZIP compression method can not be negative: " + method);
+        }
+        this.method = method;
+    }
+
+    /**
      * Retrieves the internal file attributes.
      *
      * @return the internal file attributes

Modified: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java?rev=890088&r1=890087&r2=890088&view=diff
==============================================================================
--- commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java (original)
+++ commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java Sun Dec 13 18:31:55 2009
@@ -199,6 +199,12 @@
         // avoid int overflow, check null buffer
         if (start <= buffer.length && length >= 0 && start >= 0
             && buffer.length - start >= length) {
+            if (!current.isSupportedCompressionMethod()) {
+                throw new IOException(
+                        "Unsupported compression method " + current.getMethod()
+                        + " in ZIP archive entry " + current.getName());
+            }
+
             if (current.getMethod() == ZipArchiveOutputStream.STORED) {
                 int csize = (int) current.getSize();
                 if (readBytesOfEntry >= csize) {
@@ -224,6 +230,7 @@
                 crc.update(buffer, start, toRead);
                 return toRead;
             }
+
             if (inf.needsInput()) {
                 fill();
                 if (lengthOfLastRead > 0) {

Modified: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java?rev=890088&r1=890087&r2=890088&view=diff
==============================================================================
--- commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java (original)
+++ commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java Sun Dec 13 18:31:55 2009
@@ -510,7 +510,11 @@
      * @throws IOException on error
      */
     public void write(byte[] b, int offset, int length) throws IOException {
-        if (entry.getMethod() == DEFLATED) {
+        if (!entry.isSupportedCompressionMethod()) {
+            throw new IOException(
+                    "Unsupported compression method " + entry.getMethod()
+                    + " in ZIP archive entry " + entry.getName());
+        } else if (entry.getMethod() == DEFLATED) {
             if (length > 0) {
                 if (!def.finished()) {
                     if (length <= DEFLATER_BLOCK_SIZE) {

Modified: commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/ZipTestCase.java
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/ZipTestCase.java?rev=890088&r1=890087&r2=890088&view=diff
==============================================================================
--- commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/ZipTestCase.java (original)
+++ commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/ZipTestCase.java Sun Dec 13 18:31:55 2009
@@ -21,6 +21,7 @@
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
+import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.ArrayList;
@@ -112,7 +113,22 @@
         out.close();
         in.close();
     }
-    
+
+    /**
+     * Test case for
+     * <a href="https://issues.apache.org/jira/browse/COMPRESS-93"
+     * >COMPRESS-93</a>.
+     */
+    public void testSupportedCompressionMethod() throws IOException {
+        ZipFile bla = new ZipFile(getFile("bla.zip"));
+        assertTrue(bla.getEntry("test1.xml").isSupportedCompressionMethod());
+        bla.close();
+
+        ZipFile moby = new ZipFile(getFile("moby.zip"));
+        assertFalse(moby.getEntry("README").isSupportedCompressionMethod());
+        moby.close();
+    }
+
     /**
      * Checks if all entries from a nested archive can be read.
      * The archive: OSX_ArchiveWithNestedArchive.zip contains:

Modified: commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipArchiveEntryTest.java
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipArchiveEntryTest.java?rev=890088&r1=890087&r2=890088&view=diff
==============================================================================
--- commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipArchiveEntryTest.java (original)
+++ commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipArchiveEntryTest.java Sun Dec 13 18:31:55 2009
@@ -195,4 +195,28 @@
         assertEquals(0x11, ze.getExternalAttributes()  & 0xFFFF);
     }
 
+    /**
+     * Test case for
+     * <a href="https://issues.apache.org/jira/browse/COMPRESS-93"
+     * >COMPRESS-93</a>.
+     */
+    public void testCompressionMethod() {
+        ZipArchiveEntry entry = new ZipArchiveEntry("foo");
+        assertEquals(-1, entry.getMethod());
+        assertFalse(entry.isSupportedCompressionMethod());
+
+        entry.setMethod(ZipArchiveEntry.STORED);
+        assertEquals(ZipArchiveEntry.STORED, entry.getMethod());
+        assertTrue(entry.isSupportedCompressionMethod());
+
+        entry.setMethod(ZipArchiveEntry.DEFLATED);
+        assertEquals(ZipArchiveEntry.DEFLATED, entry.getMethod());
+        assertTrue(entry.isSupportedCompressionMethod());
+
+        // Test the unsupported "imploded" compression method (6)
+        entry.setMethod(6);
+        assertEquals(6, entry.getMethod());
+        assertFalse(entry.isSupportedCompressionMethod());
+    }
+
 }

Added: commons/proper/compress/trunk/src/test/resources/moby.zip
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/test/resources/moby.zip?rev=890088&view=auto
==============================================================================
Binary file - no diff available.

Propchange: commons/proper/compress/trunk/src/test/resources/moby.zip
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream