This is an automated email from the ASF dual-hosted git repository.

centic pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/poi.git

commit d1f3f9489fc0f2fc32b109d39817ec29067ab127
Author: Dominik Stadler <[email protected]>
AuthorDate: Sun Jan 18 17:38:48 2026 +0100

    Add check for too large allocation in SharedFormulaGroup
    
    A malformed spreadsheet could trigger a very large allocation.
    
    Can be overruled by users via IOUtils.setByteArrayMaxOverride().
    
    Fixes https://issues.oss-fuzz.com/issues/476431391
---
 .../hssf/record/aggregates/SharedValueManager.java  |   9 ++++++++-
 poi/src/main/java/org/apache/poi/util/IOUtils.java  |   8 ++++----
 .../apache/poi/hssf/dev/TestBiffDrawingToXml.java   |   2 ++
 .../org/apache/poi/hssf/dev/TestBiffViewer.java     |   1 +
 .../org/apache/poi/hssf/dev/TestFormulaViewer.java  |   1 +
 .../org/apache/poi/hssf/dev/TestRecordLister.java   |   1 +
 ...ase-minimized-POIHSSFFuzzer-4734163573080064.xls | Bin 0 -> 7168 bytes
 test-data/spreadsheet/stress.xls                    | Bin 77312 -> 77312 bytes
 8 files changed, 17 insertions(+), 5 deletions(-)

diff --git 
a/poi/src/main/java/org/apache/poi/hssf/record/aggregates/SharedValueManager.java
 
b/poi/src/main/java/org/apache/poi/hssf/record/aggregates/SharedValueManager.java
index 0a22a74f67..44763597cb 100644
--- 
a/poi/src/main/java/org/apache/poi/hssf/record/aggregates/SharedValueManager.java
+++ 
b/poi/src/main/java/org/apache/poi/hssf/record/aggregates/SharedValueManager.java
@@ -31,6 +31,7 @@ import org.apache.poi.hssf.record.TableRecord;
 import org.apache.poi.ss.formula.ptg.ExpPtg;
 import org.apache.poi.hssf.util.CellRangeAddress8Bit;
 import org.apache.poi.ss.util.CellReference;
