diff --git a/poi/src/main/java/org/apache/poi/extractor/MainExtractorFactory.java b/poi/src/main/java/org/apache/poi/extractor/MainExtractorFactory.java index eba21972d9f..8a39bc360a8 100644 --- a/poi/src/main/java/org/apache/poi/extractor/MainExtractorFactory.java +++ b/poi/src/main/java/org/apache/poi/extractor/MainExtractorFactory.java @@ -31,6 +31,7 @@ Licensed to the Apache Software Foundation (ASF) under one or more import org.apache.poi.poifs.filesystem.DirectoryNode; import org.apache.poi.poifs.filesystem.FileMagic; import org.apache.poi.poifs.filesystem.POIFSFileSystem; +import org.apache.poi.util.ExceptionUtil; /** * ExtractorFactory for HSSF and Old Excel format @@ -44,34 +45,62 @@ public boolean accepts(FileMagic fm) { @SuppressWarnings({"java:S2095"}) @Override public POITextExtractor create(File file, String password) throws IOException { - return create(new POIFSFileSystem(file, true).getRoot(), password); + POIFSFileSystem fs = new POIFSFileSystem(file, true); + POITextExtractor extractor = null; + try { + extractor = create(fs.getRoot(), password); + } catch (Throwable t) { + if (!ExceptionUtil.isFatal(t)) { + fs.close(); + throw t; + } + } + if (extractor == null) { + fs.close(); + } + return extractor; } @Override public POITextExtractor create(InputStream inputStream, String password) throws IOException { - return create(new POIFSFileSystem(inputStream).getRoot(), password); + POIFSFileSystem fs = new POIFSFileSystem(inputStream); + POITextExtractor extractor = null; + try { + extractor = create(fs.getRoot(), password); + } catch (Throwable t) { + if (!ExceptionUtil.isFatal(t)) { + fs.close(); + throw t; + } + } + if (extractor == null) { + fs.close(); + } + return extractor; } @SuppressWarnings("java:S2093") @Override public POITextExtractor create(DirectoryNode poifsDir, String password) throws IOException { final String oldPW = Biff8EncryptionKey.getCurrentUserPassword(); - try { - Biff8EncryptionKey.setCurrentUserPassword(password); - if (poifsDir.hasEntry(InternalWorkbook.OLD_WORKBOOK_DIR_ENTRY_NAME)) { + if (poifsDir.hasEntry(InternalWorkbook.OLD_WORKBOOK_DIR_ENTRY_NAME)) { + Biff8EncryptionKey.setCurrentUserPassword(password); + try { return new OldExcelExtractor(poifsDir); + } finally { + Biff8EncryptionKey.setCurrentUserPassword(oldPW); } + } - // Look for certain entries in the stream, to figure it out from - for (String workbookName : WORKBOOK_DIR_ENTRY_NAMES_CASE_INSENSITIVE) { - if (poifsDir.hasEntryCaseInsensitive(workbookName)) { - return ExtractorFactory.getPreferEventExtractor() ? new EventBasedExcelExtractor(poifsDir) : new ExcelExtractor(poifsDir); - } + // Look for certain entries in the stream, to figure it out from + for (String workbookName : WORKBOOK_DIR_ENTRY_NAMES_CASE_INSENSITIVE) { + if (poifsDir.hasEntryCaseInsensitive(workbookName)) { + final char[] passArray = password == null ? null : password.toCharArray(); + return ExtractorFactory.getPreferEventExtractor() ? + new EventBasedExcelExtractor(poifsDir, passArray) : + new ExcelExtractor(poifsDir, passArray); } - - } finally { - Biff8EncryptionKey.setCurrentUserPassword(oldPW); } return null; diff --git a/poi/src/main/java/org/apache/poi/hssf/extractor/EventBasedExcelExtractor.java b/poi/src/main/java/org/apache/poi/hssf/extractor/EventBasedExcelExtractor.java index a3bb7fb633f..3f5144a04a0 100644 --- a/poi/src/main/java/org/apache/poi/hssf/extractor/EventBasedExcelExtractor.java +++ b/poi/src/main/java/org/apache/poi/hssf/extractor/EventBasedExcelExtractor.java @@ -63,18 +63,35 @@ Licensed to the Apache Software Foundation (ASF) under one or more public class EventBasedExcelExtractor implements POIOLE2TextExtractor, org.apache.poi.ss.extractor.ExcelExtractor { private final POIFSFileSystem poifs; private final DirectoryNode _dir; + private final char[] _password; private boolean doCloseFilesystem = true; boolean _includeSheetNames = true; boolean _formulasNotResults; public EventBasedExcelExtractor(DirectoryNode dir) { + this(dir, null); + } + + /** + * @since 6.0.0 + */ + public EventBasedExcelExtractor(DirectoryNode dir, char[] password) { poifs = null; _dir = dir; + _password = password; } public EventBasedExcelExtractor(POIFSFileSystem fs) { + this(fs, null); + } + + /** + * @since 6.0.0 + */ + public EventBasedExcelExtractor(POIFSFileSystem fs, char[] password) { poifs = fs; _dir = fs.getRoot(); + _password = password; } /** @@ -95,7 +112,6 @@ public SummaryInformation getSummaryInformation() { throw new IllegalStateException("Metadata extraction not supported in streaming mode, please use ExcelExtractor"); } - /** * Would control the inclusion of cell comments from the document, * if we supported it @@ -158,7 +174,7 @@ private TextListener triggerExtraction() throws IOException { HSSFRequest request = new HSSFRequest(); request.addListenerForAllRecords(ft); - factory.processWorkbookEvents(request, _dir); + factory.processWorkbookEvents(request, _dir, _password); return tl; }