diff options
5 files changed, 47 insertions, 0 deletions
diff --git a/poi-ooxml/src/main/java/org/apache/poi/openxml4j/opc/ZipPackage.java b/poi-ooxml/src/main/java/org/apache/poi/openxml4j/opc/ZipPackage.java index 46b3fd3b7f..7811627c33 100644 --- a/poi-ooxml/src/main/java/org/apache/poi/openxml4j/opc/ZipPackage.java +++ b/poi-ooxml/src/main/java/org/apache/poi/openxml4j/opc/ZipPackage.java @@ -187,6 +187,8 @@ public final class ZipPackage extends OPCPackage { try { final ZipFile zipFile = ZipHelper.openZipFile(file); // NOSONAR ze = new ZipFileZipEntrySource(zipFile); + } catch (InvalidZipException e) { + throw new InvalidOperationException("Can't open the specified file: '" + file + "'", e); } catch (IOException e) { // probably not happening with write access - not sure how to handle the default read-write access ... if (access == PackageAccess.WRITE) { diff --git a/poi-ooxml/src/main/java/org/apache/poi/openxml4j/opc/internal/InvalidZipException.java b/poi-ooxml/src/main/java/org/apache/poi/openxml4j/opc/internal/InvalidZipException.java new file mode 100644 index 0000000000..9a788b2134 --- /dev/null +++ b/poi-ooxml/src/main/java/org/apache/poi/openxml4j/opc/internal/InvalidZipException.java @@ -0,0 +1,14 @@ +package org.apache.poi.openxml4j.opc.internal; + +import java.io.IOException; + +/** + * Thrown if the zip file is invalid. + * + * @since 5.3.1 + */ +public class InvalidZipException extends IOException { + public InvalidZipException(String message) { + super(message); + } +} diff --git a/poi-ooxml/src/main/java/org/apache/poi/openxml4j/util/ZipSecureFile.java b/poi-ooxml/src/main/java/org/apache/poi/openxml4j/util/ZipSecureFile.java index 60dcb1d53c..ff183a696e 100644 --- a/poi-ooxml/src/main/java/org/apache/poi/openxml4j/util/ZipSecureFile.java +++ b/poi-ooxml/src/main/java/org/apache/poi/openxml4j/util/ZipSecureFile.java @@ -19,11 +19,15 @@ package org.apache.poi.openxml4j.util; import java.io.File; import java.io.IOException; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.Set; import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; import org.apache.commons.compress.archivers.zip.ZipFile; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.apache.poi.openxml4j.opc.internal.InvalidZipException; import org.apache.poi.util.Internal; import org.apache.poi.util.Removal; @@ -205,6 +209,7 @@ public class ZipSecureFile extends ZipFile { public ZipSecureFile(File file) throws IOException { super(file); this.fileName = file.getAbsolutePath(); + validateEntryNames(); } /** @@ -214,6 +219,7 @@ public class ZipSecureFile extends ZipFile { public ZipSecureFile(String name) throws IOException { super(name); this.fileName = new File(name).getAbsolutePath(); + validateEntryNames(); } /** @@ -246,4 +252,16 @@ public class ZipSecureFile extends ZipFile { public String getName() { return fileName; } + + private void validateEntryNames() throws IOException { + Enumeration<ZipArchiveEntry> en = getEntries(); + Set<String> filenames = new HashSet<>(); + while (en.hasMoreElements()) { + String name = en.nextElement().getName(); + if (filenames.contains(name)) { + throw new InvalidZipException("Input file contains more than 1 entry with the name " + name); + } + filenames.add(name); + } + } } diff --git a/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFWorkbook.java b/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFWorkbook.java index 744887ff40..bd36492535 100644 --- a/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFWorkbook.java +++ b/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFWorkbook.java @@ -27,6 +27,7 @@ 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; @@ -1448,6 +1449,18 @@ public final class TestXSSFWorkbook extends BaseTestXWorkbook { } @Test + void testDuplicateFileReadAsFile() { + assertThrows(InvalidOperationException.class, () -> { + try ( + OPCPackage pkg = OPCPackage.open(getSampleFile("duplicate-file.xlsx"), PackageAccess.READ); + XSSFWorkbook wb = new XSSFWorkbook(pkg) + ) { + // expect exception here + } + }); + } + + @Test void testWorkbookCloseClosesInputStream() throws Exception { try (TrackingInputStream stream = new TrackingInputStream( HSSFTestDataSamples.openSampleFileStream("github-321.xlsx"))) { diff --git a/test-data/spreadsheet/duplicate-file.xlsx b/test-data/spreadsheet/duplicate-file.xlsx Binary files differnew file mode 100644 index 0000000000..5853cf1ded --- /dev/null +++ b/test-data/spreadsheet/duplicate-file.xlsx |