diff options
author | Dominik Stadler <centic@apache.org> | 2023-08-09 16:16:49 +0000 |
---|---|---|
committer | Dominik Stadler <centic@apache.org> | 2023-08-09 16:16:49 +0000 |
commit | 107def2e6527f605f1108829dd850fa46bc65b62 (patch) | |
tree | 529da2ca6e73abc7293f7b317bcce807fed02b95 /poi-scratchpad | |
parent | ccec6c4bf8484fef87584723781dc4b7370ec459 (diff) | |
download | poi-107def2e6527f605f1108829dd850fa46bc65b62.tar.gz poi-107def2e6527f605f1108829dd850fa46bc65b62.zip |
Bug 66425: Avoid a StackOverflowException found via oss-fuzz
We try to avoid causing StackOverflow, but it was possible
to trigger one here with a specially crafted input-file.
This puts a limit on the number of nested children in place
and logs a warning when the Stream is not fully parsed.
Should fix https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=61256
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1911577 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'poi-scratchpad')
-rw-r--r-- | poi-scratchpad/src/main/java/org/apache/poi/hdgf/streams/PointerContainingStream.java | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/poi-scratchpad/src/main/java/org/apache/poi/hdgf/streams/PointerContainingStream.java b/poi-scratchpad/src/main/java/org/apache/poi/hdgf/streams/PointerContainingStream.java index 3f3192f9fc..c4a91ad969 100644 --- a/poi-scratchpad/src/main/java/org/apache/poi/hdgf/streams/PointerContainingStream.java +++ b/poi-scratchpad/src/main/java/org/apache/poi/hdgf/streams/PointerContainingStream.java @@ -17,6 +17,8 @@ package org.apache.poi.hdgf.streams; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.apache.poi.hdgf.chunks.ChunkFactory; import org.apache.poi.hdgf.pointers.Pointer; import org.apache.poi.hdgf.pointers.PointerFactory; @@ -26,11 +28,15 @@ import org.apache.poi.hdgf.pointers.PointerFactory; * other data too. */ public class PointerContainingStream extends Stream { // TODO - instantiable superclass - private Pointer[] childPointers; + private static final Logger LOG = LogManager.getLogger(PointerContainingStream.class); + + private static final int MAX_CHILDREN_NESTING = 1000; + + private final Pointer[] childPointers; private Stream[] childStreams; - private ChunkFactory chunkFactory; - private PointerFactory pointerFactory; + private final ChunkFactory chunkFactory; + private final PointerFactory pointerFactory; protected PointerContainingStream(Pointer pointer, StreamStore store, ChunkFactory chunkFactory, PointerFactory pointerFactory) { super(pointer, store); @@ -58,6 +64,17 @@ public class PointerContainingStream extends Stream { // TODO - instantiable sup * those if appropriate. */ public void findChildren(byte[] documentData) { + findChildren(documentData, 0); + } + + private void findChildren(byte[] documentData, int nesting) { + if (nesting > MAX_CHILDREN_NESTING) { + LOG.warn("Encountered too deep nesting, cannot fully process stream " + + " with more than " + MAX_CHILDREN_NESTING + " nested children." + + " Some data could not be parsed."); + return; + } + // For each pointer, generate the Stream it points to childStreams = new Stream[childPointers.length]; for(int i=0; i<childPointers.length; i++) { @@ -74,7 +91,7 @@ public class PointerContainingStream extends Stream { // TODO - instantiable sup if(childStreams[i] instanceof PointerContainingStream) { PointerContainingStream child = (PointerContainingStream)childStreams[i]; - child.findChildren(documentData); + child.findChildren(documentData, nesting + 1); } } } |