mirror of
https://github.com/apache/poi.git
synced 2026-02-27 20:40:08 +08:00
Implement lazy allocation of data for complex escher properties
This may reduce memory usage if the content is never used or not populated for some reason. This should fix https://issues.oss-fuzz.com/issues/42528528
This commit is contained in:
parent
cc8b6d7591
commit
017ff5f8f8
@ -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<Arguments> files() {
|
||||
|
||||
@ -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"
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
@ -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<String, Supplier<?>> getGenericProperties() {
|
||||
ensureComplexData();
|
||||
return GenericRecordUtil.getGenericProperties(
|
||||
"base", super::getGenericProperties,
|
||||
"data", this::getComplexData
|
||||
|
||||
@ -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
|
||||
|
||||
@ -1186,3 +1186,4 @@ ctindex5371type
|
||||
stholesizepercenta3d2type
|
||||
stholesizeubyte577atype
|
||||
chartspace67aadoctype
|
||||
ctsupplementalfonta06etype
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user