From 63402b104006064db04d03f342aacbc88b8b3eae Mon Sep 17 00:00:00 2001 From: dxbjavid Date: Tue, 2 Jun 2026 02:39:59 +0530 Subject: [PATCH] fix int overflow in pos + size bounds check in array vector constructors --- .../math4/legacy/linear/ArrayFieldVector.java | 10 ++++++---- .../math4/legacy/linear/ArrayRealVector.java | 10 ++++++---- .../legacy/linear/ArrayFieldVectorTest.java | 19 ++++++++++++++++++ .../legacy/linear/ArrayRealVectorTest.java | 20 +++++++++++++++++++ 4 files changed, 51 insertions(+), 8 deletions(-) diff --git a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/linear/ArrayFieldVector.java b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/linear/ArrayFieldVector.java index d7c5f6d8f0..9684458128 100644 --- a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/linear/ArrayFieldVector.java +++ b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/linear/ArrayFieldVector.java @@ -187,8 +187,9 @@ public ArrayFieldVector(Field field, T[] d, boolean copyArray) public ArrayFieldVector(T[] d, int pos, int size) throws NullArgumentException, NumberIsTooLargeException { NullArgumentException.check(d); - if (d.length < pos + size) { - throw new NumberIsTooLargeException(pos + size, d.length, true); + if (d.length < (long) pos + size) { + throw new NumberIsTooLargeException(Long.valueOf((long) pos + size), + Integer.valueOf(d.length), true); } field = d[0].getField(); data = MathArrays.buildArray(field, size); @@ -209,8 +210,9 @@ public ArrayFieldVector(T[] d, int pos, int size) public ArrayFieldVector(Field field, T[] d, int pos, int size) throws NullArgumentException, NumberIsTooLargeException { NullArgumentException.check(d); - if (d.length < pos + size) { - throw new NumberIsTooLargeException(pos + size, d.length, true); + if (d.length < (long) pos + size) { + throw new NumberIsTooLargeException(Long.valueOf((long) pos + size), + Integer.valueOf(d.length), true); } this.field = field; data = MathArrays.buildArray(field, size); diff --git a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/linear/ArrayRealVector.java b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/linear/ArrayRealVector.java index 3df56b0551..e539d194ab 100644 --- a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/linear/ArrayRealVector.java +++ b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/linear/ArrayRealVector.java @@ -121,8 +121,9 @@ public ArrayRealVector(double[] d, int pos, int size) if (d == null) { throw new NullArgumentException(); } - if (d.length < pos + size) { - throw new NumberIsTooLargeException(pos + size, d.length, true); + if (d.length < (long) pos + size) { + throw new NumberIsTooLargeException(Long.valueOf((long) pos + size), + Integer.valueOf(d.length), true); } data = new double[size]; System.arraycopy(d, pos, data, 0, size); @@ -155,8 +156,9 @@ public ArrayRealVector(Double[] d, int pos, int size) if (d == null) { throw new NullArgumentException(); } - if (d.length < pos + size) { - throw new NumberIsTooLargeException(pos + size, d.length, true); + if (d.length < (long) pos + size) { + throw new NumberIsTooLargeException(Long.valueOf((long) pos + size), + Integer.valueOf(d.length), true); } data = new double[size]; for (int i = pos; i < pos + size; i++) { diff --git a/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/linear/ArrayFieldVectorTest.java b/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/linear/ArrayFieldVectorTest.java index 4c1301efb8..77dcd70f84 100644 --- a/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/linear/ArrayFieldVectorTest.java +++ b/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/linear/ArrayFieldVectorTest.java @@ -24,6 +24,7 @@ import org.apache.commons.math4.legacy.core.FieldElement; import org.apache.commons.math4.legacy.TestUtils; import org.apache.commons.math4.legacy.exception.MathIllegalArgumentException; +import org.apache.commons.math4.legacy.exception.NumberIsTooLargeException; import org.apache.commons.math4.legacy.exception.NumberIsTooSmallException; import org.apache.commons.math4.legacy.exception.OutOfRangeException; import org.apache.commons.math4.legacy.core.dfp.Dfp; @@ -352,6 +353,24 @@ public void testConstructors() { Assert.assertEquals(Dfp25.of(1), v9.getEntry(7)); } + @Test + public void testConstructorPosSizeOverflow() { + // pos + size overflows int and wraps negative; the bounds check must + // still reject the range and report the true value in the exception. + try { + new ArrayFieldVector<>(vec4, Integer.MAX_VALUE, 1); + Assert.fail("NumberIsTooLargeException expected"); + } catch (NumberIsTooLargeException ex) { + Assert.assertEquals(1L + Integer.MAX_VALUE, ex.getArgument().longValue()); + } + try { + new ArrayFieldVector<>(Dfp25.getField(), vec4, Integer.MAX_VALUE, 1); + Assert.fail("NumberIsTooLargeException expected"); + } catch (NumberIsTooLargeException ex) { + Assert.assertEquals(1L + Integer.MAX_VALUE, ex.getArgument().longValue()); + } + } + @Test public void testDataInOut() { diff --git a/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/linear/ArrayRealVectorTest.java b/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/linear/ArrayRealVectorTest.java index 9d0e6aafe4..87c64380ef 100644 --- a/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/linear/ArrayRealVectorTest.java +++ b/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/linear/ArrayRealVectorTest.java @@ -17,6 +17,7 @@ package org.apache.commons.math4.legacy.linear; import org.apache.commons.math4.legacy.exception.MathIllegalArgumentException; +import org.apache.commons.math4.legacy.exception.NumberIsTooLargeException; import org.junit.Assert; import org.junit.Test; @@ -144,6 +145,25 @@ public void testConstructors() { Assert.assertEquals("testData is 1.0 ", 1.0, v14.getEntry(3), 0); } + @Test + public void testConstructorPosSizeOverflow() { + final double[] d = {1d, 2d, 3d}; + // pos + size overflows int and wraps negative; the bounds check must + // still reject the range and report the true value in the exception. + try { + new ArrayRealVector(d, Integer.MAX_VALUE, 1); + Assert.fail("NumberIsTooLargeException expected"); + } catch (NumberIsTooLargeException ex) { + Assert.assertEquals(1L + Integer.MAX_VALUE, ex.getArgument().longValue()); + } + try { + new ArrayRealVector(new Double[] {1d, 2d, 3d}, Integer.MAX_VALUE, 1); + Assert.fail("NumberIsTooLargeException expected"); + } catch (NumberIsTooLargeException ex) { + Assert.assertEquals(1L + Integer.MAX_VALUE, ex.getArgument().longValue()); + } + } + @Test public void testGetDataRef() { final double[] data = {1d, 2d, 3d, 4d};