You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by bo...@apache.org on 2012/12/28 07:53:21 UTC

svn commit: r1426417 - in /commons/proper/compress/trunk/src: changes/changes.xml main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java test/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStreamTest.java

Author: bodewig
Date: Fri Dec 28 06:53:21 2012
New Revision: 1426417

URL: http://svn.apache.org/viewvc?rev=1426417&view=rev
Log:
COMPRESS-189 Inflater may return 0 if it needs more input, we don't handle this case properly

Modified:
    commons/proper/compress/trunk/src/changes/changes.xml
    commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java
    commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStreamTest.java

Modified: commons/proper/compress/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/changes/changes.xml?rev=1426417&r1=1426416&r2=1426417&view=diff
==============================================================================
--- commons/proper/compress/trunk/src/changes/changes.xml (original)
+++ commons/proper/compress/trunk/src/changes/changes.xml Fri Dec 28 06:53:21 2012
@@ -78,6 +78,10 @@ The <action> type attribute can be add,u
         Writing TAR PAX headers failed if the generated entry name
         ended with a "/".
       </action>
+      <action type="fix" date="2012-12-28" issue="COMPRESS-189">
+        ZipArchiveInputStream sometimes failed to provide input to the
+        Inflater when it needed it, leading to reads returning 0.
+      </action>
     </release>
     <release version="1.4.1" date="2012-05-23"
              description="Release 1.4.1">

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=1426417&r1=1426416&r2=1426417&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 Fri Dec 28 06:53:21 2012
@@ -380,20 +380,9 @@ public class ZipArchiveInputStream exten
      */
     private int readDeflated(byte[] buffer, int start, int length)
         throws IOException {
-        if (inf.needsInput()) {
-            fill();
-            if (buf.lengthOfLastRead > 0) {
-                current.bytesReadFromStream += buf.lengthOfLastRead;
-            }
-        }
-        int read = 0;
-        try {
-            read = inf.inflate(buffer, start, length);
-        } catch (DataFormatException e) {
-            throw new ZipException(e.getMessage());
-        }
+        int read = readFromInflater(buffer, start, length);
         if (read == 0) {
-            if (inf.finished()) {
+            if (inf.finished() || inf.needsDictionary()) {
                 return -1;
             } else if (buf.lengthOfLastRead == -1) {
                 throw new IOException("Truncated ZIP file");
@@ -403,6 +392,31 @@ public class ZipArchiveInputStream exten
         return read;
     }
 
+    /**
+     * Potentially reads more bytes to fill the inflater's buffer and
+     * reads from it.
+     */
+    private int readFromInflater(byte[] buffer, int start, int length)
+        throws IOException {
+        int read = 0;
+        do {
+            if (inf.needsInput()) {
+                fill();
+                if (buf.lengthOfLastRead > 0) {
+                    current.bytesReadFromStream += buf.lengthOfLastRead;
+                } else {
+                    break;
+                }
+            }
+            try {
+                read = inf.inflate(buffer, start, length);
+            } catch (DataFormatException e) {
+                throw new ZipException(e.getMessage());
+            }
+        } while (read == 0 && inf.needsInput());
+        return read;
+    }
+
     @Override
     public void close() throws IOException {
         if (!closed) {

Modified: commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStreamTest.java
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStreamTest.java?rev=1426417&r1=1426416&r2=1426417&view=diff
==============================================================================
--- commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStreamTest.java (original)
+++ commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStreamTest.java Fri Dec 28 06:53:21 2012
@@ -19,12 +19,15 @@
 package org.apache.commons.compress.archivers.zip;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
+import java.io.BufferedInputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.net.URI;
 import java.net.URL;
 
+import org.junit.Ignore;
 import org.junit.Test;
 
 public class ZipArchiveInputStreamTest {
@@ -49,4 +52,33 @@ public class ZipArchiveInputStreamTest {
         }
     }
 
-}
\ No newline at end of file
+    /**
+     * @see "https://issues.apache.org/jira/browse/COMPRESS-189"
+     */
+    @Test
+    @Ignore
+    public void properUseOfInflater() throws Exception {
+        URL zip = getClass().getResource("/COMPRESS-189.zip");
+        ZipFile zf = null;
+        ZipArchiveInputStream in = null;
+        try {
+            zf = new ZipFile(new File(new URI(zip.toString())));
+            ZipArchiveEntry zae = zf.getEntry("USD0558682-20080101.ZIP");
+            in = new ZipArchiveInputStream(new BufferedInputStream(zf.getInputStream(zae)));
+            ZipArchiveEntry innerEntry;
+            while ((innerEntry = in.getNextZipEntry()) != null) {
+                if (innerEntry.getName().endsWith("XML")) {
+                    assertTrue(0 < in.read());
+                }
+            }
+        } finally {
+            if (zf != null) {
+                zf.close();
+            }
+            if (in != null) {
+                in.close();
+            }
+        }
+    }
+
+}