diff --git a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/random/SobolSequenceGenerator.java b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/random/SobolSequenceGenerator.java index bf4a2a9acf..58d1d0d222 100644 --- a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/random/SobolSequenceGenerator.java +++ b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/random/SobolSequenceGenerator.java @@ -205,6 +205,9 @@ private int initFromStream(final InputStream is) throws IOException { dim = Integer.parseInt(st.nextToken()); if (dim >= 2 && dim <= dimension) { // we have found the right dimension final int s = Integer.parseInt(st.nextToken()); + if (s < 1 || s > BITS) { + throw new MathParseException(line, lineNumber); + } final int a = Integer.parseInt(st.nextToken()); final int[] m = new int[s + 1]; for (int i = 1; i <= s; i++) { diff --git a/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/random/SobolSequenceGeneratorTest.java b/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/random/SobolSequenceGeneratorTest.java index 39f1f4029b..be14c9fb10 100644 --- a/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/random/SobolSequenceGeneratorTest.java +++ b/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/random/SobolSequenceGeneratorTest.java @@ -18,8 +18,11 @@ import org.junit.Assert; +import java.io.ByteArrayInputStream; import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import org.apache.commons.math4.legacy.exception.MathParseException; import org.apache.commons.math4.legacy.exception.OutOfRangeException; import org.junit.Before; import org.junit.Test; @@ -91,6 +94,24 @@ public void testConstructor2() throws Exception{ } } + @Test + public void testConstructorDegreeTooLarge() { + // direction number degree s = 60 exceeds the BITS (52) entries available + // per dimension; without range validation this indexes past direction[d] + // and throws ArrayIndexOutOfBoundsException instead of MathParseException. + final StringBuilder sb = new StringBuilder("d s a m_i\n2 60 0"); + for (int i = 0; i < 60; i++) { + sb.append(" 1"); + } + final InputStream is = new ByteArrayInputStream(sb.toString().getBytes(StandardCharsets.UTF_8)); + try { + new SobolSequenceGenerator(2, is); + Assert.fail("an exception should have been thrown"); + } catch (MathParseException e) { + // expected + } + } + @Test public void testSkip() { double[] result = generator.skipTo(5);