diff options
author | Dominik Stadler <centic@apache.org> | 2023-12-30 11:11:32 +0000 |
---|---|---|
committer | Dominik Stadler <centic@apache.org> | 2023-12-30 11:11:32 +0000 |
commit | 8e3b60f63d21458c59b9bf10dde10dcc2fa928b0 (patch) | |
tree | 56b4d1d9028fef4a63865de0b0458a2fedafec88 | |
parent | c63cb1846c7d7e1168abf221c831ea89b8ef6cd1 (diff) | |
download | poi-8e3b60f63d21458c59b9bf10dde10dcc2fa928b0.tar.gz poi-8e3b60f63d21458c59b9bf10dde10dcc2fa928b0.zip |
Bug 66425: Avoid exceptions found via poi-fuzz
Prevent StackOverflow via endless nesting
Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=65303
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1914989 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | poi-scratchpad/src/test/java/org/apache/poi/hslf/dev/BaseTestPPTIterating.java | 1 | ||||
-rw-r--r-- | poi/src/main/java/org/apache/poi/ddf/EscherContainerRecord.java | 4 | ||||
-rw-r--r-- | poi/src/main/java/org/apache/poi/ddf/UnknownEscherRecord.java | 19 | ||||
-rw-r--r-- | test-data/slideshow/clusterfuzz-testcase-minimized-POIHSLFFuzzer-5018229722382336.ppt | bin | 0 -> 9157 bytes | |||
-rw-r--r-- | test-data/spreadsheet/stress.xls | bin | 61952 -> 62464 bytes |
5 files changed, 21 insertions, 3 deletions
diff --git a/poi-scratchpad/src/test/java/org/apache/poi/hslf/dev/BaseTestPPTIterating.java b/poi-scratchpad/src/test/java/org/apache/poi/hslf/dev/BaseTestPPTIterating.java index be18652602..79b200dcca 100644 --- a/poi-scratchpad/src/test/java/org/apache/poi/hslf/dev/BaseTestPPTIterating.java +++ b/poi-scratchpad/src/test/java/org/apache/poi/hslf/dev/BaseTestPPTIterating.java @@ -70,6 +70,7 @@ public abstract class BaseTestPPTIterating { EXCLUDED.put("clusterfuzz-testcase-minimized-POIFuzzer-6411649193738240.ppt", FileNotFoundException.class); EXCLUDED.put("clusterfuzz-testcase-minimized-POIHSLFFuzzer-4838893004128256.ppt", FileNotFoundException.class); EXCLUDED.put("clusterfuzz-testcase-minimized-POIHSLFFuzzer-4624961081573376.ppt", FileNotFoundException.class); + EXCLUDED.put("clusterfuzz-testcase-minimized-POIHSLFFuzzer-5018229722382336.ppt", RuntimeException.class); } public static Stream<Arguments> files() { diff --git a/poi/src/main/java/org/apache/poi/ddf/EscherContainerRecord.java b/poi/src/main/java/org/apache/poi/ddf/EscherContainerRecord.java index da4d2a3289..ab30e2c404 100644 --- a/poi/src/main/java/org/apache/poi/ddf/EscherContainerRecord.java +++ b/poi/src/main/java/org/apache/poi/ddf/EscherContainerRecord.java @@ -91,7 +91,7 @@ public final class EscherContainerRecord extends EscherRecord implements Iterabl return fillFields(data, pOffset, recordFactory, 0); } - private int fillFields(byte[] data, int pOffset, EscherRecordFactory recordFactory, int nesting) { + 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"); } @@ -104,6 +104,8 @@ public final class EscherContainerRecord extends EscherRecord implements Iterabl final int childBytesWritten; if (child instanceof EscherContainerRecord) { childBytesWritten = ((EscherContainerRecord)child).fillFields(data, offset, recordFactory, nesting + 1); + } else if (child instanceof UnknownEscherRecord) { + childBytesWritten = ((UnknownEscherRecord)child).fillFields(data, offset, recordFactory, nesting + 1); } else { childBytesWritten = child.fillFields(data, offset, recordFactory); } diff --git a/poi/src/main/java/org/apache/poi/ddf/UnknownEscherRecord.java b/poi/src/main/java/org/apache/poi/ddf/UnknownEscherRecord.java index c6e71ea099..475cfdecae 100644 --- a/poi/src/main/java/org/apache/poi/ddf/UnknownEscherRecord.java +++ b/poi/src/main/java/org/apache/poi/ddf/UnknownEscherRecord.java @@ -32,13 +32,14 @@ import org.apache.poi.util.LittleEndian; * we do not explicitly support. */ public final class UnknownEscherRecord extends EscherRecord { - //arbitrarily selected; may need to increase private static final int DEFAULT_MAX_RECORD_LENGTH = 100_000_000; private static int MAX_RECORD_LENGTH = DEFAULT_MAX_RECORD_LENGTH; private static final byte[] NO_BYTES = new byte[0]; + private static final int MAX_NESTED_CHILD_NODES = 1000; + /** The data for this record not including the 8 byte header */ private byte[] thedata = NO_BYTES; private final List<EscherRecord> _childRecords = new ArrayList<>(); @@ -66,6 +67,14 @@ public final class UnknownEscherRecord extends EscherRecord { @Override public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) { + return fillFields(data, offset, recordFactory, 0); + } + + int fillFields(byte[] data, int offset, 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, offset ); /* * Have a check between available bytes and bytesRemaining, @@ -83,7 +92,13 @@ public final class UnknownEscherRecord extends EscherRecord { bytesWritten += 8; while ( bytesRemaining > 0 ) { 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; diff --git a/test-data/slideshow/clusterfuzz-testcase-minimized-POIHSLFFuzzer-5018229722382336.ppt b/test-data/slideshow/clusterfuzz-testcase-minimized-POIHSLFFuzzer-5018229722382336.ppt Binary files differnew file mode 100644 index 0000000000..29c33243bf --- /dev/null +++ b/test-data/slideshow/clusterfuzz-testcase-minimized-POIHSLFFuzzer-5018229722382336.ppt diff --git a/test-data/spreadsheet/stress.xls b/test-data/spreadsheet/stress.xls Binary files differindex 686638aa53..43e8f6950d 100644 --- a/test-data/spreadsheet/stress.xls +++ b/test-data/spreadsheet/stress.xls |