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]
