COMPRESS-510 : fix multiple retrievals of first entry of 7z
Multiple retrievals of InputStream for same SevenZFile entry fails
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 5247a15..90804e8 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -60,6 +60,11 @@
of 7z.
Github Pull Request #95.
</action>
+ <action issue="COMPRESS-510" type="fix" date="2020-04-18">
+ Fix bugs in random access of 7z. Exceptions are thrown
+ when reading the first entry multiable times by random
+ access.
+ </action>
</release>
<release version="1.20" date="2020-02-08"
description="Release 1.20">
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 2a1d7f9..04a01e8 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
@@ -1179,8 +1179,9 @@
// previous stream has to be fully decoded before we can start reading
// but don't do it eagerly -- if the user skips over the entire folder nothing
// is effectively decompressed.
-
- file.setContentMethods(archive.files[entryIndex - 1].getContentMethods());
+ if (entryIndex > 0) {
+ file.setContentMethods(archive.files[entryIndex - 1].getContentMethods());
+ }
// if this is called in a random access, then the content methods of previous entry may be null
// the content methods should be set to methods of the first entry as it must not be null,
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 c47904b..68b478c 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
@@ -673,6 +673,17 @@
}
}
+ @Test
+ public void retrieveInputStreamForAllEntriesMultipleTimes() throws IOException {
+ try (SevenZFile sevenZFile = new SevenZFile(getFile("bla.7z"))) {
+ for (SevenZArchiveEntry entry : sevenZFile.getEntries()) {
+ byte[] firstRead = IOUtils.toByteArray(sevenZFile.getInputStream(entry));
+ byte[] secondRead = IOUtils.toByteArray(sevenZFile.getInputStream(entry));
+ assertArrayEquals(firstRead, secondRead);
+ }
+ }
+ }
+
private void test7zUnarchive(final File f, final SevenZMethod m, final byte[] password) throws Exception {
try (SevenZFile sevenZFile = new SevenZFile(f, password)) {
test7zUnarchive(sevenZFile, m);