]> source.dussan.org Git - poi.git/commitdiff
throw exception if xlsx contains duplicate file names
authorPJ Fanning <fanningpj@apache.org>
Mon, 1 Jul 2024 22:40:18 +0000 (22:40 +0000)
committerPJ Fanning <fanningpj@apache.org>
Mon, 1 Jul 2024 22:40:18 +0000 (22:40 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1918802 13f79535-47bb-0310-9956-ffa450edef68

poi-ooxml/src/main/java/org/apache/poi/ooxml/util/PackageHelper.java
poi-ooxml/src/main/java/org/apache/poi/openxml4j/opc/OPCPackage.java
poi-ooxml/src/main/java/org/apache/poi/openxml4j/util/ZipInputStreamZipEntrySource.java
poi-ooxml/src/main/java/org/apache/poi/openxml4j/util/ZipSecureFile.java
poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFWorkbook.java

index 75f4371c3167494610a713ea91bd802d670760bb..119289cfd4431b1628f562d8f261c3c3b757c1a0 100644 (file)
@@ -35,6 +35,7 @@ import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
 import org.apache.poi.openxml4j.opc.PackageRelationshipTypes;
 import org.apache.poi.openxml4j.opc.PackagingURIHelper;
 import org.apache.poi.openxml4j.opc.TargetMode;
+import org.apache.poi.openxml4j.opc.internal.InvalidZipException;
 import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.Removal;
 
@@ -62,8 +63,12 @@ public final class PackageHelper {
     public static OPCPackage open(InputStream stream, boolean closeStream) throws IOException {
         try {
             return OPCPackage.open(stream, closeStream);
-        } catch (InvalidFormatException e){
-            throw new POIXMLException(e);
+        } catch (InvalidFormatException e) {
+            final Throwable cause = e.getCause();
+            if (cause instanceof IOException) {
+                throw (IOException) cause;
+            }
+            throw new IOException(e);
         } finally {
             if (closeStream) {
                 stream.close();
index e15284806d7f951e50b66c96132546a6874107db..0b476b1b12b43a3e00d6ba7e7fb7814898d60060 100644 (file)
@@ -50,6 +50,7 @@ import org.apache.poi.openxml4j.exceptions.OpenXML4JRuntimeException;
 import org.apache.poi.openxml4j.exceptions.PartAlreadyExistsException;
 import org.apache.poi.openxml4j.opc.internal.ContentType;
 import org.apache.poi.openxml4j.opc.internal.ContentTypeManager;
+import org.apache.poi.openxml4j.opc.internal.InvalidZipException;
 import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart;
 import org.apache.poi.openxml4j.opc.internal.PartMarshaller;
 import org.apache.poi.openxml4j.opc.internal.PartUnmarshaller;
@@ -193,7 +194,7 @@ public abstract class OPCPackage implements RelationshipSource, Closeable {
    }
 
    /**
-    * Open an user provided {@link ZipEntrySource} with read-only permission.
+    * Open a user provided {@link ZipEntrySource} with read-only permission.
     * This method can be used to stream data into POI.
     * Opposed to other open variants, the data is read as-is, e.g. there aren't
     * any zip-bomb protection put in place.
@@ -202,8 +203,7 @@ public abstract class OPCPackage implements RelationshipSource, Closeable {
     * @return A Package object
     * @throws InvalidFormatException if a parsing error occur.
     */
-   public static OPCPackage open(ZipEntrySource zipEntry)
-   throws InvalidFormatException {
+   public static OPCPackage open(ZipEntrySource zipEntry) throws InvalidFormatException {
        OPCPackage pack = new ZipPackage(zipEntry, PackageAccess.READ);
        try {
            if (pack.partList == null) {
@@ -282,7 +282,12 @@ public abstract class OPCPackage implements RelationshipSource, Closeable {
            throw new IllegalArgumentException("file must not be a directory");
        }
 
-       OPCPackage pack = new ZipPackage(file, access); //NOSONAR
+       final OPCPackage pack;
+       try {
+           pack = new ZipPackage(file, access); //NOSONAR
+       } catch (InvalidOperationException e) {
+           throw new InvalidFormatException(e.getMessage(), e);
+       }
        try {
            if (pack.partList == null && access != PackageAccess.WRITE) {
                pack.getParts();
@@ -316,8 +321,12 @@ public abstract class OPCPackage implements RelationshipSource, Closeable {
      */
     public static OPCPackage open(InputStream in) throws InvalidFormatException,
             IOException {
-        OPCPackage pack = new ZipPackage(in, PackageAccess.READ_WRITE);
+        final OPCPackage pack;
         try {
+            pack = new ZipPackage(in, PackageAccess.READ_WRITE);
+        } catch (InvalidZipException e) {
+            throw new InvalidFormatException(e.getMessage(), e);
+        }        try {
             if (pack.partList == null) {
                 pack.getParts();
             }
@@ -348,7 +357,12 @@ public abstract class OPCPackage implements RelationshipSource, Closeable {
      */
     public static OPCPackage open(InputStream in, boolean closeStream) throws InvalidFormatException,
             IOException {
-        OPCPackage pack = new ZipPackage(in, PackageAccess.READ_WRITE, closeStream);
+        final OPCPackage pack;
+        try {
+            pack = new ZipPackage(in, PackageAccess.READ_WRITE, closeStream);
+        } catch (InvalidZipException e) {
+            throw new InvalidFormatException(e.getMessage(), e);
+        }
         try {
             if (pack.partList == null) {
                 pack.getParts();
index 5f9a057d4f75bada96f42b4fea34d8255708f0d2..676a9a3c0c4ec834d8072869da7d1d019c1881af 100644 (file)
@@ -21,9 +21,12 @@ import java.io.InputStream;
 import java.util.Collections;
 import java.util.Enumeration;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
+import java.util.Set;
 
 import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
+import org.apache.poi.openxml4j.opc.internal.InvalidZipException;
 
 /**
  * Provides a way to get at all the ZipEntries
@@ -90,12 +93,18 @@ public class ZipInputStreamZipEntrySource implements ZipEntrySource {
      * @see #setThresholdBytesForTempFiles
      */
     public ZipInputStreamZipEntrySource(ZipArchiveThresholdInputStream inp) throws IOException {
+        final Set<String> filenames = new HashSet<>();
         for (;;) {
             final ZipArchiveEntry zipEntry = inp.getNextEntry();
             if (zipEntry == null) {
                 break;
             }
-            zipEntries.put(zipEntry.getName(), new ZipArchiveFakeEntry(zipEntry, inp));
+            String name = zipEntry.getName();
+            if (filenames.contains(name)) {
+                throw new InvalidZipException("Input file contains more than 1 entry with the name " + name);
+            }
+            filenames.add(name);
+            zipEntries.put(name, new ZipArchiveFakeEntry(zipEntry, inp));
         }
 
         streamToClose = inp;
index ff183a696ecaaf37b41d4cfa95a76b6412ee2592..233661f5deb3b507fd22639151a118cc7cb22a98 100644 (file)
@@ -254,8 +254,8 @@ public class ZipSecureFile extends ZipFile {
     }
 
     private void validateEntryNames() throws IOException {
-        Enumeration<ZipArchiveEntry> en = getEntries();
-        Set<String> filenames = new HashSet<>();
+        final Enumeration<ZipArchiveEntry> en = getEntries();
+        final Set<String> filenames = new HashSet<>();
         while (en.hasMoreElements()) {
             String name = en.nextElement().getName();
             if (filenames.contains(name)) {
index bd364925358c06b69a887e7614d1401ca9ce443e..854798f16ff462202bc53dacb28ead284fe4238a 100644 (file)
@@ -27,7 +27,6 @@ import org.apache.poi.hssf.HSSFTestDataSamples;
 import org.apache.poi.ooxml.POIXMLProperties;
 import org.apache.poi.ooxml.TrackingInputStream;
 import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
-import org.apache.poi.openxml4j.exceptions.InvalidOperationException;
 import org.apache.poi.openxml4j.opc.ContentTypes;
 import org.apache.poi.openxml4j.opc.OPCPackage;
 import org.apache.poi.openxml4j.opc.PackageAccess;
@@ -38,6 +37,7 @@ import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
 import org.apache.poi.openxml4j.opc.PackagingURIHelper;
 import org.apache.poi.openxml4j.opc.ZipPackage;
 import org.apache.poi.openxml4j.opc.internal.FileHelper;
+import org.apache.poi.openxml4j.opc.internal.InvalidZipException;
 import org.apache.poi.openxml4j.opc.internal.MemoryPackagePart;
 import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart;
 import org.apache.poi.openxml4j.util.ZipInputStreamZipEntrySource;
@@ -1448,13 +1448,28 @@ public final class TestXSSFWorkbook extends BaseTestXWorkbook {
         }
     }
 
+    @Test
+    void testDuplicateFileReadAsOPCFile() {
+        assertThrows(InvalidFormatException.class, () -> {
+            try (OPCPackage pkg = OPCPackage.open(getSampleFile("duplicate-file.xlsx"), PackageAccess.READ)) {
+                // expect exception here
+            }
+        });
+    }
+
     @Test
     void testDuplicateFileReadAsFile() {
-        assertThrows(InvalidOperationException.class, () -> {
-            try (
-                    OPCPackage pkg = OPCPackage.open(getSampleFile("duplicate-file.xlsx"), PackageAccess.READ);
-                    XSSFWorkbook wb = new XSSFWorkbook(pkg)
-            ) {
+        assertThrows(InvalidFormatException.class, () -> {
+            try (XSSFWorkbook wb = new XSSFWorkbook(getSampleFile("duplicate-file.xlsx"))) {
+                // expect exception here
+            }
+        });
+    }
+
+    @Test
+    void testDuplicateFileReadAsStream() {
+        assertThrows(InvalidZipException.class, () -> {
+            try (XSSFWorkbook wb = new XSSFWorkbook(openSampleFileStream("duplicate-file.xlsx"))) {
                 // expect exception here
             }
         });