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
This commit is contained in:
Dominik Stadler 2026-01-18 17:38:48 +01:00
parent d1f0a88ea1
commit d1f3f9489f
8 changed files with 17 additions and 5 deletions

View File

@ -31,6 +31,7 @@ import org.apache.poi.hssf.record.TableRecord;
import org.apache.poi.ss.formula.ptg.ExpPtg; import org.apache.poi.ss.formula.ptg.ExpPtg;
import org.apache.poi.hssf.util.CellRangeAddress8Bit; import org.apache.poi.hssf.util.CellRangeAddress8Bit;
import org.apache.poi.ss.util.CellReference; import org.apache.poi.ss.util.CellReference;
import org.apache.poi.util.IOUtils;
/** /**
* Manages various auxiliary records while constructing a * Manages various auxiliary records while constructing a
@ -42,6 +43,7 @@ import org.apache.poi.ss.util.CellReference;
* </ul> * </ul>
*/ */
public final class SharedValueManager { public final class SharedValueManager {
private static final int MAX_NUMBER_AGGS = 10_000;
private static final class SharedFormulaGroup { private static final class SharedFormulaGroup {
private final SharedFormulaRecord _sfr; private final SharedFormulaRecord _sfr;
@ -63,7 +65,12 @@ public final class SharedValueManager {
_firstCell = firstCell; _firstCell = firstCell;
int width = sfr.getLastColumn() - sfr.getFirstColumn() + 1; int width = sfr.getLastColumn() - sfr.getFirstColumn() + 1;
int height = sfr.getLastRow() - sfr.getFirstRow() + 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; _numberOfFormulas = 0;
} }

View File

@ -36,6 +36,7 @@ import org.apache.poi.hssf.usermodel.HSSFPatriarch;
import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.util.RecordFormatException;
import org.apache.poi.util.StringUtil; import org.apache.poi.util.StringUtil;
import org.apache.tools.ant.util.NullOutputStream; 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-5436547081830400.xls", IllegalArgumentException.class);
excludes.put("clusterfuzz-testcase-minimized-POIHSSFFuzzer-5889658057523200.xls", IndexOutOfBoundsException.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-4977868385681408.xls", IllegalArgumentException.class);
excludes.put("clusterfuzz-testcase-minimized-POIHSSFFuzzer-4734163573080064.xls", RecordFormatException.class);
return excludes; return excludes;
} }

View File

@ -48,6 +48,7 @@ class TestBiffViewer extends BaseTestIteratingXLS {
excludes.put("clusterfuzz-testcase-minimized-POIHSSFFuzzer-6137883240824832.xls", IndexOutOfBoundsException.class); 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-6483562584932352.xls", IndexOutOfBoundsException.class);
excludes.put("clusterfuzz-testcase-minimized-POIHSSFFuzzer-5816431116615680.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; return excludes;
} }

View File

@ -45,6 +45,7 @@ class TestFormulaViewer extends BaseTestIteratingXLS {
excludes.put("43493.xls", RecordInputStream.LeftoverDataException.class); // HSSFWorkbook cannot open it as well excludes.put("43493.xls", RecordInputStream.LeftoverDataException.class); // HSSFWorkbook cannot open it as well
excludes.put("44958_1.xls", RecordInputStream.LeftoverDataException.class); excludes.put("44958_1.xls", RecordInputStream.LeftoverDataException.class);
excludes.put("protected_66115.xls", EncryptedDocumentException.class); excludes.put("protected_66115.xls", EncryptedDocumentException.class);
excludes.put("clusterfuzz-testcase-minimized-POIHSSFFuzzer-4734163573080064.xls", IndexOutOfBoundsException.class);
return excludes; return excludes;
} }

View File

@ -51,6 +51,7 @@ class TestRecordLister extends BaseTestIteratingXLS {
excludes.put("clusterfuzz-testcase-minimized-POIHSSFFuzzer-6137883240824832.xls", RecordFormatException.class); 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-6483562584932352.xls", RecordFormatException.class);
excludes.put("clusterfuzz-testcase-minimized-POIHSSFFuzzer-5816431116615680.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; return excludes;
} }

Binary file not shown.