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/20 19:30:20 UTC

[commons-compress] branch master updated: COMPRESS-478 allow 7z default name to override null file name

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 c937e01  COMPRESS-478 allow 7z default name to override null file name
c937e01 is described below

commit c937e01ae3ad2f258b5a2c94f2a03e8c8e740e7d
Author: Stefan Bodewig <bo...@apache.org>
AuthorDate: Tue Aug 20 21:28:47 2019 +0200

    COMPRESS-478 allow 7z default name to override null file name
---
 .../apache/commons/compress/archivers/Lister.java  |   4 +-
 .../compress/archivers/sevenz/SevenZFile.java      | 157 ++++++---------------
 .../archivers/sevenz/SevenZFileOptions.java        | 116 +++++++++++++++
 .../compress/archivers/sevenz/SevenZFileTest.java  |  44 +++++-
 src/test/resources/bla-nonames.7z                  | Bin 0 -> 556 bytes
 5 files changed, 208 insertions(+), 113 deletions(-)

diff --git a/src/main/java/org/apache/commons/compress/archivers/Lister.java b/src/main/java/org/apache/commons/compress/archivers/Lister.java
index 481cc30..dd404a5 100644
--- a/src/main/java/org/apache/commons/compress/archivers/Lister.java
+++ b/src/main/java/org/apache/commons/compress/archivers/Lister.java
@@ -89,7 +89,9 @@ public final class Lister {
             System.out.println("Created " + z.toString());
             ArchiveEntry ae;
             while ((ae = z.getNextEntry()) != null) {
-                System.out.println(ae.getName());
+                String name = ae.getName() == null ? z.getDefaultName() + " (entry name was null)"
+                    : ae.getName();
+                System.out.println(name);
             }
         }
     }
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 00d2fde..ac148e5 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
@@ -92,7 +92,7 @@ public class SevenZFile implements Closeable {
     private int currentFolderIndex = -1;
     private InputStream currentFolderInputStream = null;
     private byte[] password;
-    private int maxMemoryLimitInKb;
+    private final SevenZFileOptions options;
 
     private long compressedBytesReadFromCurrentEntry;
     private long uncompressedBytesReadFromCurrentEntry;
@@ -113,22 +113,21 @@ public class SevenZFile implements Closeable {
      * @since 1.17
      */
     public SevenZFile(final File fileName, final char[] password) throws IOException {
-        this(fileName, password, Integer.MAX_VALUE);
+        this(fileName, password, SevenZFileOptions.DEFAULT);
     }
 
     /**
-     * Reads a file as 7z archive with memory limitation
+     * Reads a file as 7z archive with additional options.
      *
      * @param fileName the file to read
      * @param password optional password if the archive is encrypted
-     * @param maxMemoryLimitInKb limit of the maximum amount of memory to use for extraction. Not all codecs will honor
-     *                           this setting. Currently only lzma and lzma2 are supported.
-     * @throws IOException if reading the archive fails or the memory limit is too small
+     * @param options the options to apply
+     * @throws IOException if reading the archive fails or the memory limit (if set) is too small
      * @since 1.19
      */
-    public SevenZFile(final File fileName, final char[] password, final int maxMemoryLimitInKb) throws IOException {
+    public SevenZFile(final File fileName, final char[] password, SevenZFileOptions options) throws IOException {
         this(Files.newByteChannel(fileName.toPath(), EnumSet.of(StandardOpenOption.READ)),
-                fileName.getAbsolutePath(), utf16Decode(password), true, maxMemoryLimitInKb);
+                fileName.getAbsolutePath(), utf16Decode(password), true, options);
     }
 
     /**
@@ -142,25 +141,8 @@ public class SevenZFile implements Closeable {
      * @deprecated use the char[]-arg version for the password instead
      */
     public SevenZFile(final File fileName, final byte[] password) throws IOException {
-        this(fileName, password, Integer.MAX_VALUE);
-    }
-
-    /**
-     * Reads a file as 7z archive with memory limitation
-     *
-     * @param fileName the file to read
-     * @param password optional password if the archive is encrypted -
-     * the byte array is supposed to be the UTF16-LE encoded
-     * representation of the password.
-     * @param maxMemoryLimitInKb limit of the maximum amount of memory to use for extraction. Not all codecs will honor
-     *                           this setting. Currently only lzma and lzma2 are supported.
-     * @throws IOException if reading the archive fails or the memory limit is too small
-     * @deprecated use the char[]-arg version for the password instead
-     * @since 1.19
-     */
-    public SevenZFile(final File fileName, final byte[] password, final int maxMemoryLimitInKb) throws IOException {
-        this(Files.newByteChannel(fileName.toPath(), EnumSet.of(StandardOpenOption.READ)), fileName.getAbsolutePath(),
-                password, true, maxMemoryLimitInKb);
+        this(Files.newByteChannel(fileName.toPath(), EnumSet.of(StandardOpenOption.READ)),
+                fileName.getAbsolutePath(), password, true, SevenZFileOptions.DEFAULT);
     }
 
     /**
@@ -175,24 +157,23 @@ public class SevenZFile implements Closeable {
      * @since 1.13
      */
     public SevenZFile(final SeekableByteChannel channel) throws IOException {
-        this(channel, Integer.MAX_VALUE);
+        this(channel, SevenZFileOptions.DEFAULT);
     }
 
     /**
-     * Reads a SeekableByteChannel as 7z archive with memory limitation
+     * Reads a SeekableByteChannel as 7z archive with addtional options.
      *
      * <p>{@link
      * org.apache.commons.compress.utils.SeekableInMemoryByteChannel}
      * allows you to read from an in-memory archive.</p>
      *
      * @param channel the channel to read
-     * @param maxMemoryLimitInKb limit of the maximum amount of memory to use for extraction. Not all codecs will honor
-     *                           this setting. Currently only lzma and lzma2 are supported.
-     * @throws IOException if reading the archive fails or the memory limit is too small
+     * @param options the options to apply
+     * @throws IOException if reading the archive fails or the memory limit (if set) is too small
      * @since 1.19
      */
-    public SevenZFile(final SeekableByteChannel channel, final int maxMemoryLimitInKb) throws IOException {
-        this(channel, DEFAULT_FILE_NAME, (char[]) null, maxMemoryLimitInKb);
+    public SevenZFile(final SeekableByteChannel channel, SevenZFileOptions options) throws IOException {
+        this(channel, DEFAULT_FILE_NAME, (char[]) null, options);
     }
 
     /**
@@ -209,11 +190,11 @@ public class SevenZFile implements Closeable {
      */
     public SevenZFile(final SeekableByteChannel channel,
                       final char[] password) throws IOException {
-        this(channel, password, Integer.MAX_VALUE);
+        this(channel, password, SevenZFileOptions.DEFAULT);
     }
 
     /**
-     * Reads a SeekableByteChannel as 7z archive with memory limitation
+     * Reads a SeekableByteChannel as 7z archive with additional options.
      *
      * <p>{@link
      * org.apache.commons.compress.utils.SeekableInMemoryByteChannel}
@@ -221,14 +202,13 @@ public class SevenZFile implements Closeable {
      *
      * @param channel the channel to read
      * @param password optional password if the archive is encrypted
-     * @param maxMemoryLimitInKb limit of the maximum amount of memory to use for extraction. Not all codecs will honor
-     *                           this setting. Currently only lzma and lzma2 are supported.
-     * @throws IOException if reading the archive fails or the memory limit is too small
+     * @param options the options to apply
+     * @throws IOException if reading the archive fails or the memory limit (if set) is too small
      * @since 1.19
      */
-    public SevenZFile(final SeekableByteChannel channel, final char[] password, final int maxMemoryLimitInKb)
+    public SevenZFile(final SeekableByteChannel channel, final char[] password, final SevenZFileOptions options)
             throws IOException {
-        this(channel, DEFAULT_FILE_NAME, utf16Decode(password), maxMemoryLimitInKb);
+        this(channel, DEFAULT_FILE_NAME, password, options);
     }
 
     /**
@@ -246,11 +226,11 @@ public class SevenZFile implements Closeable {
      */
     public SevenZFile(final SeekableByteChannel channel, String fileName,
                       final char[] password) throws IOException {
-        this(channel, fileName, password, Integer.MAX_VALUE);
+        this(channel, fileName, password, SevenZFileOptions.DEFAULT);
     }
 
     /**
-     * Reads a SeekableByteChannel as 7z archive with memory limitation
+     * Reads a SeekableByteChannel as 7z archive with addtional options.
      *
      * <p>{@link
      * org.apache.commons.compress.utils.SeekableInMemoryByteChannel}
@@ -259,14 +239,13 @@ public class SevenZFile implements Closeable {
      * @param channel the channel to read
      * @param fileName name of the archive - only used for error reporting
      * @param password optional password if the archive is encrypted
-     * @param maxMemoryLimitInKb limit of the maximum amount of memory to use for extraction. Not all codecs will honor
-     *                           this setting. Currently only lzma and lzma2 are supported.
-     * @throws IOException if reading the archive fails or the memory limit is too small
+     * @param options the options to apply
+     * @throws IOException if reading the archive fails or the memory limit (if set) is too small
      * @since 1.19
      */
     public SevenZFile(final SeekableByteChannel channel, String fileName, final char[] password,
-            final int maxMemoryLimitInKb) throws IOException {
-        this(channel, fileName, utf16Decode(password), false, maxMemoryLimitInKb);
+            final SevenZFileOptions options) throws IOException {
+        this(channel, fileName, utf16Decode(password), false, options);
     }
 
     /**
@@ -283,11 +262,11 @@ public class SevenZFile implements Closeable {
      */
     public SevenZFile(final SeekableByteChannel channel, String fileName)
         throws IOException {
-        this(channel, fileName, Integer.MAX_VALUE);
+        this(channel, fileName, SevenZFileOptions.DEFAULT);
     }
 
     /**
-     * Reads a SeekableByteChannel as 7z archive with memory limitation
+     * Reads a SeekableByteChannel as 7z archive with additional options.
      *
      * <p>{@link
      * org.apache.commons.compress.utils.SeekableInMemoryByteChannel}
@@ -295,14 +274,13 @@ public class SevenZFile implements Closeable {
      *
      * @param channel the channel to read
      * @param fileName name of the archive - only used for error reporting
-     * @param maxMemoryLimitInKb limit of the maximum amount of memory to use for extraction. Not all codecs will honor
-     *                           this setting. Currently only lzma and lzma2 are supported.
-     * @throws IOException if reading the archive fails or the memory limit is too small
+     * @param options the options to apply
+     * @throws IOException if reading the archive fails or the memory limit (if set) is too small
      * @since 1.19
      */
-    public SevenZFile(final SeekableByteChannel channel, String fileName, final int maxMemoryLimitInKb)
+    public SevenZFile(final SeekableByteChannel channel, String fileName, final SevenZFileOptions options)
             throws IOException {
-        this(channel, fileName, null, false, maxMemoryLimitInKb);
+        this(channel, fileName, null, false, options);
     }
 
     /**
@@ -326,28 +304,6 @@ public class SevenZFile implements Closeable {
     }
 
     /**
-     * Reads a SeekableByteChannel as 7z archive with memory limitation
-     *
-     * <p>{@link
-     * org.apache.commons.compress.utils.SeekableInMemoryByteChannel}
-     * allows you to read from an in-memory archive.</p>
-     *
-     * @param channel the channel to read
-     * @param password optional password if the archive is encrypted -
-     * the byte array is supposed to be the UTF16-LE encoded
-     * representation of the password.
-     * @param maxMemoryLimitInKb limit of the maximum amount of memory to use for extraction. Not all codecs will honor
-     *                           this setting. Currently only lzma and lzma2 are supported.
-     * @throws IOException if reading the archive fails or the memory limit is too small
-     * @since 1.19
-     * @deprecated use the char[]-arg version for the password instead
-     */
-    public SevenZFile(final SeekableByteChannel channel, final byte[] password, final int maxMemoryLimitInKb)
-            throws IOException {
-        this(channel, DEFAULT_FILE_NAME, password, maxMemoryLimitInKb);
-    }
-
-    /**
      * Reads a SeekableByteChannel as 7z archive
      *
      * <p>{@link
@@ -365,38 +321,15 @@ public class SevenZFile implements Closeable {
      */
     public SevenZFile(final SeekableByteChannel channel, String fileName,
                       final byte[] password) throws IOException {
-        this(channel, fileName, password, false, Integer.MAX_VALUE);
-    }
-
-    /**
-     * Reads a SeekableByteChannel as 7z archive with memory limitation
-     *
-     * <p>{@link
-     * org.apache.commons.compress.utils.SeekableInMemoryByteChannel}
-     * allows you to read from an in-memory archive.</p>
-     *
-     * @param channel the channel to read
-     * @param fileName name of the archive - only used for error reporting
-     * @param password optional password if the archive is encrypted -
-     * the byte array is supposed to be the UTF16-LE encoded
-     * representation of the password.
-     * @param maxMemoryLimitInKb limit of the maximum amount of memory to use for extraction. Not all codecs will honor
-     *                           this setting. Currently only lzma and lzma2 are supported.
-     * @throws IOException if reading the archive fails or the memory limit is too small
-     * @since 1.19
-     * @deprecated use the char[]-arg version for the password instead
-     */
-    public SevenZFile(final SeekableByteChannel channel, String fileName, final byte[] password,
-            final int maxMemoryLimitInKb) throws IOException {
-        this(channel, fileName, password, false, maxMemoryLimitInKb);
+        this(channel, fileName, password, false, SevenZFileOptions.DEFAULT);
     }
 
     private SevenZFile(final SeekableByteChannel channel, String filename,
-                       final byte[] password, boolean closeOnError, final int maxMemoryLimitInKb) throws IOException {
+                       final byte[] password, boolean closeOnError, SevenZFileOptions options) throws IOException {
         boolean succeeded = false;
         this.channel = channel;
         this.fileName = filename;
-        this.maxMemoryLimitInKb = maxMemoryLimitInKb;
+        this.options = options;
         try {
             archive = readHeaders(password);
             if (password != null) {
@@ -419,20 +352,19 @@ public class SevenZFile implements Closeable {
      * @throws IOException if reading the archive fails
      */
     public SevenZFile(final File fileName) throws IOException {
-        this(fileName, Integer.MAX_VALUE);
+        this(fileName, SevenZFileOptions.DEFAULT);
     }
 
     /**
      * Reads a file as unencrypted 7z archive
      *
      * @param fileName the file to read
-     * @param maxMemoryLimitInKb limit of the maximum amount of memory to use for extraction. Not all codecs will honor
-     *                           this setting. Currently only lzma and lzma2 are supported.
-     * @throws IOException if reading the archive fails or the memory limit is too small
+     * @param options the options to apply
+     * @throws IOException if reading the archive fails or the memory limit (if set) is too small
      * @since 1.19
      */
-    public SevenZFile(final File fileName, final int maxMemoryLimitInKb) throws IOException {
-        this(fileName, (char[]) null, maxMemoryLimitInKb);
+    public SevenZFile(final File fileName, final SevenZFileOptions options) throws IOException {
+        this(fileName, (char[]) null, options);
     }
 
     /**
@@ -467,6 +399,9 @@ public class SevenZFile implements Closeable {
         }
         ++currentEntryIndex;
         final SevenZArchiveEntry entry = archive.files[currentEntryIndex];
+        if (entry.getName() == null && options.getUseDefaultNameForUnnamedEntries()) {
+            entry.setName(getDefaultName());
+        }
         buildDecodingStream();
         uncompressedBytesReadFromCurrentEntry = compressedBytesReadFromCurrentEntry = 0;
         return entry;
@@ -606,7 +541,7 @@ public class SevenZFile implements Closeable {
                 throw new IOException("Multi input/output stream coders are not yet supported");
             }
             inputStreamStack = Coders.addDecoder(fileName, inputStreamStack, //NOSONAR
-                    folder.getUnpackSizeForCoder(coder), coder, password, maxMemoryLimitInKb);
+                    folder.getUnpackSizeForCoder(coder), coder, password, options.getMaxMemoryLimitInKb());
         }
         if (folder.hasCrc) {
             inputStreamStack = new CRC32VerifyingInputStream(inputStreamStack,
@@ -1216,7 +1151,7 @@ public class SevenZFile implements Closeable {
             }
             final SevenZMethod method = SevenZMethod.byId(coder.decompressionMethodId);
             inputStreamStack = Coders.addDecoder(fileName, inputStreamStack,
-                    folder.getUnpackSizeForCoder(coder), coder, password, maxMemoryLimitInKb);
+                    folder.getUnpackSizeForCoder(coder), coder, password, options.getMaxMemoryLimitInKb());
             methods.addFirst(new SevenZMethodConfiguration(method,
                      Coders.findByMethod(method).getOptionsFromCoder(coder, inputStreamStack)));
         }
diff --git a/src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZFileOptions.java b/src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZFileOptions.java
new file mode 100644
index 0000000..1ce913f
--- /dev/null
+++ b/src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZFileOptions.java
@@ -0,0 +1,116 @@
+/*
+ *  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.sevenz;
+
+/**
+ * Collects options for reading 7z archives.
+ *
+ * @since 1.19
+ * @Immutable
+ */
+public class SevenZFileOptions {
+    private static final int DEFAUL_MEMORY_LIMIT_IN_KB = Integer.MAX_VALUE;
+    private static final boolean DEFAULT_USE_DEFAULTNAME_FOR_UNNAMED_ENTRIES= false;
+
+    private final int maxMemoryLimitInKb;
+    private final boolean useDefaultNameForUnnamedEntries;
+
+    private SevenZFileOptions(int maxMemoryLimitInKb, boolean useDefaultNameForUnnamedEntries) {
+        this.maxMemoryLimitInKb = maxMemoryLimitInKb;
+        this.useDefaultNameForUnnamedEntries = useDefaultNameForUnnamedEntries;
+    }
+
+    /**
+     * The default options.
+     *
+     * <ul>
+     *   <li>no memory limit</li>
+     *   <li>don't modifiy the name of unnamed entries</li>
+     * </ul>
+     */
+    public static SevenZFileOptions DEFAULT = new SevenZFileOptions(DEFAUL_MEMORY_LIMIT_IN_KB,
+        DEFAULT_USE_DEFAULTNAME_FOR_UNNAMED_ENTRIES);
+
+    /**
+     * Obtains a builder for SevenZFileOptions.
+     */
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    /**
+     * Gets the maximum amount of memory to use for extraction. Not
+     * all codecs will honor this setting. Currently only lzma and
+     * lzma2 are supported.
+     */
+    public int getMaxMemoryLimitInKb() {
+        return maxMemoryLimitInKb;
+    }
+
+    /**
+     * Gets whether entries without a name should get their names set
+     * to the archive's default file name.
+     */
+    public boolean getUseDefaultNameForUnnamedEntries() {
+        return useDefaultNameForUnnamedEntries;
+    }
+
+    /**
+     * Mutable builder for the immutable {@link SevenZFileOptions}.
+     *
+     * @since 1.19
+     */
+    public static class Builder {
+        private int maxMemoryLimitInKb = DEFAUL_MEMORY_LIMIT_IN_KB;
+        private boolean useDefaultNameForUnnamedEntries = DEFAULT_USE_DEFAULTNAME_FOR_UNNAMED_ENTRIES;
+        /**
+         * Sets the maximum amount of memory to use for
+         * extraction. Not all codecs will honor this
+         * setting. Currently only lzma and lzma2 are supported.
+         *
+         * @param maxMemoryLimitInKb limit of the maximum amount of memory to use
+         * @return the reconfigured builder
+         */
+        public Builder withMaxMemoryLimitInKb(int maxMemoryLimitInKb) {
+            this.maxMemoryLimitInKb = maxMemoryLimitInKb;
+            return this;
+        }
+
+        /**
+         * Sets whether entries without a name should get their names
+         * set to the archive's default file name.
+         *
+         * @param useDefaultNameForUnnamedEntries if true the name of
+         * unnamed entries will be set to the archive's default name
+         * @return the reconfigured builder
+         */
+        public Builder withUseDefaultNameForUnnamedEntries(boolean useDefaultNameForUnnamedEntries) {
+            this.useDefaultNameForUnnamedEntries = useDefaultNameForUnnamedEntries;
+            return this;
+        }
+
+        /**
+         * Create the {@link SevenZFileOptions}.
+         *
+         * @return configured {@link SevenZFileOptions}.
+         */
+        public SevenZFileOptions build() {
+            return new SevenZFileOptions(maxMemoryLimitInKb, useDefaultNameForUnnamedEntries);
+        }
+    }
+}
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 0982259..c996935 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
@@ -299,7 +299,8 @@ public class SevenZFileTest extends AbstractTestCase {
 
     @Test(expected = MemoryLimitException.class)
     public void limitExtractionMemory() throws IOException {
-        try (SevenZFile sevenZFile = new SevenZFile(getFile("bla.7z"), 1)) {
+        try (SevenZFile sevenZFile = new SevenZFile(getFile("bla.7z"),
+            SevenZFileOptions.builder().withMaxMemoryLimitInKb(1).build())) {
             // Do nothing. Exception should be thrown
         }
     }
@@ -328,6 +329,47 @@ public class SevenZFileTest extends AbstractTestCase {
         }
     }
 
+    @Test
+    public void noNameMeansNoNameByDefault() throws Exception {
+        try (SevenZFile sevenZFile = new SevenZFile(getFile("bla-nonames.7z"))) {
+            SevenZArchiveEntry ae = sevenZFile.getNextEntry();
+            assertNotNull(ae);
+            assertNull(ae.getName());
+            ae = sevenZFile.getNextEntry();
+            assertNotNull(ae);
+            assertNull(ae.getName());
+            assertNull(sevenZFile.getNextEntry());
+        }
+    }
+
+    @Test
+    public void noNameCanBeReplacedByDefaultName() throws Exception {
+        try (SevenZFile sevenZFile = new SevenZFile(getFile("bla-nonames.7z"),
+            SevenZFileOptions.builder().withUseDefaultNameForUnnamedEntries(true).build())) {
+            SevenZArchiveEntry ae = sevenZFile.getNextEntry();
+            assertNotNull(ae);
+            assertEquals("bla-nonames", ae.getName());
+            ae = sevenZFile.getNextEntry();
+            assertNotNull(ae);
+            assertEquals("bla-nonames", ae.getName());
+            assertNull(sevenZFile.getNextEntry());
+        }
+    }
+
+    @Test
+    public void givenNameWinsOverDefaultName() throws Exception {
+        try (SevenZFile sevenZFile = new SevenZFile(getFile("bla.7z"),
+            SevenZFileOptions.builder().withUseDefaultNameForUnnamedEntries(true).build())) {
+            SevenZArchiveEntry ae = sevenZFile.getNextEntry();
+            assertNotNull(ae);
+            assertEquals("test1.xml", ae.getName());
+            ae = sevenZFile.getNextEntry();
+            assertNotNull(ae);
+            assertEquals("test2.xml", ae.getName());
+            assertNull(sevenZFile.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/bla-nonames.7z b/src/test/resources/bla-nonames.7z
new file mode 100644
index 0000000..904a897
Binary files /dev/null and b/src/test/resources/bla-nonames.7z differ