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 2019/08/28 15:46:52 UTC

[commons-compress] branch master updated: COMPRESS-492 eliminate a bunch of potential NPEs in SevenZFile

This is an automated email from the ASF dual-hosted git repository.

bodewig pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-compress.git


The following commit(s) were added to refs/heads/master by this push:
     new 277d6a0  COMPRESS-492 eliminate a bunch of potential NPEs in SevenZFile
277d6a0 is described below

commit 277d6a0c2820548fd97748ec6aff92ceceb1fd35
Author: Stefan Bodewig <bo...@apache.org>
AuthorDate: Wed Aug 28 17:46:06 2019 +0200

    COMPRESS-492 eliminate a bunch of potential NPEs in SevenZFile
---
 src/changes/changes.xml                            |   5 +++++
 .../commons/compress/archivers/sevenz/Archive.java |   6 ++---
 .../compress/archivers/sevenz/SevenZFile.java      |   6 +++++
 .../compress/archivers/sevenz/SevenZFileTest.java  |  25 +++++++++++++++++++++
 src/test/resources/COMPRESS-492.7z                 | Bin 0 -> 39 bytes
 5 files changed, 39 insertions(+), 3 deletions(-)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 5ed50ff..5a3cc09 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -50,6 +50,11 @@ The <action> type attribute can be add,update,fix,remove.
       <action type="update" date="2019-08-27">
         Update tests from org.apache.felix:org.apache.felix.framework 6.0.2 to 6.0.3.
       </action>
+      <action issue="COMPRESS-492" type="fix" date="2019-08-28">
+        SevenZFile could throw NullPointerException rather than
+        IOException for certain archives. In addition it now handles
+        certain empty archives more gracefully.
+      </action>
     </release>
     <release version="1.19" date="2019-08-27"
              description="Release 1.19
diff --git a/src/main/java/org/apache/commons/compress/archivers/sevenz/Archive.java b/src/main/java/org/apache/commons/compress/archivers/sevenz/Archive.java
index dd1c75a..00ca8b4 100644
--- a/src/main/java/org/apache/commons/compress/archivers/sevenz/Archive.java
+++ b/src/main/java/org/apache/commons/compress/archivers/sevenz/Archive.java
@@ -23,17 +23,17 @@ class Archive {
     /// Offset from beginning of file + SIGNATURE_HEADER_SIZE to packed streams.
     long packPos;
     /// Size of each packed stream.
-    long[] packSizes;
+    long[] packSizes = new long[0];
     /// Whether each particular packed streams has a CRC.
     BitSet packCrcsDefined;
     /// CRCs for each packed stream, valid only if that packed stream has one.
     long[] packCrcs;
     /// Properties of solid compression blocks.
-    Folder[] folders;
+    Folder[] folders = new Folder[0];
     /// Temporary properties for non-empty files (subsumed into the files array later).
     SubStreamsInfo subStreamsInfo;
     /// The files and directories in the archive.
-    SevenZArchiveEntry[] files;
+    SevenZArchiveEntry[] files = new SevenZArchiveEntry[0];
     /// Mapping between folders, files and streams.
     StreamMap streamMap;
 
diff --git a/src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZFile.java b/src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZFile.java
index ac148e5..7a02d78 100644
--- a/src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZFile.java
+++ b/src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZFile.java
@@ -1002,6 +1002,9 @@ public class SevenZFile implements Closeable {
         for (int i = 0; i < files.length; i++) {
             files[i].setHasStream(isEmptyStream == null || !isEmptyStream.get(i));
             if (files[i].hasStream()) {
+                if (archive.subStreamsInfo == null) {
+                    throw new IOException("Archive contains file with streams but no subStreamsInfo");
+                }
                 files[i].setDirectory(false);
                 files[i].setAntiItem(false);
                 files[i].setHasCrc(archive.subStreamsInfo.hasCrc.get(nonEmptyFileCounter));
@@ -1074,6 +1077,9 @@ public class SevenZFile implements Closeable {
     }
 
     private void buildDecodingStream() throws IOException {
+        if (archive.streamMap == null) {
+            throw new IOException("Archive doesn't contain stream information to read entries");
+        }
         final int folderIndex = archive.streamMap.fileFolderIndex[currentEntryIndex];
         if (folderIndex < 0) {
             deferredBlockStreams.clear();
diff --git a/src/test/java/org/apache/commons/compress/archivers/sevenz/SevenZFileTest.java b/src/test/java/org/apache/commons/compress/archivers/sevenz/SevenZFileTest.java
index c996935..db4fe1d 100644
--- a/src/test/java/org/apache/commons/compress/archivers/sevenz/SevenZFileTest.java
+++ b/src/test/java/org/apache/commons/compress/archivers/sevenz/SevenZFileTest.java
@@ -370,6 +370,31 @@ public class SevenZFileTest extends AbstractTestCase {
         }
     }
 
+    /**
+     * @see https://issues.apache.org/jira/browse/COMPRESS-492
+     */
+    @Test
+    public void handlesEmptyArchiveWithFilesInfo() throws Exception {
+        File f = new File(dir, "empty.7z");
+        try (SevenZOutputFile s = new SevenZOutputFile(f)) {
+        }
+        try (SevenZFile z = new SevenZFile(f)) {
+            assertFalse(z.getEntries().iterator().hasNext());
+            assertNull(z.getNextEntry());
+        }
+    }
+
+    /**
+     * @see https://issues.apache.org/jira/browse/COMPRESS-492
+     */
+    @Test
+    public void handlesEmptyArchiveWithoutFilesInfo() throws Exception {
+        try (SevenZFile z = new SevenZFile(getFile("COMPRESS-492.7z"))) {
+            assertFalse(z.getEntries().iterator().hasNext());
+            assertNull(z.getNextEntry());
+        }
+    }
+
     private void test7zUnarchive(final File f, final SevenZMethod m, final byte[] password) throws Exception {
         try (SevenZFile sevenZFile = new SevenZFile(f, password)) {
             test7zUnarchive(sevenZFile, m);
diff --git a/src/test/resources/COMPRESS-492.7z b/src/test/resources/COMPRESS-492.7z
new file mode 100644
index 0000000..53edfbc
Binary files /dev/null and b/src/test/resources/COMPRESS-492.7z differ