Properly close file handles in extractors and when handling password-protected files

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1885229 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Dominik Stadler 2021-01-07 06:52:57 +00:00
parent 1882dc74c9
commit 4bc450ef5f
5 changed files with 54 additions and 14 deletions

View File

@ -291,4 +291,20 @@ public class EventBasedExcelExtractor implements POIOLE2TextExtractor, org.apach
public DirectoryEntry getRoot() { public DirectoryEntry getRoot() {
return _dir; return _dir;
} }
@Override
public void close() throws IOException {
// first perform the default close
POIOLE2TextExtractor.super.close();
// also ensure that an underlying DirectoryNode
// is closed properly to avoid leaking file-handles
DirectoryEntry root = getRoot();
if (root instanceof DirectoryNode) {
Closeable fs = ((DirectoryNode) root).getFileSystem();
if (isCloseFilesystem() && fs != null) {
fs.close();
}
}
}
} }

View File

@ -101,15 +101,22 @@ public class OldExcelExtractor implements POITextExtractor {
// ensure that the stream is properly closed here if an Exception // ensure that the stream is properly closed here if an Exception
// is thrown while opening // is thrown while opening
biffStream.close(); biffStream.close();
toClose.close();
throw e; throw e;
} }
} }
public OldExcelExtractor(POIFSFileSystem fs) throws IOException { public OldExcelExtractor(POIFSFileSystem fs) throws IOException {
toClose = fs;
open(fs); open(fs);
} }
public OldExcelExtractor(DirectoryNode directory) throws IOException { public OldExcelExtractor(DirectoryNode directory) throws IOException {
toClose = directory.getFileSystem();
open(directory); open(directory);
} }

View File

@ -100,7 +100,17 @@ public class HSSFWorkbookFactory implements WorkbookProvider {
passwordSet = true; passwordSet = true;
} }
try { try {
return new HSSFWorkbook(new POIFSFileSystem(file, readOnly), true); POIFSFileSystem fs = new POIFSFileSystem(file, readOnly);
try {
return new HSSFWorkbook(fs, true);
} catch (RuntimeException e) {
// we need to close the filesystem
// if we encounter an exception to
// not leak file handles
fs.close();
throw e;
}
} finally { } finally {
if (passwordSet) { if (passwordSet) {
Biff8EncryptionKey.setCurrentUserPassword(null); Biff8EncryptionKey.setCurrentUserPassword(null);

View File

@ -240,8 +240,6 @@ public final class POIXMLExtractorFactory implements ExtractorProvider {
} }
return null; return null;
} catch (IOException e) {
throw e;
} catch (Error | RuntimeException | XmlException | OpenXML4JException e) { // NOSONAR } catch (Error | RuntimeException | XmlException | OpenXML4JException e) { // NOSONAR
throw new IOException(e); throw new IOException(e);
} }
@ -271,6 +269,13 @@ public final class POIXMLExtractorFactory implements ExtractorProvider {
} }
try (InputStream is = dec.getDataStream(poifsDir)) { try (InputStream is = dec.getDataStream(poifsDir)) {
return create(is, password); return create(is, password);
} finally {
// we should close the underlying file-system as all information
// is read now and we should make sure that resources are freed
POIFSFileSystem fs = poifsDir.getFileSystem();
if (fs != null) {
fs.close();
}
} }
} catch (IOException | RuntimeException e) { } catch (IOException | RuntimeException e) {
throw e; throw e;

View File

@ -20,6 +20,7 @@ package org.apache.poi.ss.usermodel;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.IOException;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.Locale; import java.util.Locale;
@ -345,19 +346,20 @@ public abstract class BaseTestSheetAutosizeColumn {
@Test @Test
public void testExcelExporter() { public void testExcelExporter() throws IOException {
final Workbook wb = _testDataProvider.createWorkbook(); try (final Workbook wb = _testDataProvider.createWorkbook()) {
final Sheet sheet = wb.createSheet("test"); final Sheet sheet = wb.createSheet("test");
trackColumnsForAutoSizingIfSXSSF(sheet); trackColumnsForAutoSizingIfSXSSF(sheet);
final Row row = sheet.createRow(0); final Row row = sheet.createRow(0);
final Cell cell = row.createCell(0); final Cell cell = row.createCell(0);
CellStyle csDateTime = wb.createCellStyle(); CellStyle csDateTime = wb.createCellStyle();
csDateTime.setAlignment(HorizontalAlignment.LEFT); csDateTime.setAlignment(HorizontalAlignment.LEFT);
cell.setCellValue(new Date(Long.parseLong("1439800763994"))); cell.setCellValue(new Date(Long.parseLong("1439800763994")));
cell.setCellStyle(csDateTime); cell.setCellStyle(csDateTime);
sheet.autoSizeColumn(0); sheet.autoSizeColumn(0);
}
} }
} }