#60713 - (S)XSSFWorkbook/POIXMLDocument.write(OutputStream) closes the OutputStream

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1833566 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andreas Beeker 2018-06-14 22:25:26 +00:00
parent 5169036f66
commit de9b2e0481
4 changed files with 59 additions and 15 deletions

View File

@ -63,16 +63,32 @@ public class EncryptedTempData {
tempFile = TempFile.createTempFile("poi-temp-data", ".tmp"); 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 { public OutputStream getOutputStream() throws IOException {
Cipher ciEnc = CryptoFunctions.getCipher(skeySpec, cipherAlgorithm, ChainingMode.cbc, ivBytes, Cipher.ENCRYPT_MODE, PADDING); Cipher ciEnc = CryptoFunctions.getCipher(skeySpec, cipherAlgorithm, ChainingMode.cbc, ivBytes, Cipher.ENCRYPT_MODE, PADDING);
return new CipherOutputStream(new FileOutputStream(tempFile), ciEnc); 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 { public InputStream getInputStream() throws IOException {
Cipher ciDec = CryptoFunctions.getCipher(skeySpec, cipherAlgorithm, ChainingMode.cbc, ivBytes, Cipher.DECRYPT_MODE, PADDING); Cipher ciDec = CryptoFunctions.getCipher(skeySpec, cipherAlgorithm, ChainingMode.cbc, ivBytes, Cipher.DECRYPT_MODE, PADDING);
return new CipherInputStream(new FileInputStream(tempFile), ciDec); return new CipherInputStream(new FileInputStream(tempFile), ciDec);
} }
/**
* Removes the temporarily backing file
*/
public void dispose() { public void dispose() {
if (!tempFile.delete()) { if (!tempFile.delete()) {
LOG.log(POILogger.WARN, tempFile.getAbsolutePath()+" can't be removed (or was already removed."); LOG.log(POILogger.WARN, tempFile.getAbsolutePath()+" can't be removed (or was already removed.");

View File

@ -376,7 +376,8 @@ public class SXSSFWorkbook implements Workbook {
} }
protected void injectData(ZipEntrySource zipEntrySource, OutputStream out) throws IOException { 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(); Enumeration<? extends ZipArchiveEntry> en = zipEntrySource.getEntries();
while (en.hasMoreElements()) { while (en.hasMoreElements()) {
ZipArchiveEntry ze = en.nextElement(); ZipArchiveEntry ze = en.nextElement();
@ -402,6 +403,7 @@ public class SXSSFWorkbook implements Workbook {
} }
} }
} finally { } finally {
zos.finish();
zipEntrySource.close(); zipEntrySource.close();
} }
} }

View File

@ -17,6 +17,8 @@
package org.apache.poi.openxml4j.opc; 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.assertEquals;
import static org.junit.Assert.assertFalse; 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.POILogger;
import org.apache.poi.util.TempFile; import org.apache.poi.util.TempFile;
import org.apache.poi.xssf.XSSFTestDataSamples; 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.poi.xwpf.usermodel.XWPFRelation;
import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlException;
import org.hamcrest.Description; import org.hamcrest.Description;
@ -85,6 +89,7 @@ import org.junit.Ignore;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.ExpectedException; import org.junit.rules.ExpectedException;
import org.mockito.Mockito;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.w3c.dom.Element; import org.w3c.dom.Element;
import org.w3c.dom.NodeList; import org.w3c.dom.NodeList;
@ -1085,6 +1090,24 @@ public final class TestPackage {
openInvalidFile("SampleSS.txt", true); 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 { private static void openInvalidFile(final String name, final boolean useStream) throws IOException, InvalidFormatException {
// Spreadsheet has a good mix of alternate file types // Spreadsheet has a good mix of alternate file types
final POIDataSamples files = POIDataSamples.getSpreadSheetInstance(); final POIDataSamples files = POIDataSamples.getSpreadSheetInstance();

View File

@ -30,6 +30,7 @@ import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.security.GeneralSecurityException; import java.security.GeneralSecurityException;
import java.util.List; import java.util.List;
@ -86,21 +87,23 @@ public final class TestSXSSFWorkbookWithCustomZipEntrySource {
SXSSFCell cell1 = row1.createCell(1); SXSSFCell cell1 = row1.createCell(1);
cell1.setCellValue(cellValue); cell1.setCellValue(cellValue);
EncryptedTempData tempData = new EncryptedTempData(); EncryptedTempData tempData = new EncryptedTempData();
workbook.write(tempData.getOutputStream()); try (OutputStream os = tempData.getOutputStream()) {
workbook.write(os);
}
workbook.close(); workbook.close();
workbook.dispose(); workbook.dispose();
ZipEntrySource zipEntrySource = AesZipFileZipEntrySource.createZipEntrySource(tempData.getInputStream()); try (InputStream is = tempData.getInputStream();
tempData.dispose(); ZipEntrySource zipEntrySource = AesZipFileZipEntrySource.createZipEntrySource(is)) {
OPCPackage opc = OPCPackage.open(zipEntrySource); tempData.dispose();
XSSFWorkbook xwb = new XSSFWorkbook(opc); try (OPCPackage opc = OPCPackage.open(zipEntrySource);
zipEntrySource.close(); XSSFWorkbook xwb = new XSSFWorkbook(opc)) {
XSSFSheet xs1 = xwb.getSheetAt(0); XSSFSheet xs1 = xwb.getSheetAt(0);
assertEquals(sheetName, xs1.getSheetName()); assertEquals(sheetName, xs1.getSheetName());
XSSFRow xr1 = xs1.getRow(1); XSSFRow xr1 = xs1.getRow(1);
XSSFCell xc1 = xr1.getCell(1); XSSFCell xc1 = xr1.getCell(1);
assertEquals(cellValue, xc1.getStringCellValue()); assertEquals(cellValue, xc1.getStringCellValue());
xwb.close(); }
opc.close(); }
} }
@Test @Test