]> source.dussan.org Git - poi.git/commitdiff
Properly close file handles in extractors and when handling password-protected files
authorDominik Stadler <centic@apache.org>
Thu, 7 Jan 2021 06:52:57 +0000 (06:52 +0000)
committerDominik Stadler <centic@apache.org>
Thu, 7 Jan 2021 06:52:57 +0000 (06:52 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1885229 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/hssf/extractor/EventBasedExcelExtractor.java
src/java/org/apache/poi/hssf/extractor/OldExcelExtractor.java
src/java/org/apache/poi/hssf/usermodel/HSSFWorkbookFactory.java
src/ooxml/java/org/apache/poi/ooxml/extractor/POIXMLExtractorFactory.java
src/testcases/org/apache/poi/ss/usermodel/BaseTestSheetAutosizeColumn.java

index 68c69cf1d36c46e79a43c324916338f7fd49211c..a3239def70cf0ff55e57fb93c97a503d330a3a0e 100644 (file)
@@ -291,4 +291,20 @@ public class EventBasedExcelExtractor implements POIOLE2TextExtractor, org.apach
     public DirectoryEntry getRoot() {
         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();
+            }
+        }
+    }
 }
index 56b1424b3d716292c3712412b787b7719d01dcae..c93482f901a2edb64b658207d7872f063b91902d 100644 (file)
@@ -101,15 +101,22 @@ public class OldExcelExtractor implements POITextExtractor {
             // ensure that the stream is properly closed here if an Exception
             // is thrown while opening
             biffStream.close();
+
+            toClose.close();
+
             throw e;
         }
     }
 
     public OldExcelExtractor(POIFSFileSystem fs) throws IOException {
+        toClose = fs;
+
         open(fs);
     }
 
     public OldExcelExtractor(DirectoryNode directory) throws IOException {
+        toClose = directory.getFileSystem();
+
         open(directory);
     }
 
index 0c4c98a7c2e84952d73a08831d3c644d2fd8818c..b43a45de6aa2c317df98210a9d0df9cb3919e4a5 100644 (file)
@@ -100,7 +100,17 @@ public class HSSFWorkbookFactory implements WorkbookProvider {
             passwordSet = true;
         }
         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 {
             if (passwordSet) {
                 Biff8EncryptionKey.setCurrentUserPassword(null);
index 2d90b46f202e79a520d342d6bad9d83732962165..8cad08609d9194f45f512716978458e0c9978ad9 100644 (file)
@@ -240,8 +240,6 @@ public final class POIXMLExtractorFactory implements ExtractorProvider {
             }
 
             return null;
-        } catch (IOException e) {
-            throw e;
         } catch (Error | RuntimeException | XmlException | OpenXML4JException e) { // NOSONAR
             throw new IOException(e);
         }
@@ -271,6 +269,13 @@ public final class POIXMLExtractorFactory implements ExtractorProvider {
                 }
                 try (InputStream is = dec.getDataStream(poifsDir)) {
                     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) {
                 throw e;
index c7584ef978891ca5a296a0857841854bd0baa1cf..849f656d1cec5cba46c41b4cfe458f6ed808e1c9 100644 (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.assertTrue;
 
+import java.io.IOException;
 import java.util.Calendar;
 import java.util.Date;
 import java.util.Locale;
@@ -345,19 +346,20 @@ public abstract class BaseTestSheetAutosizeColumn {
 
 
     @Test
-    public void testExcelExporter() {
-        final Workbook wb = _testDataProvider.createWorkbook();
-        final Sheet sheet = wb.createSheet("test");
-        trackColumnsForAutoSizingIfSXSSF(sheet);
-        final Row row = sheet.createRow(0);
-        final Cell cell = row.createCell(0);
+    public void testExcelExporter() throws IOException {
+        try (final Workbook wb = _testDataProvider.createWorkbook()) {
+            final Sheet sheet = wb.createSheet("test");
+            trackColumnsForAutoSizingIfSXSSF(sheet);
+            final Row row = sheet.createRow(0);
+            final Cell cell = row.createCell(0);
 
-        CellStyle csDateTime = wb.createCellStyle();
-        csDateTime.setAlignment(HorizontalAlignment.LEFT);
+            CellStyle csDateTime = wb.createCellStyle();
+            csDateTime.setAlignment(HorizontalAlignment.LEFT);
 
-        cell.setCellValue(new Date(Long.parseLong("1439800763994")));
-        cell.setCellStyle(csDateTime);
+            cell.setCellValue(new Date(Long.parseLong("1439800763994")));
+            cell.setCellStyle(csDateTime);
 
-        sheet.autoSizeColumn(0);
+            sheet.autoSizeColumn(0);
+        }
     }
 }
\ No newline at end of file