diff --git a/poi-scratchpad/src/test/java/org/apache/poi/hwpf/converter/TestWordToConverterSuite.java b/poi-scratchpad/src/test/java/org/apache/poi/hwpf/converter/TestWordToConverterSuite.java index 9cfb4b6d11..56665c679d 100644 --- a/poi-scratchpad/src/test/java/org/apache/poi/hwpf/converter/TestWordToConverterSuite.java +++ b/poi-scratchpad/src/test/java/org/apache/poi/hwpf/converter/TestWordToConverterSuite.java @@ -61,7 +61,8 @@ public class TestWordToConverterSuite { "clusterfuzz-testcase-minimized-POIHWPFFuzzer-4947285593948160.doc", "clusterfuzz-testcase-minimized-POIHWPFFuzzer-5440721166139392.doc", "clusterfuzz-testcase-minimized-POIHWPFFuzzer-5050208641482752.doc", - "clusterfuzz-testcase-minimized-POIHWPFFuzzer-6610789829836800.doc" + "clusterfuzz-testcase-minimized-POIHWPFFuzzer-6610789829836800.doc", + "clusterfuzz-testcase-minimized-POIHWPFFuzzer-5832867957309440.doc" ); public static Stream files() { diff --git a/poi-scratchpad/src/test/java/org/apache/poi/hwpf/converter/TestWordToTextConverter.java b/poi-scratchpad/src/test/java/org/apache/poi/hwpf/converter/TestWordToTextConverter.java index 9e66096b3c..c2bd0582ba 100644 --- a/poi-scratchpad/src/test/java/org/apache/poi/hwpf/converter/TestWordToTextConverter.java +++ b/poi-scratchpad/src/test/java/org/apache/poi/hwpf/converter/TestWordToTextConverter.java @@ -54,7 +54,8 @@ public class TestWordToTextConverter { "clusterfuzz-testcase-minimized-POIHWPFFuzzer-4947285593948160.doc", "clusterfuzz-testcase-minimized-POIHWPFFuzzer-5440721166139392.doc", "clusterfuzz-testcase-minimized-POIHWPFFuzzer-5050208641482752.doc", - "clusterfuzz-testcase-minimized-POIHWPFFuzzer-6610789829836800.doc" + "clusterfuzz-testcase-minimized-POIHWPFFuzzer-6610789829836800.doc", + "clusterfuzz-testcase-minimized-POIHWPFFuzzer-5832867957309440.doc" ); /** diff --git a/poi/src/main/java/org/apache/poi/ddf/EscherComplexProperty.java b/poi/src/main/java/org/apache/poi/ddf/EscherComplexProperty.java index c001707c6c..675bc7d49c 100644 --- a/poi/src/main/java/org/apache/poi/ddf/EscherComplexProperty.java +++ b/poi/src/main/java/org/apache/poi/ddf/EscherComplexProperty.java @@ -35,6 +35,7 @@ public class EscherComplexProperty extends EscherProperty { private static final int DEFAULT_MAX_RECORD_LENGTH = 100_000_000; private static int MAX_RECORD_LENGTH = DEFAULT_MAX_RECORD_LENGTH; + private int complexSize; private byte[] complexData; /** @@ -61,7 +62,15 @@ public class EscherComplexProperty extends EscherProperty { */ public EscherComplexProperty(short id, int complexSize) { super((short)(id | IS_COMPLEX)); - complexData = IOUtils.safelyAllocate(complexSize, MAX_RECORD_LENGTH); + + // lazy-allocate the data + this.complexSize = complexSize; + } + + private void ensureComplexData() { + if (this.complexData == null) { + complexData = IOUtils.safelyAllocate(complexSize, MAX_RECORD_LENGTH); + } } /** @@ -94,7 +103,7 @@ public class EscherComplexProperty extends EscherProperty { @Override public int serializeSimplePart(byte[] data, int pos) { LittleEndian.putShort(data, pos, getId()); - LittleEndian.putInt(data, pos + 2, complexData.length); + LittleEndian.putInt(data, pos + 2, complexSize); return 6; } @@ -107,8 +116,13 @@ public class EscherComplexProperty extends EscherProperty { */ @Override public int serializeComplexPart(byte[] data, int pos) { - System.arraycopy(complexData, 0, data, pos, complexData.length); - return complexData.length; + if (complexData == null) { + // initialize empty array if complexData was never allocated + Arrays.fill(data, pos, pos + complexSize, (byte)0); + } else { + System.arraycopy(complexData, 0, data, pos, complexData.length); + } + return complexSize; } /** @@ -117,6 +131,7 @@ public class EscherComplexProperty extends EscherProperty { * @return the complex bytes */ public byte[] getComplexData() { + ensureComplexData(); return complexData; } @@ -128,25 +143,31 @@ public class EscherComplexProperty extends EscherProperty { if (complexData == null) { return 0; } else { + ensureComplexData(); int copySize = Math.max(0, Math.min(this.complexData.length, complexData.length - offset)); System.arraycopy(complexData, offset, this.complexData, 0, copySize); return copySize; } } - - protected void resizeComplexData(int newSize) { resizeComplexData(newSize, Integer.MAX_VALUE); } protected void resizeComplexData(int newSize, int copyLen) { - if (newSize == complexData.length) { + if (newSize == complexSize) { return; } + + // no need to copy if data was not initialized yet + if (complexData == null) { + return; + } + byte[] newArray = IOUtils.safelyAllocate(newSize, MAX_RECORD_LENGTH); System.arraycopy(complexData, 0, newArray, 0, Math.min(Math.min(complexData.length, copyLen),newSize)); complexData = newArray; + complexSize = newSize; } /** @@ -166,6 +187,18 @@ public class EscherComplexProperty extends EscherProperty { EscherComplexProperty escherComplexProperty = (EscherComplexProperty) o; + // not equal if size differs + if (complexSize != escherComplexProperty.complexSize) { + return false; + } + + if (complexData == null) { + // if coomplexData is not initialized, it is equal only if + // complexData is also uninitialized or equals an empty array + return escherComplexProperty.complexData == null || + Arrays.equals(escherComplexProperty.complexData, new byte[escherComplexProperty.complexSize]); + } + return Arrays.equals(complexData, escherComplexProperty.complexData); } @@ -176,16 +209,18 @@ public class EscherComplexProperty extends EscherProperty { */ @Override public int getPropertySize() { - return 6 + complexData.length; + return 6 + complexSize; } @Override public int hashCode() { + ensureComplexData(); return Arrays.deepHashCode(new Object[]{complexData, getId()}); } @Override public Map> getGenericProperties() { + ensureComplexData(); return GenericRecordUtil.getGenericProperties( "base", super::getGenericProperties, "data", this::getComplexData diff --git a/src/resources/ooxml-lite-report.clazz b/src/resources/ooxml-lite-report.clazz index 144216dba8..444e098823 100644 --- a/src/resources/ooxml-lite-report.clazz +++ b/src/resources/ooxml-lite-report.clazz @@ -2551,3 +2551,5 @@ org/openxmlformats/schemas/drawingml/x2006/main/impl/CTAudioFileImpl org/openxmlformats/schemas/drawingml/x2006/main/CTAudioFile org/openxmlformats/schemas/drawingml/x2006/chart/impl/STHoleSizePercentImpl org/openxmlformats/schemas/drawingml/x2006/chart/impl/STHoleSizeUByteImpl +org/openxmlformats/schemas/drawingml/x2006/main/CTSupplementalFont +org/openxmlformats/schemas/drawingml/x2006/main/impl/CTSupplementalFontImpl diff --git a/src/resources/ooxml-lite-report.xsb b/src/resources/ooxml-lite-report.xsb index 7f3d358103..2120d975b8 100644 --- a/src/resources/ooxml-lite-report.xsb +++ b/src/resources/ooxml-lite-report.xsb @@ -1186,3 +1186,4 @@ ctindex5371type stholesizepercenta3d2type stholesizeubyte577atype chartspace67aadoctype +ctsupplementalfonta06etype diff --git a/test-data/document/clusterfuzz-testcase-minimized-POIHWPFFuzzer-5832867957309440.doc b/test-data/document/clusterfuzz-testcase-minimized-POIHWPFFuzzer-5832867957309440.doc new file mode 100644 index 0000000000..4f2d6de96c Binary files /dev/null and b/test-data/document/clusterfuzz-testcase-minimized-POIHWPFFuzzer-5832867957309440.doc differ diff --git a/test-data/spreadsheet/stress.xls b/test-data/spreadsheet/stress.xls index 6fb06f73a6..94775397c8 100644 Binary files a/test-data/spreadsheet/stress.xls and b/test-data/spreadsheet/stress.xls differ