mirror of https://github.com/apache/poi.git
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
This commit is contained in:
parent
c63cb1846c
commit
8e3b60f63d
|
@ -70,6 +70,7 @@ public abstract class BaseTestPPTIterating {
|
||||||
EXCLUDED.put("clusterfuzz-testcase-minimized-POIFuzzer-6411649193738240.ppt", FileNotFoundException.class);
|
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-4838893004128256.ppt", FileNotFoundException.class);
|
||||||
EXCLUDED.put("clusterfuzz-testcase-minimized-POIHSLFFuzzer-4624961081573376.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() {
|
public static Stream<Arguments> files() {
|
||||||
|
|
|
@ -91,7 +91,7 @@ public final class EscherContainerRecord extends EscherRecord implements Iterabl
|
||||||
return fillFields(data, pOffset, recordFactory, 0);
|
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) {
|
if (nesting > MAX_NESTED_CHILD_NODES) {
|
||||||
throw new IllegalStateException("Had more than the limit of " + MAX_NESTED_CHILD_NODES + " nested child notes");
|
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;
|
final int childBytesWritten;
|
||||||
if (child instanceof EscherContainerRecord) {
|
if (child instanceof EscherContainerRecord) {
|
||||||
childBytesWritten = ((EscherContainerRecord)child).fillFields(data, offset, recordFactory, nesting + 1);
|
childBytesWritten = ((EscherContainerRecord)child).fillFields(data, offset, recordFactory, nesting + 1);
|
||||||
|
} else if (child instanceof UnknownEscherRecord) {
|
||||||
|
childBytesWritten = ((UnknownEscherRecord)child).fillFields(data, offset, recordFactory, nesting + 1);
|
||||||
} else {
|
} else {
|
||||||
childBytesWritten = child.fillFields(data, offset, recordFactory);
|
childBytesWritten = child.fillFields(data, offset, recordFactory);
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,13 +32,14 @@ import org.apache.poi.util.LittleEndian;
|
||||||
* we do not explicitly support.
|
* we do not explicitly support.
|
||||||
*/
|
*/
|
||||||
public final class UnknownEscherRecord extends EscherRecord {
|
public final class UnknownEscherRecord extends EscherRecord {
|
||||||
|
|
||||||
//arbitrarily selected; may need to increase
|
//arbitrarily selected; may need to increase
|
||||||
private static final int DEFAULT_MAX_RECORD_LENGTH = 100_000_000;
|
private static final int DEFAULT_MAX_RECORD_LENGTH = 100_000_000;
|
||||||
private static int MAX_RECORD_LENGTH = DEFAULT_MAX_RECORD_LENGTH;
|
private static int MAX_RECORD_LENGTH = DEFAULT_MAX_RECORD_LENGTH;
|
||||||
|
|
||||||
private static final byte[] NO_BYTES = new byte[0];
|
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 */
|
/** The data for this record not including the 8 byte header */
|
||||||
private byte[] thedata = NO_BYTES;
|
private byte[] thedata = NO_BYTES;
|
||||||
private final List<EscherRecord> _childRecords = new ArrayList<>();
|
private final List<EscherRecord> _childRecords = new ArrayList<>();
|
||||||
|
@ -66,6 +67,14 @@ public final class UnknownEscherRecord extends EscherRecord {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) {
|
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 );
|
int bytesRemaining = readHeader( data, offset );
|
||||||
/*
|
/*
|
||||||
* Have a check between available bytes and bytesRemaining,
|
* Have a check between available bytes and bytesRemaining,
|
||||||
|
@ -83,7 +92,13 @@ public final class UnknownEscherRecord extends EscherRecord {
|
||||||
bytesWritten += 8;
|
bytesWritten += 8;
|
||||||
while ( bytesRemaining > 0 ) {
|
while ( bytesRemaining > 0 ) {
|
||||||
EscherRecord child = recordFactory.createRecord( data, offset );
|
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;
|
bytesWritten += childBytesWritten;
|
||||||
offset += childBytesWritten;
|
offset += childBytesWritten;
|
||||||
bytesRemaining -= childBytesWritten;
|
bytesRemaining -= childBytesWritten;
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue