Author: centic
Date: Mon Sep 18 06:38:37 2023
New Revision: 1912383

URL: http://svn.apache.org/viewvc?rev=1912383&view=rev
Log:
Bug 66425: Avoid exceptions found via poi-fuzz

We try to avoid throwing NullPointerException, ClassCastExceptions and 
StackOverflowException, but it was possible
to trigger them

Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=61562
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=62068

Added:
    
poi/trunk/test-data/document/clusterfuzz-testcase-minimized-POIHWPFFuzzer-5074346559012864.doc
   (with props)
    
poi/trunk/test-data/document/clusterfuzz-testcase-minimized-POIXWPFFuzzer-6733884933668864.docx
   (with props)
    
poi/trunk/test-data/slideshow/clusterfuzz-testcase-minimized-POIHSLFFuzzer-5962760801091584.ppt
   (with props)
    
poi/trunk/test-data/spreadsheet/clusterfuzz-testcase-minimized-XLSX2CSVFuzzer-6594557414080512.xlsx
   (with props)
Modified:
    poi/trunk/poi-ooxml/src/main/java/org/apache/poi/ooxml/POIXMLRelation.java
    
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/ooxml/extractor/POIXMLExtractorFactory.java
    
poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hwpf/converter/WordToTextConverter.java
    
poi/trunk/poi-scratchpad/src/test/java/org/apache/poi/hslf/dev/BaseTestPPTIterating.java
    poi/trunk/poi/src/main/java/org/apache/poi/ddf/EscherContainerRecord.java
    poi/trunk/test-data/spreadsheet/stress.xls

Modified: 
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/ooxml/POIXMLRelation.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/poi-ooxml/src/main/java/org/apache/poi/ooxml/POIXMLRelation.java?rev=1912383&r1=1912382&r2=1912383&view=diff
==============================================================================
--- poi/trunk/poi-ooxml/src/main/java/org/apache/poi/ooxml/POIXMLRelation.java 
(original)
+++ poi/trunk/poi-ooxml/src/main/java/org/apache/poi/ooxml/POIXMLRelation.java 
Mon Sep 18 06:38:37 2023
@@ -198,6 +198,9 @@ public abstract class POIXMLRelation {
      *  @since 3.16-beta3
      */
     public InputStream getContents(PackagePart corePart) throws IOException, 
InvalidFormatException {
+        if (corePart == null) {
+            throw new IllegalArgumentException("Core-Part cannot be empty");
+        }
         PackageRelationshipCollection prc =
                 corePart.getRelationshipsByType(getRelation());
         Iterator<PackageRelationship> it = prc.iterator();

Modified: 
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/ooxml/extractor/POIXMLExtractorFactory.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/poi-ooxml/src/main/java/org/apache/poi/ooxml/extractor/POIXMLExtractorFactory.java?rev=1912383&r1=1912382&r2=1912383&view=diff
==============================================================================
--- 
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/ooxml/extractor/POIXMLExtractorFactory.java
 (original)
+++ 
poi/trunk/poi-ooxml/src/main/java/org/apache/poi/ooxml/extractor/POIXMLExtractorFactory.java
 Mon Sep 18 06:38:37 2023
@@ -229,7 +229,7 @@ public final class POIXMLExtractorFactor
 
             // Grab the core document part, and try to identify from that
             final PackagePart corePart = pkg.getPart(core.getRelationship(0));
-            final String contentType = corePart.getContentType();
+            final String contentType = corePart == null ? null : 
corePart.getContentType();
 
             // Is it XSSF?
             for (XSSFRelation rel : XSSFExcelExtractor.SUPPORTED_TYPES) {

Modified: 
poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hwpf/converter/WordToTextConverter.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hwpf/converter/WordToTextConverter.java?rev=1912383&r1=1912382&r2=1912383&view=diff
==============================================================================
--- 
poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hwpf/converter/WordToTextConverter.java
 (original)
+++ 
poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hwpf/converter/WordToTextConverter.java
 Mon Sep 18 06:38:37 2023
@@ -22,8 +22,6 @@ import java.lang.reflect.Method;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicInteger;
 
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.transform.OutputKeys;
 import javax.xml.transform.Transformer;
 import javax.xml.transform.dom.DOMSource;
@@ -53,10 +51,11 @@ import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
 @Beta
-public class WordToTextConverter extends AbstractWordConverter
-{
+public class WordToTextConverter extends AbstractWordConverter {
     private static final Logger LOG = 
LogManager.getLogger(WordToTextConverter.class);
 
+    private static final int MAX_NESTED_CHILD_NODES = 500;
+
     public static String getText( DirectoryNode root ) throws Exception
     {
         final HWPFDocumentCore wordDocument = AbstractWordUtils.loadDoc( root 
);
@@ -109,7 +108,7 @@ public class WordToTextConverter extends
         serializer.transform( domSource, streamResult );
     }
 
-    private static Document process( File docFile ) throws IOException, 
ParserConfigurationException {
+    private static Document process( File docFile ) throws IOException {
         try (final HWPFDocumentCore wordDocument = AbstractWordUtils.loadDoc( 
docFile )) {
             WordToTextConverter wordToTextConverter = new WordToTextConverter(
                     XMLHelper.newDocumentBuilder().newDocument());
@@ -118,7 +117,7 @@ public class WordToTextConverter extends
         }
     }
 
-    private AtomicInteger noteCounters = new AtomicInteger( 1 );
+    private final AtomicInteger noteCounters = new AtomicInteger( 1 );
 
     private Element notes;
 
@@ -130,11 +129,8 @@ public class WordToTextConverter extends
      * Creates new instance of {@link WordToTextConverter}. Can be used for
      * output several {@link HWPFDocument}s into single text document.
      *
-     * @throws ParserConfigurationException
-     *             if an internal {@link DocumentBuilder} cannot be created
      */
-    public WordToTextConverter() throws ParserConfigurationException
-    {
+    public WordToTextConverter() {
         this.textDocumentFacade = new TextDocumentFacade(
                 XMLHelper.newDocumentBuilder().newDocument() );
     }
@@ -312,6 +308,12 @@ public class WordToTextConverter extends
         Element note = textDocumentFacade.createBlock();
         notes.appendChild( note );
 
+        // avoid StackOverflowException with very deeply nested files (mostly 
synthetic test files via fuzzing)
+        // if this limit is reached in real-word documents, we can make this 
configurable
+        if (note.getParentNode() != null && 
note.getParentNode().getChildNodes().getLength() > MAX_NESTED_CHILD_NODES) {
+            throw new IllegalStateException("Had more than the limit of " + 
MAX_NESTED_CHILD_NODES + " nested child notes");
+        }
+
         note.appendChild( textDocumentFacade.createText( "^" + noteIndex
                 + "\t " ) );
         processCharacters( wordDocument, Integer.MIN_VALUE, noteTextRange, 
note );

Modified: 
poi/trunk/poi-scratchpad/src/test/java/org/apache/poi/hslf/dev/BaseTestPPTIterating.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/poi-scratchpad/src/test/java/org/apache/poi/hslf/dev/BaseTestPPTIterating.java?rev=1912383&r1=1912382&r2=1912383&view=diff
==============================================================================
--- 
poi/trunk/poi-scratchpad/src/test/java/org/apache/poi/hslf/dev/BaseTestPPTIterating.java
 (original)
+++ 
poi/trunk/poi-scratchpad/src/test/java/org/apache/poi/hslf/dev/BaseTestPPTIterating.java
 Mon Sep 18 06:38:37 2023
@@ -35,6 +35,7 @@ import java.util.stream.Stream;
 
 import org.apache.poi.POIDataSamples;
 import org.apache.poi.hslf.exceptions.EncryptedPowerPointFileException;
+import org.apache.poi.hslf.exceptions.HSLFException;
 import org.apache.poi.hslf.exceptions.OldPowerPointFormatException;
 import org.apache.poi.util.IOUtils;
 import org.apache.commons.io.output.NullPrintStream;
@@ -65,6 +66,7 @@ public abstract class BaseTestPPTIterati
         
EXCLUDED.put("clusterfuzz-testcase-minimized-POIHSLFFuzzer-6710128412590080.ppt",
 RuntimeException.class);
         
EXCLUDED.put("clusterfuzz-testcase-minimized-POIFuzzer-5429732352851968.ppt", 
FileNotFoundException.class);
         
EXCLUDED.put("clusterfuzz-testcase-minimized-POIFuzzer-5681320547975168.ppt", 
FileNotFoundException.class);
+        
EXCLUDED.put("clusterfuzz-testcase-minimized-POIHSLFFuzzer-5962760801091584.ppt",
 RuntimeException.class);
     }
 
     public static Stream<Arguments> files() {

Modified: 
poi/trunk/poi/src/main/java/org/apache/poi/ddf/EscherContainerRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/ddf/EscherContainerRecord.java?rev=1912383&r1=1912382&r2=1912383&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/ddf/EscherContainerRecord.java 
(original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/ddf/EscherContainerRecord.java 
Mon Sep 18 06:38:37 2023
@@ -50,6 +50,8 @@ public final class EscherContainerRecord
 
     private static final Logger LOGGER = 
LogManager.getLogger(EscherContainerRecord.class);
 
+    private static final int MAX_NESTED_CHILD_NODES = 1000;
+
     /**
      * in case if document contains any charts we have such document structure:
      * BOF
@@ -86,12 +88,26 @@ public final class EscherContainerRecord
 
     @Override
     public int fillFields(byte[] data, int pOffset, EscherRecordFactory 
recordFactory) {
+        return fillFields(data, pOffset, recordFactory, 0);
+    }
+
+    private int fillFields(byte[] data, int pOffset, EscherRecordFactory 
recordFactory, int nesting) {
+        if (nesting > MAX_NESTED_CHILD_NODES) {
+            throw new IllegalStateException("Had more than the limit of " + 
MAX_NESTED_CHILD_NODES + " nested child notes");
+        }
         int bytesRemaining = readHeader(data, pOffset);
         int bytesWritten = 8;
         int offset = pOffset + 8;
         while (bytesRemaining > 0 && offset < data.length) {
             EscherRecord child = recordFactory.createRecord(data, offset);
-            int childBytesWritten = child.fillFields(data, offset, 
recordFactory);
+
+            final int childBytesWritten;
+            if (child instanceof EscherContainerRecord) {
+                childBytesWritten = 
((EscherContainerRecord)child).fillFields(data, offset, recordFactory, nesting 
+ 1);
+            } else {
+                childBytesWritten = child.fillFields(data, offset, 
recordFactory);
+            }
+
             bytesWritten += childBytesWritten;
             offset += childBytesWritten;
             bytesRemaining -= childBytesWritten;

Added: 
poi/trunk/test-data/document/clusterfuzz-testcase-minimized-POIHWPFFuzzer-5074346559012864.doc
URL: 
http://svn.apache.org/viewvc/poi/trunk/test-data/document/clusterfuzz-testcase-minimized-POIHWPFFuzzer-5074346559012864.doc?rev=1912383&view=auto
==============================================================================
Binary file - no diff available.

Propchange: 
poi/trunk/test-data/document/clusterfuzz-testcase-minimized-POIHWPFFuzzer-5074346559012864.doc
------------------------------------------------------------------------------
    svn:mime-type = application/msword

Added: 
poi/trunk/test-data/document/clusterfuzz-testcase-minimized-POIXWPFFuzzer-6733884933668864.docx
URL: 
http://svn.apache.org/viewvc/poi/trunk/test-data/document/clusterfuzz-testcase-minimized-POIXWPFFuzzer-6733884933668864.docx?rev=1912383&view=auto
==============================================================================
Binary file - no diff available.

Propchange: 
poi/trunk/test-data/document/clusterfuzz-testcase-minimized-POIXWPFFuzzer-6733884933668864.docx
------------------------------------------------------------------------------
--- svn:mime-type (added)
+++ svn:mime-type Mon Sep 18 06:38:37 2023
@@ -0,0 +1 @@
+application/vnd.openxmlformats-officedocument.wordprocessingml.document

Added: 
poi/trunk/test-data/slideshow/clusterfuzz-testcase-minimized-POIHSLFFuzzer-5962760801091584.ppt
URL: 
http://svn.apache.org/viewvc/poi/trunk/test-data/slideshow/clusterfuzz-testcase-minimized-POIHSLFFuzzer-5962760801091584.ppt?rev=1912383&view=auto
==============================================================================
Binary file - no diff available.

Propchange: 
poi/trunk/test-data/slideshow/clusterfuzz-testcase-minimized-POIHSLFFuzzer-5962760801091584.ppt
------------------------------------------------------------------------------
    svn:mime-type = application/vnd.ms-powerpoint

Added: 
poi/trunk/test-data/spreadsheet/clusterfuzz-testcase-minimized-XLSX2CSVFuzzer-6594557414080512.xlsx
URL: 
http://svn.apache.org/viewvc/poi/trunk/test-data/spreadsheet/clusterfuzz-testcase-minimized-XLSX2CSVFuzzer-6594557414080512.xlsx?rev=1912383&view=auto
==============================================================================
Binary file - no diff available.

Propchange: 
poi/trunk/test-data/spreadsheet/clusterfuzz-testcase-minimized-XLSX2CSVFuzzer-6594557414080512.xlsx
------------------------------------------------------------------------------
--- svn:mime-type (added)
+++ svn:mime-type Mon Sep 18 06:38:37 2023
@@ -0,0 +1 @@
+application/vnd.openxmlformats-officedocument.spreadsheetml.sheet

Modified: poi/trunk/test-data/spreadsheet/stress.xls
URL: 
http://svn.apache.org/viewvc/poi/trunk/test-data/spreadsheet/stress.xls?rev=1912383&r1=1912382&r2=1912383&view=diff
==============================================================================
Binary files - no diff available.



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

Reply via email to