mirror of
https://github.com/apache/poi.git
synced 2026-02-27 20:40:08 +08:00
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:
parent
d1f0a88ea1
commit
d1f3f9489f
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -460,7 +460,7 @@ public final class IOUtils {
|
|||||||
public static long copy(InputStream srcStream, File destFile) throws IOException {
|
public static long copy(InputStream srcStream, File destFile) throws IOException {
|
||||||
File destDirectory = destFile.getParentFile();
|
File destDirectory = destFile.getParentFile();
|
||||||
if (!(destDirectory.exists() || destDirectory.mkdirs())) {
|
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())) {
|
try (OutputStream destStream = Files.newOutputStream(destFile.toPath())) {
|
||||||
return IOUtils.copy(srcStream, destStream);
|
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);
|
throw new RecordFormatException("Can't allocate an array of length < 0, but had " + length + " and " + maxLength);
|
||||||
}
|
}
|
||||||
if (length > (long)Integer.MAX_VALUE) {
|
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);
|
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" +
|
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" +
|
", 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" +
|
"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));
|
"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 " +
|
throw new RecordFormatException(String.format(Locale.ROOT, "Tried to read data but the maximum length " +
|
||||||
"for this record type is %,d.%n" +
|
"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" +
|
"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));
|
"You can set a higher override value with IOUtils.setByteArrayMaxOverride()", maxLength));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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.
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user