+import org.apache.poi.util.IOUtils;
 
 /**
  * Manages various auxiliary records while constructing a
@@ -42,6 +43,7 @@ import org.apache.poi.ss.util.CellReference;
  * </ul>
  */
 public final class SharedValueManager {
+    private static final int MAX_NUMBER_AGGS = 10_000;
 
     private static final class SharedFormulaGroup {
         private final SharedFormulaRecord _sfr;
@@ -63,7 +65,12 @@ public final class SharedValueManager {
             _firstCell = firstCell;
             int width = sfr.getLastColumn() - sfr.getFirstColumn() + 1;
             int height = sfr.getLastRow() - sfr.getFirstRow() + 1;
-            _frAggs = new FormulaRecordAggregate[width * height];
+
+            // ensure we do not try to initialize a very large amount of 
formula-record-aggregates
+            int allocateSize = width * height;
+            IOUtils.safelyAllocateCheck(allocateSize, MAX_NUMBER_AGGS);
+
+            _frAggs = new FormulaRecordAggregate[allocateSize];
             _numberOfFormulas = 0;
         }
 
diff --git a/poi/src/main/java/org/apache/poi/util/IOUtils.java 
b/poi/src/main/java/org/apache/poi/util/IOUtils.java
index 9dc7ee80c5..f7abf94319 100644
--- a/poi/src/main/java/org/apache/poi/util/IOUtils.java
+++ b/poi/src/main/java/org/apache/poi/util/IOUtils.java
@@ -460,7 +460,7 @@ public final class IOUtils {
     public static long copy(InputStream srcStream, File destFile) throws 
IOException {
         File destDirectory = destFile.getParentFile();
         if (!(destDirectory.exists() || destDirectory.mkdirs())) {
-            throw new IllegalStateException("Can't create destination 
directory: "+destDirectory);
+            throw new IllegalStateException("Can't create destination 
directory: " + destDirectory);
         }
         try (OutputStream destStream = 
Files.newOutputStream(destFile.toPath())) {
             return IOUtils.copy(srcStream, destStream);
@@ -581,7 +581,7 @@ public final class IOUtils {
             throw new RecordFormatException("Can't allocate an array of length 
< 0, but had " + length + " and " + maxLength);
         }
         if (length > (long)Integer.MAX_VALUE) {
-            throw new RecordFormatException("Can't allocate an array > 
"+Integer.MAX_VALUE);
+            throw new RecordFormatException("Can't allocate an array > " + 
Integer.MAX_VALUE);
         }
         checkLength(length, maxLength);
     }
@@ -643,7 +643,7 @@ public final class IOUtils {
         throw new RecordFormatException(String.format(Locale.ROOT, "Tried to 
allocate an array of length %,d" +
                         ", but the maximum length for this record type is 
%,d.%n" +
                         "If the file is not corrupt and not large, please open 
an issue on bugzilla to request %n" +
-                        "increasing the maximum allowable size for this record 
type.%n"+
+                        "increasing the maximum allowable size for this record 
type.%n" +
                         "You can set a higher override value with 
IOUtils.setByteArrayMaxOverride()", length, maxLength));
     }
 
@@ -651,7 +651,7 @@ public final class IOUtils {
         throw new RecordFormatException(String.format(Locale.ROOT, "Tried to 
read data but the maximum length " +
                 "for this record type is %,d.%n" +
                 "If the file is not corrupt and not large, please open an 
issue on bugzilla to request %n" +
-                "increasing the maximum allowable size for this record 
type.%n"+
+                "increasing the maximum allowable size for this record 
type.%n" +
                 "You can set a higher override value with 
IOUtils.setByteArrayMaxOverride()", maxLength));
     }
 }
diff --git 
a/poi/src/test/java/org/apache/poi/hssf/dev/TestBiffDrawingToXml.java 
b/poi/src/test/java/org/apache/poi/hssf/dev/TestBiffDrawingToXml.java
index b9e7d3050a..1c17bb1506 100644
--- a/poi/src/test/java/org/apache/poi/hssf/dev/TestBiffDrawingToXml.java
+++ b/poi/src/test/java/org/apache/poi/hssf/dev/TestBiffDrawingToXml.java
@@ -36,6 +36,7 @@ import org.apache.poi.hssf.usermodel.HSSFPatriarch;
 import org.apache.poi.hssf.usermodel.HSSFSheet;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.util.RecordFormatException;
 import org.apache.poi.util.StringUtil;
 import org.apache.tools.ant.util.NullOutputStream;
 
@@ -57,6 +58,7 @@ class TestBiffDrawingToXml extends BaseTestIteratingXLS {
         
excludes.put("clusterfuzz-testcase-minimized-POIHSSFFuzzer-5436547081830400.xls",
 IllegalArgumentException.class);
         
excludes.put("clusterfuzz-testcase-minimized-POIHSSFFuzzer-5889658057523200.xls",
 IndexOutOfBoundsException.class);
         
excludes.put("clusterfuzz-testcase-minimized-POIHSSFFuzzer-4977868385681408.xls",
 IllegalArgumentException.class);
+        
excludes.put("clusterfuzz-testcase-minimized-POIHSSFFuzzer-4734163573080064.xls",
 RecordFormatException.class);
         return excludes;
     }
 
diff --git a/poi/src/test/java/org/apache/poi/hssf/dev/TestBiffViewer.java 
b/poi/src/test/java/org/apache/poi/hssf/dev/TestBiffViewer.java
index 77f41647b7..33f28455a8 100644
--- a/poi/src/test/java/org/apache/poi/hssf/dev/TestBiffViewer.java
+++ b/poi/src/test/java/org/apache/poi/hssf/dev/TestBiffViewer.java
@@ -48,6 +48,7 @@ class TestBiffViewer extends BaseTestIteratingXLS {
         
excludes.put("clusterfuzz-testcase-minimized-POIHSSFFuzzer-6137883240824832.xls",
 IndexOutOfBoundsException.class);
         
excludes.put("clusterfuzz-testcase-minimized-POIHSSFFuzzer-6483562584932352.xls",
 IndexOutOfBoundsException.class);
         
excludes.put("clusterfuzz-testcase-minimized-POIHSSFFuzzer-5816431116615680.xls",
 RecordFormatException.class);
+        
excludes.put("clusterfuzz-testcase-minimized-POIHSSFFuzzer-4734163573080064.xls",
 IndexOutOfBoundsException.class);
 
         return excludes;
     }
diff --git a/poi/src/test/java/org/apache/poi/hssf/dev/TestFormulaViewer.java 
b/poi/src/test/java/org/apache/poi/hssf/dev/TestFormulaViewer.java
index 29b31dec81..994a09e8ea 100644
--- a/poi/src/test/java/org/apache/poi/hssf/dev/TestFormulaViewer.java
+++ b/poi/src/test/java/org/apache/poi/hssf/dev/TestFormulaViewer.java
@@ -45,6 +45,7 @@ class TestFormulaViewer extends BaseTestIteratingXLS {
         excludes.put("43493.xls", 
RecordInputStream.LeftoverDataException.class);  // HSSFWorkbook cannot open it 
as well
         excludes.put("44958_1.xls", 
RecordInputStream.LeftoverDataException.class);
         excludes.put("protected_66115.xls", EncryptedDocumentException.class);
+        
excludes.put("clusterfuzz-testcase-minimized-POIHSSFFuzzer-4734163573080064.xls",
 IndexOutOfBoundsException.class);
         return excludes;
     }
 
diff --git a/poi/src/test/java/org/apache/poi/hssf/dev/TestRecordLister.java 
b/poi/src/test/java/org/apache/poi/hssf/dev/TestRecordLister.java
index d244f3ff5a..eab59c339f 100644
--- a/poi/src/test/java/org/apache/poi/hssf/dev/TestRecordLister.java
+++ b/poi/src/test/java/org/apache/poi/hssf/dev/TestRecordLister.java
@@ -51,6 +51,7 @@ class TestRecordLister extends BaseTestIteratingXLS {
         
excludes.put("clusterfuzz-testcase-minimized-POIHSSFFuzzer-6137883240824832.xls",
 RecordFormatException.class);
         
excludes.put("clusterfuzz-testcase-minimized-POIHSSFFuzzer-6483562584932352.xls",
 RecordFormatException.class);
         
excludes.put("clusterfuzz-testcase-minimized-POIHSSFFuzzer-5816431116615680.xls",
 RecordFormatException.class);
+        
excludes.put("clusterfuzz-testcase-minimized-POIHSSFFuzzer-4734163573080064.xls",
 IndexOutOfBoundsException.class);
 
         return excludes;
     }
diff --git 
a/test-data/spreadsheet/clusterfuzz-testcase-minimized-POIHSSFFuzzer-4734163573080064.xls
 
b/test-data/spreadsheet/clusterfuzz-testcase-minimized-POIHSSFFuzzer-4734163573080064.xls
new file mode 100644
index 0000000000..26f9566e23
Binary files /dev/null and 
b/test-data/spreadsheet/clusterfuzz-testcase-minimized-POIHSSFFuzzer-4734163573080064.xls
 differ
diff --git a/test-data/spreadsheet/stress.xls b/test-data/spreadsheet/stress.xls
index 7eca50c81b..1539461dde 100644
Binary files a/test-data/spreadsheet/stress.xls and 
b/test-data/spreadsheet/stress.xls differ


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to