diff --git a/src/ooxml/java/org/apache/poi/poifs/crypt/temp/EncryptedTempData.java b/src/ooxml/java/org/apache/poi/poifs/crypt/temp/EncryptedTempData.java index 8cfd93c0f..d5dd4e230 100644 --- a/src/ooxml/java/org/apache/poi/poifs/crypt/temp/EncryptedTempData.java +++ b/src/ooxml/java/org/apache/poi/poifs/crypt/temp/EncryptedTempData.java @@ -63,16 +63,32 @@ public class EncryptedTempData { tempFile = TempFile.createTempFile("poi-temp-data", ".tmp"); } + /** + * Returns the output stream for writing the data.

+ * 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."); diff --git a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java index 0ed33d1c0..6dc03d884 100644 --- a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java +++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java @@ -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 en = zipEntrySource.getEntries(); while (en.hasMoreElements()) { ZipArchiveEntry ze = en.nextElement(); @@ -402,6 +403,7 @@ public class SXSSFWorkbook implements Workbook { } } } finally { + zos.finish(); zipEntrySource.close(); } } diff --git a/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackage.java b/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackage.java index a6a9a3529..3e747b3a3 100644 --- a/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackage.java +++ b/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackage.java @@ -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(); diff --git a/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFWorkbookWithCustomZipEntrySource.java b/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFWorkbookWithCustomZipEntrySource.java index e9f266939..aeffd1a1a 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFWorkbookWithCustomZipEntrySource.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFWorkbookWithCustomZipEntrySource.java @@ -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