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 2009/10/30 06:29:17 UTC

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

Author: bodewig
Date: Fri Oct 30 05:29:17 2009
New Revision: 831204

URL: http://svn.apache.org/viewvc?rev=831204&view=rev
Log:
make ZipArchiveInputStream deal better with truncated archives.  Submitted by Antoni Mylka.  COMPRESS-87

Added:
    commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/Maven221MultiVolumeTest.java   (with props)
    commons/proper/compress/trunk/src/test/resources/apache-maven-2.2.1.zip.001   (with props)
Modified:
    commons/proper/compress/trunk/src/changes/changes.xml
    commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.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=831204&r1=831203&r2=831204&view=diff
==============================================================================
--- commons/proper/compress/trunk/src/changes/changes.xml (original)
+++ commons/proper/compress/trunk/src/changes/changes.xml Fri Oct 30 05:29:17 2009
@@ -23,6 +23,11 @@
   </properties>
   <body>
     <release version="1.1" date="as in SVN" description="Release 1.1">
+      <action type="fix" issue="COMPRESS-87" date="2009-10-30"
+              due-to="Antoni Mylka">
+        ZipArchiveInputStream could repeatedly return 0 on read() when
+        the archive was truncated.
+      </action>
       <action type="fix" issue="COMPRESS-86" date="2009-10-08">
         Tar archive entries holding the file name for names longer
         than 100 characters in GNU longfile mode didn't properly

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=831204&r1=831203&r2=831204&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 Oct 30 05:29:17 2009
@@ -236,8 +236,12 @@
             } catch (DataFormatException e) {
                 throw new ZipException(e.getMessage());
             }
-            if (read == 0 && inf.finished()) {
-                return -1;
+            if (read == 0) {
+                if (inf.finished()) {
+                    return -1;
+                } else if (lengthOfLastRead == -1) {
+                    throw new IOException("Truncated ZIP file");
+                }
             }
             crc.update(buffer, start, read);
             return read;

Added: commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/Maven221MultiVolumeTest.java
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/Maven221MultiVolumeTest.java?rev=831204&view=auto
==============================================================================
--- commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/Maven221MultiVolumeTest.java (added)
+++ commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/Maven221MultiVolumeTest.java Fri Oct 30 05:29:17 2009
@@ -0,0 +1,129 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.commons.compress.archivers.zip;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+
+import org.apache.commons.compress.archivers.ArchiveEntry;
+
+import junit.framework.TestCase;
+
+/**
+ * JUnit 3 testcase for a multi-volume zip file.
+ * 
+ * Some tools (like 7-zip) allow users to split a large archives into 'volumes'
+ * with a given size to fit them into multiple cds, usb drives, or emails with
+ * an attachment size limit. It's basically the same file split into chunks of
+ * exactly 65536 bytes length. Concatenating volumes yields exactly the original
+ * file. There is no mechanism in the ZIP algorithm to accommodate for this.
+ * Before commons-compress used to enter an infinite loop on the last entry for
+ * such a file. This test is intended to prove that this error doesn't occur
+ * anymore. All entries but the last one are returned correctly, the last entry
+ * yields an exception.
+ * 
+ */
+public class Maven221MultiVolumeTest extends TestCase {
+
+    private static final String [] ENTRIES = new String [] {
+	"apache-maven-2.2.1/",
+	"apache-maven-2.2.1/LICENSE.txt",
+	"apache-maven-2.2.1/NOTICE.txt",
+	"apache-maven-2.2.1/README.txt",
+	"apache-maven-2.2.1/bin/",
+	"apache-maven-2.2.1/bin/m2.conf",
+	"apache-maven-2.2.1/bin/mvn",
+	"apache-maven-2.2.1/bin/mvn.bat",
+	"apache-maven-2.2.1/bin/mvnDebug",
+	"apache-maven-2.2.1/bin/mvnDebug.bat",
+	"apache-maven-2.2.1/boot/",
+	"apache-maven-2.2.1/boot/classworlds-1.1.jar",
+	"apache-maven-2.2.1/conf/",
+	"apache-maven-2.2.1/conf/settings.xml",
+	"apache-maven-2.2.1/lib/"
+    };
+    
+    private static final String LAST_ENTRY_NAME = 
+	"apache-maven-2.2.1/lib/maven-2.2.1-uber.jar";
+    
+    public void testRead7ZipMultiVolumeArchiveForStream() throws IOException,
+	    URISyntaxException {
+	
+	URL zip = getClass().getResource("/apache-maven-2.2.1.zip.001");
+	FileInputStream archive = new FileInputStream(
+		new File(new URI(zip.toString())));
+	ZipArchiveInputStream zi = null;
+	try {
+	    zi = new ZipArchiveInputStream(archive,null,false);
+	    
+	    // these are the entries that are supposed to be processed
+	    // correctly without any problems
+	    for (int i = 0; i < ENTRIES.length; i++) {
+		assertEquals(ENTRIES[i], zi.getNextEntry().getName());
+	    }
+	    
+	    // this is the last entry that is truncated
+	    ArchiveEntry lastEntry = zi.getNextEntry();
+	    assertEquals(LAST_ENTRY_NAME, lastEntry.getName());
+	    byte [] buffer = new byte [4096];
+	    
+	    // before the fix, we'd get 0 bytes on this read and all
+	    // subsequent reads thus a client application might enter
+	    // an infinite loop after the fix, we should get an
+	    // exception
+	    try {
+                int read = 0;
+		while ((read = zi.read(buffer)) > 0) { }
+		fail("shouldn't be able to read from truncated entry");
+	    } catch (IOException e) {
+                assertEquals("Truncated ZIP file", e.getMessage());
+	    }
+	    
+	    // and now we get another entry, which should also yield
+	    // an exception
+	    try {
+		zi.getNextEntry();
+		fail("shouldn't be able to read another entry from truncated"
+                     + " file");
+	    } catch (IOException e) {
+		// this is to be expected
+	    }
+	} finally {
+	    if (zi != null) {
+		zi.close();
+	    }
+	}
+    }
+
+    public void testRead7ZipMultiVolumeArchiveForFile()
+        throws IOException, URISyntaxException {
+	URL zip = getClass().getResource("/apache-maven-2.2.1.zip.001");
+        File file = new File(new URI(zip.toString()));
+        try {
+            new ZipFile(file);
+            fail("Expected ZipFile to fail");
+        } catch (IOException ex) {
+            // expected
+        }
+    }
+}

Propchange: commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/Maven221MultiVolumeTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

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

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