]> source.dussan.org Git - poi.git/commitdiff
[bug-67579] do not close stream when reading XSSFWorkbook based on stream
authorPJ Fanning <fanningpj@apache.org>
Tue, 3 Oct 2023 00:06:27 +0000 (00:06 +0000)
committerPJ Fanning <fanningpj@apache.org>
Tue, 3 Oct 2023 00:06:27 +0000 (00:06 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1912700 13f79535-47bb-0310-9956-ffa450edef68

poi-ooxml/src/main/java/org/apache/poi/openxml4j/opc/ZipPackage.java
poi-ooxml/src/main/java/org/apache/poi/openxml4j/opc/internal/NoCloseInputStream.java [new file with mode: 0644]
poi-ooxml/src/main/java/org/apache/poi/openxml4j/opc/internal/ZipHelper.java
poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFWorkbook.java

index 21894df27059b6ddd3c0a445f26f9d51c5b665ab..dce58c71690a2b374916859a5ffd63cc43788500 100644 (file)
@@ -132,6 +132,7 @@ public final class ZipPackage extends OPCPackage {
         try (ZipArchiveThresholdInputStream zis = ZipHelper.openZipStream(in)) {
             this.zipArchive = new ZipInputStreamZipEntrySource(zis);
         } catch (final IOException | RuntimeException e) {
+            IOUtils.closeQuietly(in);
             throw e;
         }
     }
diff --git a/poi-ooxml/src/main/java/org/apache/poi/openxml4j/opc/internal/NoCloseInputStream.java b/poi-ooxml/src/main/java/org/apache/poi/openxml4j/opc/internal/NoCloseInputStream.java
new file mode 100644 (file)
index 0000000..38cd6d5
--- /dev/null
@@ -0,0 +1,30 @@
+/* ====================================================================
+   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.poi.openxml4j.opc.internal;
+
+import java.io.FilterInputStream;
+import java.io.InputStream;
+
+final class NoCloseInputStream extends FilterInputStream {
+    NoCloseInputStream(InputStream stream) {
+        super(stream);
+    }
+
+    @Override
+    public void close() {}
+}
index 26f3cffae1c5cc710711f3a71df4b2cd361a1214..7622b28b5ca3a6ddf1dfc1e21a45917472948899 100644 (file)
@@ -176,7 +176,7 @@ public final class ZipHelper {
         verifyZipHeader(checkedStream);
         
         // Open as a proper zip stream
-        return new ZipArchiveThresholdInputStream(new ZipArchiveInputStream(checkedStream));
+        return new ZipArchiveThresholdInputStream(new ZipArchiveInputStream(new NoCloseInputStream(checkedStream)));
     }
 
     /**
index 8f1ad227f668acbb5971585b4dd595dacb35516e..8d258bb289835101ecb40c6a1cb41598743e36a1 100644 (file)
 
 package org.apache.poi.xssf.usermodel;
 
+import org.apache.commons.compress.archivers.ArchiveEntry;
+import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
+import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
+import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
 import org.apache.commons.io.output.NullOutputStream;
 import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
 import org.apache.poi.POIDataSamples;
@@ -77,7 +81,9 @@ import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
 import java.util.Date;
 import java.util.Iterator;
 import java.util.List;
@@ -85,6 +91,7 @@ import java.util.Locale;
 import java.util.zip.CRC32;
 
 import static org.apache.poi.hssf.HSSFTestDataSamples.openSampleFileStream;
+import static org.apache.poi.xssf.XSSFTestDataSamples.getSampleFile;
 import static org.apache.poi.xssf.XSSFTestDataSamples.openSampleWorkbook;
 import static org.apache.poi.xssf.XSSFTestDataSamples.writeOut;
 import static org.apache.poi.xssf.XSSFTestDataSamples.writeOutAndReadBack;
@@ -1440,6 +1447,42 @@ public final class TestXSSFWorkbook extends BaseTestXWorkbook {
         }
     }
 
+    @Test
+    void readFromZipStream() throws IOException {
+        File tempFile = TempFile.createTempFile("poitest", ".zip");
+        try {
+            try (ZipArchiveOutputStream zos = new ZipArchiveOutputStream(tempFile)) {
+                File f1 = getSampleFile("github-321.xlsx");
+                File f2 = getSampleFile("48495.xlsx");
+                ArchiveEntry e1 = zos.createArchiveEntry(f1, "github-321.xlsx");
+                zos.putArchiveEntry(e1);
+                try (InputStream s = Files.newInputStream(f1.toPath())) {
+                    IOUtils.copy(s, zos);
+                }
+                zos.closeArchiveEntry();
+                ArchiveEntry e2 = zos.createArchiveEntry(f2, "48495.xlsx");
+                zos.putArchiveEntry(e2);
+                try (InputStream s = Files.newInputStream(f2.toPath())) {
+                    IOUtils.copy(s, zos);
+                }
+                zos.closeArchiveEntry();
+                zos.finish();
+            }
+            int count = 0;
+            try (ZipArchiveInputStream zis = new ZipArchiveInputStream(Files.newInputStream(tempFile.toPath()))) {
+                ZipArchiveEntry entry;
+                while ((entry = zis.getNextZipEntry()) != null) {
+                    XSSFWorkbook wb = new XSSFWorkbook(zis);
+                    assertNotNull(wb);
+                    count++;
+                }
+            }
+            assertEquals(2, count);
+        } finally {
+            tempFile.delete();
+        }
+    }
+
     private static void expectFormattedContent(Cell cell, String value) {
         assertEquals(value, new DataFormatter().formatCellValue(cell),
                 "Cell " + ref(cell) + " has wrong formatted content.");