diff --git a/commons-math-legacy-core/src/main/java/org/apache/commons/math4/legacy/core/MathArrays.java b/commons-math-legacy-core/src/main/java/org/apache/commons/math4/legacy/core/MathArrays.java index 8d10992dae..425d3292e6 100644 --- a/commons-math-legacy-core/src/main/java/org/apache/commons/math4/legacy/core/MathArrays.java +++ b/commons-math-legacy-core/src/main/java/org/apache/commons/math4/legacy/core/MathArrays.java @@ -962,9 +962,9 @@ public static boolean verifyValues(final double[] values, final int begin, throw new NotPositiveException(LocalizedFormats.LENGTH, Integer.valueOf(length)); } - if (begin + length > values.length) { + if ((long) begin + length > values.length) { throw new NumberIsTooLargeException(LocalizedFormats.SUBARRAY_ENDS_AFTER_ARRAY_END, - Integer.valueOf(begin + length), Integer.valueOf(values.length), true); + Long.valueOf((long) begin + length), Integer.valueOf(values.length), true); } return !(length == 0 && !allowEmpty); diff --git a/commons-math-legacy-core/src/test/java/org/apache/commons/math4/legacy/core/MathArraysTest.java b/commons-math-legacy-core/src/test/java/org/apache/commons/math4/legacy/core/MathArraysTest.java index d57dc068c7..927e93f5c9 100644 --- a/commons-math-legacy-core/src/test/java/org/apache/commons/math4/legacy/core/MathArraysTest.java +++ b/commons-math-legacy-core/src/test/java/org/apache/commons/math4/legacy/core/MathArraysTest.java @@ -30,6 +30,7 @@ import org.apache.commons.math4.legacy.exception.NotANumberException; import org.apache.commons.math4.legacy.exception.NotPositiveException; import org.apache.commons.math4.legacy.exception.NotStrictlyPositiveException; +import org.apache.commons.math4.legacy.exception.NumberIsTooLargeException; import org.apache.commons.math4.legacy.exception.NullArgumentException; import org.apache.commons.math4.legacy.exception.NotFiniteNumberException; import org.apache.commons.math4.core.jdkmath.JdkMath; @@ -630,6 +631,18 @@ public void testVerifyValuesPositive() { Assert.assertTrue(MathArrays.verifyValues(singletonArray, 0, 0, true)); } + @Test + public void testVerifyValuesOverflow() { + // begin + length overflows int; the check must not be bypassed and the + // reported end position must be the true (long) value, not the wrapped int. + try { + MathArrays.verifyValues(testArray, 1, Integer.MAX_VALUE); + Assert.fail("Expecting NumberIsTooLargeException"); + } catch (NumberIsTooLargeException ex) { + Assert.assertEquals(1L + Integer.MAX_VALUE, ex.getArgument().longValue()); + } + } + @Test public void testVerifyValuesNegative() { final double[] nullArray = null; diff --git a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/AbstractUnivariateStatistic.java b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/AbstractUnivariateStatistic.java index 41618fdf9d..03a1766f7a 100644 --- a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/AbstractUnivariateStatistic.java +++ b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/stat/descriptive/AbstractUnivariateStatistic.java @@ -109,9 +109,9 @@ public void setData(final double[] values, final int begin, final int length) throw new NotPositiveException(LocalizedFormats.LENGTH, length); } - if (begin + length > values.length) { + if ((long) begin + length > values.length) { throw new NumberIsTooLargeException(LocalizedFormats.SUBARRAY_ENDS_AFTER_ARRAY_END, - begin + length, values.length, true); + (long) begin + length, values.length, true); } storedData = new double[length]; System.arraycopy(values, begin, storedData, 0, length); diff --git a/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/stat/descriptive/AbstractUnivariateStatisticTest.java b/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/stat/descriptive/AbstractUnivariateStatisticTest.java new file mode 100644 index 0000000000..be9511eda5 --- /dev/null +++ b/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/stat/descriptive/AbstractUnivariateStatisticTest.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.math4.legacy.stat.descriptive; + +import org.apache.commons.math4.legacy.exception.NumberIsTooLargeException; +import org.junit.Assert; +import org.junit.Test; + +/** + * Test cases for {@link AbstractUnivariateStatistic}. + */ +public class AbstractUnivariateStatisticTest { + + /** Minimal concrete implementation for exercising the base class. */ + private static final class Stat extends AbstractUnivariateStatistic { + @Override + public double evaluate(double[] values, int begin, int length) { + return 0; + } + + @Override + public UnivariateStatistic copy() { + return new Stat(); + } + } + + @Test + public void testSetDataOverflow() { + // begin + length overflows int; the check must not be bypassed and the + // reported end position must be the true (long) value, not the wrapped int. + try { + new Stat().setData(new double[10], 1, Integer.MAX_VALUE); + Assert.fail("Expecting NumberIsTooLargeException"); + } catch (NumberIsTooLargeException ex) { + Assert.assertEquals(1L + Integer.MAX_VALUE, ex.getArgument().longValue()); + } + } +}