]> source.dussan.org Git - poi.git/commitdiff
#60713 - (S)XSSFWorkbook/POIXMLDocument.write(OutputStream) closes the OutputStream
authorAndreas Beeker <kiwiwings@apache.org>
Thu, 14 Jun 2018 22:25:26 +0000 (22:25 +0000)
committerAndreas Beeker <kiwiwings@apache.org>
Thu, 14 Jun 2018 22:25:26 +0000 (22:25 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1833566 13f79535-47bb-0310-9956-ffa450edef68

src/ooxml/java/org/apache/poi/poifs/crypt/temp/EncryptedTempData.java
src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java
src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackage.java
src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFWorkbookWithCustomZipEntrySource.java

index 8cfd93c0f5cbc6d923231f69dd8cfb33287e30cd..d5dd4e230301fc8ba101dad453f3320958bf0bf1 100644 (file)
@@ -63,16 +63,32 @@ public class EncryptedTempData {
         tempFile = TempFile.createTempFile("poi-temp-data", ".tmp");
     }
 
+    /**
+     * Returns the output stream for writing the data.<p>
+     * Make sure to close it, otherwise the last cipher block is not written completely.
+     *
+     * @return the outputstream
+     * @throws IOException if the writing to the underlying file fails
+     */
     public OutputStream getOutputStream() throws IOException {
         Cipher ciEnc = CryptoFunctions.getCipher(skeySpec, cipherAlgorithm, ChainingMode.cbc, ivBytes, Cipher.ENCRYPT_MODE, PADDING);
         return new CipherOutputStream(new FileOutputStream(tempFile), ciEnc);
     }
 
+    /**
+     * Returns the input stream for reading the previously written encrypted data
+     *
+     * @return the inputstream
+     * @throws IOException if the reading of the underlying file fails
+     */
     public InputStream getInputStream() throws IOException {
         Cipher ciDec = CryptoFunctions.getCipher(skeySpec, cipherAlgorithm, ChainingMode.cbc, ivBytes, Cipher.DECRYPT_MODE, PADDING);
         return new CipherInputStream(new FileInputStream(tempFile), ciDec);
     }
-    
+
+    /**
+     * Removes the temporarily backing file
+     */
     public void dispose() {
         if (!tempFile.delete()) {
             LOG.log(POILogger.WARN, tempFile.getAbsolutePath()+" can't be removed (or was already removed.");
index 0ed33d1c0b6cae57d2993f62b61502ea2236c1ed..6dc03d884e0e81ef72b27e1f539c8f3a408f9daa 100644 (file)
@@ -376,7 +376,8 @@ public class SXSSFWorkbook implements Workbook {
     }
 
     protected void injectData(ZipEntrySource zipEntrySource, OutputStream out) throws IOException {
-        try (ZipArchiveOutputStream zos = new ZipArchiveOutputStream(out)) {
+        ZipArchiveOutputStream zos = new ZipArchiveOutputStream(out);
+        try {
             Enumeration<? extends ZipArchiveEntry> en = zipEntrySource.getEntries();
             while (en.hasMoreElements()) {
                 ZipArchiveEntry ze = en.nextElement();
@@ -402,6 +403,7 @@ public class SXSSFWorkbook implements Workbook {
                 }
             }
         } finally {
+            zos.finish();
             zipEntrySource.close();
         }
     }
index a6a9a35295eb704794f708a2011b817460142db1..3e747b3a363210bdfac13dd9df54ad9a8ac841a5 100644 (file)
@@ -17,6 +17,8 @@
 
 package org.apache.poi.openxml4j.opc;
 
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -77,6 +79,8 @@ import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
 import org.apache.poi.util.TempFile;
 import org.apache.poi.xssf.XSSFTestDataSamples;
+import org.apache.poi.xssf.streaming.SXSSFWorkbook;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.apache.poi.xwpf.usermodel.XWPFRelation;
 import org.apache.xmlbeans.XmlException;
 import org.hamcrest.Description;
@@ -85,6 +89,7 @@ import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
+import org.mockito.Mockito;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.NodeList;
@@ -1085,6 +1090,24 @@ public final class TestPackage {
                openInvalidFile("SampleSS.txt", true);
        }
 
+       @Test
+       public void testDoNotCloseStream() throws IOException {
+               OutputStream os = Mockito.mock(OutputStream.class);
+               try (XSSFWorkbook wb = new XSSFWorkbook()) {
+                       wb.createSheet();
+                       wb.write(os);
+               }
+               verify(os, never()).close();
+
+               try (SXSSFWorkbook wb = new SXSSFWorkbook()) {
+                       wb.createSheet();
+                       wb.write(os);
+               }
+               verify(os, never()).close();
+       }
+
+
+
        private static void openInvalidFile(final String name, final boolean useStream) throws IOException, InvalidFormatException {
                // Spreadsheet has a good mix of alternate file types
                final POIDataSamples files = POIDataSamples.getSpreadSheetInstance();
index e9f266939727ee1df9b12a8654c53e38bb94d859..aeffd1a1ab5f8e444017cf902f40d48b0cbdb10e 100644 (file)
@@ -30,6 +30,7 @@ import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.OutputStream;
 import java.nio.charset.Charset;
 import java.security.GeneralSecurityException;
 import java.util.List;
@@ -86,21 +87,23 @@ public final class TestSXSSFWorkbookWithCustomZipEntrySource {
         SXSSFCell cell1 = row1.createCell(1);
         cell1.setCellValue(cellValue);
         EncryptedTempData tempData = new EncryptedTempData();
-        workbook.write(tempData.getOutputStream());
+        try (OutputStream os = tempData.getOutputStream()) {
+            workbook.write(os);
+        }
         workbook.close();
         workbook.dispose();
-        ZipEntrySource zipEntrySource = AesZipFileZipEntrySource.createZipEntrySource(tempData.getInputStream());
-        tempData.dispose();
-        OPCPackage opc = OPCPackage.open(zipEntrySource);
-        XSSFWorkbook xwb = new XSSFWorkbook(opc);
-        zipEntrySource.close();
-        XSSFSheet xs1 = xwb.getSheetAt(0);
-        assertEquals(sheetName, xs1.getSheetName());
-        XSSFRow xr1 = xs1.getRow(1);
-        XSSFCell xc1 = xr1.getCell(1);
-        assertEquals(cellValue, xc1.getStringCellValue());
-        xwb.close();
-        opc.close();
+        try (InputStream is = tempData.getInputStream();
+             ZipEntrySource zipEntrySource = AesZipFileZipEntrySource.createZipEntrySource(is)) {
+            tempData.dispose();
+            try (OPCPackage opc = OPCPackage.open(zipEntrySource);
+                XSSFWorkbook xwb = new XSSFWorkbook(opc)) {
+                XSSFSheet xs1 = xwb.getSheetAt(0);
+                assertEquals(sheetName, xs1.getSheetName());
+                XSSFRow xr1 = xs1.getRow(1);
+                XSSFCell xc1 = xr1.getCell(1);
+                assertEquals(cellValue, xc1.getStringCellValue());
+            }
+        }
     }
     
     @Test