aboutsummaryrefslogtreecommitdiffstats
path: root/poi/src/main/java
diff options
context:
space:
mode:
authorDominik Stadler <centic@apache.org>2024-07-16 05:26:42 +0000
committerDominik Stadler <centic@apache.org>2024-07-16 05:26:42 +0000
commit09fbfd5be45c7597cb1517a95e18b19429c47d58 (patch)
treecd8a2fce3c07d9e4f189b38323ea3dd0653ec900 /poi/src/main/java
parent9456261cba0d0b0cb77e40f38fcc42c1dfd169b4 (diff)
downloadpoi-09fbfd5be45c7597cb1517a95e18b19429c47d58.tar.gz
poi-09fbfd5be45c7597cb1517a95e18b19429c47d58.zip
Bug 66425: Avoid exceptions found via poi-fuzz
Avoid a possible OutOfMemoryException with many child-records This avoids having too many children in EscherRecords, the limit of 100_000 is arbitrarily chosen and can be adjusted if needed Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=62924 and maybe others git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1919272 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'poi/src/main/java')
-rw-r--r--poi/src/main/java/org/apache/poi/ddf/EscherContainerRecord.java11
-rw-r--r--poi/src/main/java/org/apache/poi/ddf/EscherRecord.java18
-rw-r--r--poi/src/main/java/org/apache/poi/ddf/UnknownEscherRecord.java11
3 files changed, 40 insertions, 0 deletions
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 747dbde1a5..8a0e555736 100644
--- a/poi/src/main/java/org/apache/poi/ddf/EscherContainerRecord.java
+++ b/poi/src/main/java/org/apache/poi/ddf/EscherContainerRecord.java
@@ -208,6 +208,12 @@ public final class EscherContainerRecord extends EscherRecord implements Iterabl
if (childRecords == _childRecords) {
throw new IllegalStateException("Child records private data member has escaped");
}
+
+ if (childRecords.size() > MAX_NUMBER_OF_CHILDREN) {
+ throw new IllegalStateException("Cannot add more than " + MAX_NUMBER_OF_CHILDREN +
+ " child records, you can use 'EscherRecord.setMaxNumberOfChildren()' to increase the allow size");
+ }
+
_childRecords.clear();
_childRecords.addAll(childRecords);
}
@@ -261,6 +267,11 @@ public final class EscherContainerRecord extends EscherRecord implements Iterabl
* @param record the record to be added
*/
public void addChildRecord(EscherRecord record) {
+ if (_childRecords.size() >= MAX_NUMBER_OF_CHILDREN) {
+ throw new IllegalStateException("Cannot add more than " + MAX_NUMBER_OF_CHILDREN +
+ " child records, you can use 'EscherRecord.setMaxNumberOfChildren()' to increase the allow size");
+ }
+
_childRecords.add(record);
}
diff --git a/poi/src/main/java/org/apache/poi/ddf/EscherRecord.java b/poi/src/main/java/org/apache/poi/ddf/EscherRecord.java
index 3d9aeacca8..e633a92079 100644
--- a/poi/src/main/java/org/apache/poi/ddf/EscherRecord.java
+++ b/poi/src/main/java/org/apache/poi/ddf/EscherRecord.java
@@ -45,6 +45,10 @@ public abstract class EscherRecord implements Duplicatable, GenericRecord {
private short _options;
private short _recordId;
+ // arbitrarily selected; may need to increase
+ private static final int DEFAULT_MAX_NUMBER_OF_CHILDREN = 100_000;
+ protected static int MAX_NUMBER_OF_CHILDREN = DEFAULT_MAX_NUMBER_OF_CHILDREN;
+
/**
* Create a new instance
*/
@@ -367,4 +371,18 @@ public abstract class EscherRecord implements Duplicatable, GenericRecord {
@Override
public abstract EscherRecord copy();
+
+ /**
+ * @param length the max record length allowed for EscherArrayProperty
+ */
+ public static void setMaxNumberOfChildren(int length) {
+ MAX_NUMBER_OF_CHILDREN = length;
+ }
+
+ /**
+ * @return the max record length allowed for EscherArrayProperty
+ */
+ public static int getMaxNumberOfChildren() {
+ return MAX_NUMBER_OF_CHILDREN;
+ }
} \ No newline at end of file
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 a81286c5c7..67b6bc6317 100644
--- a/poi/src/main/java/org/apache/poi/ddf/UnknownEscherRecord.java
+++ b/poi/src/main/java/org/apache/poi/ddf/UnknownEscherRecord.java
@@ -160,6 +160,12 @@ public final class UnknownEscherRecord extends EscherRecord {
if (childRecords == _childRecords) {
return;
}
+
+ if (childRecords.size() > MAX_NUMBER_OF_CHILDREN) {
+ throw new IllegalStateException("Cannot add more than " + MAX_NUMBER_OF_CHILDREN +
+ " child records, you can use 'EscherRecord.setMaxNumberOfChildren()' to increase the allow size");
+ }
+
_childRecords.clear();
_childRecords.addAll(childRecords);
}
@@ -170,6 +176,11 @@ public final class UnknownEscherRecord extends EscherRecord {
}
public void addChildRecord(EscherRecord childRecord) {
+ if (_childRecords.size() >= MAX_NUMBER_OF_CHILDREN) {
+ throw new IllegalStateException("Cannot add more than " + MAX_NUMBER_OF_CHILDREN +
+ " child records, you can use 'EscherRecord.setMaxNumberOfChildren()' to increase the allow size");
+ }
+
getChildRecords().add( childRecord );
}