Author: bodewig
Date: Thu Aug 14 05:41:40 2014
New Revision: 1617883

URL: http://svn.apache.org/r1617883
Log:
COMPRESS-287 ignore unknown properties in 7z file headers

Modified:
    commons/proper/compress/trunk/src/changes/changes.xml
    
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZFile.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=1617883&r1=1617882&r2=1617883&view=diff
==============================================================================
--- commons/proper/compress/trunk/src/changes/changes.xml (original)
+++ commons/proper/compress/trunk/src/changes/changes.xml Thu Aug 14 05:41:40 
2014
@@ -48,6 +48,10 @@ The <action> type attribute can be add,u
               due-to="Matthias Stevens">
         Added support for DEFLATE streams without any gzip framing.
       </action>
+      <action type="fix" date="2014-08-14" issue="COMPRESS-287">
+        When reading 7z files unknown file properties and properties
+        of type kDummy are now ignored.
+      </action>
     </release>
 
     <release version="1.8.1" date="2014-05-14"

Modified: 
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZFile.java
URL: 
http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZFile.java?rev=1617883&r1=1617882&r2=1617883&view=diff
==============================================================================
--- 
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZFile.java
 (original)
+++ 
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZFile.java
 Thu Aug 14 05:41:40 2014
@@ -244,7 +244,7 @@ public class SevenZFile implements Close
         }
         
         if (nid != NID.kEnd) {
-            throw new IOException("Badly terminated header");
+            throw new IOException("Badly terminated header, found " + nid);
         }
     }
     
@@ -708,13 +708,21 @@ public class SevenZFile implements Close
                     throw new IOException("kStartPos is unsupported, please 
report");
                 }
                 case NID.kDummy: {
-                    throw new IOException("kDummy is unsupported, please 
report");
+                    // 7z 9.20 asserts the content is all zeros and ignores 
the property
+                    // Compress up to 1.8.1 would throw an exception, now we 
ignore it (see COMPRESS-287
+                    
+                    if (skipBytesFully(header, size) < size) {
+                        throw new IOException("Incomplete kDummy property");
+                    }
+                    break;
                 }
-                
+
                 default: {
-                    throw new IOException("Unknown property " + propertyType);
-                    // FIXME: Should actually:
-                    //header.skipBytes((int)size);
+                    // Compress up to 1.8.1 would throw an exception, now we 
ignore it (see COMPRESS-287
+                    if (skipBytesFully(header, size) < size) {
+                        throw new IOException("Incomplete property of type " + 
propertyType);
+                    }
+                    break;
                 }
             }
         }
@@ -944,4 +952,28 @@ public class SevenZFile implements Close
         }
         return true;
     }
+
+    private static long skipBytesFully(DataInput input, long bytesToSkip) 
throws IOException {
+        if (bytesToSkip < 1) {
+            return 0;
+        }
+        long skipped = 0;
+        while (bytesToSkip > Integer.MAX_VALUE) {
+            long skippedNow = skipBytesFully(input, Integer.MAX_VALUE);
+            if (skippedNow == 0) {
+                return skipped;
+            }
+            skipped += skippedNow;
+            bytesToSkip -= skippedNow;
+        }
+        while (bytesToSkip > 0) {
+            int skippedNow = input.skipBytes((int) bytesToSkip);
+            if (skippedNow == 0) {
+                return skipped;
+            }
+            skipped += skippedNow;
+            bytesToSkip -= skippedNow;
+        }
+        return skipped;
+    }
 }


Reply via email to