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 <bode...@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