diff --git a/math/src/main/java/com/powsybl/math/matrix/DenseMatrix.java b/math/src/main/java/com/powsybl/math/matrix/DenseMatrix.java index 4b123e23c1a..4d14277056b 100644 --- a/math/src/main/java/com/powsybl/math/matrix/DenseMatrix.java +++ b/math/src/main/java/com/powsybl/math/matrix/DenseMatrix.java @@ -7,6 +7,8 @@ package com.powsybl.math.matrix; import com.google.common.base.Strings; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.PrintStream; import java.nio.ByteBuffer; @@ -22,6 +24,10 @@ */ public class DenseMatrix extends AbstractMatrix { + private static final Logger LOGGER = LoggerFactory.getLogger(DenseMatrix.class); + + public static final int MAX_ELEMENT_COUNT = Integer.MAX_VALUE / Double.BYTES; + /** * Dense element implementation. * An element in a dense matrix is defined by its row index and column index. @@ -61,8 +67,15 @@ public void add(double value) { private final ByteBuffer buffer; private static ByteBuffer createBuffer(int rowCount, int columnCount) { - return ByteBuffer.allocateDirect(rowCount * columnCount * Double.BYTES) - .order(ByteOrder.LITTLE_ENDIAN); + try { + int capacity = Math.multiplyExact(Math.multiplyExact(rowCount, columnCount), Double.BYTES); + return ByteBuffer.allocateDirect(capacity) + .order(ByteOrder.LITTLE_ENDIAN); + } catch (ArithmeticException e) { + LOGGER.error(e.toString(), e); + throw new MatrixException("Too many elements for a dense matrix, maximum allowed is " + + MAX_ELEMENT_COUNT); + } } public DenseMatrix(int rowCount, int columnCount, double[] values) { diff --git a/math/src/test/java/com/powsybl/math/matrix/DenseMatrixTest.java b/math/src/test/java/com/powsybl/math/matrix/DenseMatrixTest.java index 5f6b2039544..4329a36a021 100644 --- a/math/src/test/java/com/powsybl/math/matrix/DenseMatrixTest.java +++ b/math/src/test/java/com/powsybl/math/matrix/DenseMatrixTest.java @@ -7,6 +7,7 @@ package com.powsybl.math.matrix; import com.google.common.collect.ImmutableList; +import com.powsybl.commons.PowsyblException; import org.junit.jupiter.api.Test; import java.io.IOException; @@ -107,4 +108,11 @@ void testDenseMultiplication() { assertEquals(0, c.get(0, 1), EPSILON); assertEquals(0, c.get(1, 1), EPSILON); } + + @Test + void testTooManyElementDenseMatrix() { + PowsyblException e = assertThrows(PowsyblException.class, () -> new DenseMatrix(100000, 10000)); + assertEquals("Too many elements for a dense matrix, maximum allowed is 268435455", e.getMessage()); + assertEquals(268435455, DenseMatrix.MAX_ELEMENT_COUNT); + } }