This is an automated email from the ASF dual-hosted git repository.

centic pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/poi.git

commit ae3ed57baa41b3e4ec027213f9367b77aeeab2c3
Author: Dominik Stadler <[email protected]>
AuthorDate: Fri Dec 5 11:55:12 2025 +0100

    Prevent a file-handle leak
    
    File-handles could leak when an exception occurs during
    class initialization when loading an broken workbook-file
---
 .../org/apache/poi/xssf/usermodel/XSSFWorkbook.java | 21 +++++++++++++++------
 .../apache/poi/xwpf/usermodel/TestXWPFDocument.java | 12 ++++++++++++
 2 files changed, 27 insertions(+), 6 deletions(-)

diff --git 
a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java 
b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java
index a063b4d8a9..1edd31d614 100644
--- a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java
+++ b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java
@@ -256,15 +256,24 @@ public class XSSFWorkbook extends POIXMLDocument 
implements Workbook, Date1904Su
      */
     public XSSFWorkbook(OPCPackage pkg) throws IOException {
         super(pkg);
-        this.xssfFactory = XSSFFactory.getInstance();
 
-        beforeDocumentRead();
+        try {
+            this.xssfFactory = XSSFFactory.getInstance();
 
-        // Build a tree of POIXMLDocumentParts, this workbook being the root
-        load(this.xssfFactory);
+            beforeDocumentRead();
 
-        // some broken Workbooks miss this...
-        setBookViewsIfMissing();
+            // Build a tree of POIXMLDocumentParts, this workbook being the 
root
+            load(this.xssfFactory);
+
+            // some broken Workbooks miss this...
+            setBookViewsIfMissing();
+        } catch (IOException | RuntimeException e) {
+            // close the package on exception to avoid file handle leaks
+            pkg.revert();
+
+            // rethrow exception
+            throw e;
+        }
     }
 
     /**
diff --git 
a/poi-ooxml/src/test/java/org/apache/poi/xwpf/usermodel/TestXWPFDocument.java 
b/poi-ooxml/src/test/java/org/apache/poi/xwpf/usermodel/TestXWPFDocument.java
index aefda3f01d..cc0349c283 100644
--- 
a/poi-ooxml/src/test/java/org/apache/poi/xwpf/usermodel/TestXWPFDocument.java
+++ 
b/poi-ooxml/src/test/java/org/apache/poi/xwpf/usermodel/TestXWPFDocument.java
@@ -44,6 +44,7 @@ import org.apache.poi.openxml4j.opc.PackageAccess;
 import org.apache.poi.openxml4j.opc.PackagePart;
 import org.apache.poi.openxml4j.opc.PackagePartName;
 import org.apache.poi.openxml4j.opc.PackagingURIHelper;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.apache.poi.xwpf.XWPFTestDataSamples;
 import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
 import org.apache.xmlbeans.XmlCursor;
@@ -512,6 +513,8 @@ public final class TestXWPFDocument {
             try (XWPFDocument doc = new XWPFDocument(
                     
POIDataSamples.getDocumentInstance().openResourceAsStream("unicode-path.docx")))
 {
                 // expect exception here
+
+                assertNotNull(doc);
             }
         });
         assertEquals("InvalidFormatException", 
ex.getCause().getClass().getSimpleName());
@@ -544,4 +547,13 @@ public final class TestXWPFDocument {
             }
         }
     }
+
+    @Test
+    void testFileHandleLeak() {
+        //noinspection resource
+        assertThrows(POIXMLException.class,
+                // Use XSSFWorkbook on purpose here to trigger missing closing 
of file-handle
+                () -> new XSSFWorkbook(
+                        
POIDataSamples.getDocumentInstance().getFile("clusterfuzz-testcase-minimized-POIXWPFFuzzer-4791943399604224.docx")));
+    }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to