--- old/src/java.base/share/classes/java/util/Scanner.java 2016-10-07 16:00:16.552275108 -0700 +++ new/src/java.base/share/classes/java/util/Scanner.java 2016-10-07 16:00:16.282276153 -0700 @@ -1267,6 +1267,9 @@ // The next operation should occur in the specified radix but // the default is left untouched. private void setRadix(int radix) { + if ((radix < Character.MIN_RADIX) || (radix > Character.MAX_RADIX)) + throw new IllegalArgumentException("radix:"+radix); + if (this.radix != radix) { // Force rebuilding and recompilation of radix dependent patterns integerPattern = null; @@ -1811,10 +1814,15 @@ * interpreted as a byte value in the specified radix using the * {@link #nextByte} method. The scanner does not advance past any input. * + *

If the radix is less than {@link Character#MIN_RADIX Character.MIN_RADIX} + * or greater than {@link Character#MAX_RADIX Character.MAX_RADIX}, then an + * {@code IllegalArgumentException} is thrown. + * * @param radix the radix used to interpret the token as a byte value * @return true if and only if this scanner's next token is a valid * byte value * @throws IllegalStateException if this scanner is closed + * @throws IllegalArgumentException if the radix is out of range */ public boolean hasNextByte(int radix) { setRadix(radix); @@ -1869,6 +1877,10 @@ * {@link Byte#parseByte(String, int) Byte.parseByte} with the * specified radix. * + *

If the radix is less than {@link Character#MIN_RADIX Character.MIN_RADIX} + * or greater than {@link Character#MAX_RADIX Character.MAX_RADIX}, then an + * {@code IllegalArgumentException} is thrown. + * * @param radix the radix used to interpret the token as a byte value * @return the {@code byte} scanned from the input * @throws InputMismatchException @@ -1876,6 +1888,7 @@ * regular expression, or is out of range * @throws NoSuchElementException if input is exhausted * @throws IllegalStateException if this scanner is closed + * @throws IllegalArgumentException if the radix is out of range */ public byte nextByte(int radix) { // Check cached result @@ -1917,10 +1930,15 @@ * interpreted as a short value in the specified radix using the * {@link #nextShort} method. The scanner does not advance past any input. * + *

If the radix is less than {@link Character#MIN_RADIX Character.MIN_RADIX} + * or greater than {@link Character#MAX_RADIX Character.MAX_RADIX}, then an + * {@code IllegalArgumentException} is thrown. + * * @param radix the radix used to interpret the token as a short value * @return true if and only if this scanner's next token is a valid * short value in the specified radix * @throws IllegalStateException if this scanner is closed + * @throws IllegalArgumentException if the radix is out of range */ public boolean hasNextShort(int radix) { setRadix(radix); @@ -1975,6 +1993,10 @@ * {@link Short#parseShort(String, int) Short.parseShort} with the * specified radix. * + *

If the radix is less than {@link Character#MIN_RADIX Character.MIN_RADIX} + * or greater than {@link Character#MAX_RADIX Character.MAX_RADIX}, then an + * {@code IllegalArgumentException} is thrown. + * * @param radix the radix used to interpret the token as a short value * @return the {@code short} scanned from the input * @throws InputMismatchException @@ -1982,6 +2004,7 @@ * regular expression, or is out of range * @throws NoSuchElementException if input is exhausted * @throws IllegalStateException if this scanner is closed + * @throws IllegalArgumentException if the radix is out of range */ public short nextShort(int radix) { // Check cached result @@ -2023,10 +2046,15 @@ * interpreted as an int value in the specified radix using the * {@link #nextInt} method. The scanner does not advance past any input. * + *

If the radix is less than {@link Character#MIN_RADIX Character.MIN_RADIX} + * or greater than {@link Character#MAX_RADIX Character.MAX_RADIX}, then an + * {@code IllegalArgumentException} is thrown. + * * @param radix the radix used to interpret the token as an int value * @return true if and only if this scanner's next token is a valid * int value * @throws IllegalStateException if this scanner is closed + * @throws IllegalArgumentException if the radix is out of range */ public boolean hasNextInt(int radix) { setRadix(radix); @@ -2105,6 +2133,10 @@ * {@link Integer#parseInt(String, int) Integer.parseInt} with the * specified radix. * + *

If the radix is less than {@link Character#MIN_RADIX Character.MIN_RADIX} + * or greater than {@link Character#MAX_RADIX Character.MAX_RADIX}, then an + * {@code IllegalArgumentException} is thrown. + * * @param radix the radix used to interpret the token as an int value * @return the {@code int} scanned from the input * @throws InputMismatchException @@ -2112,6 +2144,7 @@ * regular expression, or is out of range * @throws NoSuchElementException if input is exhausted * @throws IllegalStateException if this scanner is closed + * @throws IllegalArgumentException if the radix is out of range */ public int nextInt(int radix) { // Check cached result @@ -2153,10 +2186,15 @@ * interpreted as a long value in the specified radix using the * {@link #nextLong} method. The scanner does not advance past any input. * + *

If the radix is less than {@link Character#MIN_RADIX Character.MIN_RADIX} + * or greater than {@link Character#MAX_RADIX Character.MAX_RADIX}, then an + * {@code IllegalArgumentException} is thrown. + * * @param radix the radix used to interpret the token as a long value * @return true if and only if this scanner's next token is a valid * long value * @throws IllegalStateException if this scanner is closed + * @throws IllegalArgumentException if the radix is out of range */ public boolean hasNextLong(int radix) { setRadix(radix); @@ -2211,6 +2249,10 @@ * {@link Long#parseLong(String, int) Long.parseLong} with the * specified radix. * + *

If the radix is less than {@link Character#MIN_RADIX Character.MIN_RADIX} + * or greater than {@link Character#MAX_RADIX Character.MAX_RADIX}, then an + * {@code IllegalArgumentException} is thrown. + * * @param radix the radix used to interpret the token as an int value * @return the {@code long} scanned from the input * @throws InputMismatchException @@ -2218,6 +2260,7 @@ * regular expression, or is out of range * @throws NoSuchElementException if input is exhausted * @throws IllegalStateException if this scanner is closed + * @throws IllegalArgumentException if the radix is out of range */ public long nextLong(int radix) { // Check cached result @@ -2450,10 +2493,15 @@ * the {@link #nextBigInteger} method. The scanner does not advance past * any input. * + *

If the radix is less than {@link Character#MIN_RADIX Character.MIN_RADIX} + * or greater than {@link Character#MAX_RADIX Character.MAX_RADIX}, then an + * {@code IllegalArgumentException} is thrown. + * * @param radix the radix used to interpret the token as an integer * @return true if and only if this scanner's next token is a valid * {@code BigInteger} * @throws IllegalStateException if this scanner is closed + * @throws IllegalArgumentException if the radix is out of range */ public boolean hasNextBigInteger(int radix) { setRadix(radix); @@ -2504,6 +2552,10 @@ * java.math.BigInteger#BigInteger(java.lang.String) * BigInteger(String, int)} constructor with the specified radix. * + *

If the radix is less than {@link Character#MIN_RADIX Character.MIN_RADIX} + * or greater than {@link Character#MAX_RADIX Character.MAX_RADIX}, then an + * {@code IllegalArgumentException} is thrown. + * * @param radix the radix used to interpret the token * @return the {@code BigInteger} scanned from the input * @throws InputMismatchException @@ -2511,6 +2563,7 @@ * regular expression, or is out of range * @throws NoSuchElementException if the input is exhausted * @throws IllegalStateException if this scanner is closed + * @throws IllegalArgumentException if the radix is out of range */ public BigInteger nextBigInteger(int radix) { // Check cached result --- old/test/java/util/Scanner/ScanTest.java 2016-10-07 16:00:17.308272183 -0700 +++ new/test/java/util/Scanner/ScanTest.java 2016-10-07 16:00:17.029273262 -0700 @@ -24,7 +24,7 @@ /** * @test * @bug 4313885 4926319 4927634 5032610 5032622 5049968 5059533 6223711 6277261 6269946 6288823 - * 8072722 8139414 + * 8072722 8139414 8166261 * @summary Basic tests of java.util.Scanner methods * @key randomness * @modules jdk.localedata @@ -36,6 +36,7 @@ import java.nio.*; import java.text.*; import java.util.*; +import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.regex.*; import java.util.stream.*; @@ -79,6 +80,7 @@ resetTest(); streamCloseTest(); streamComodTest(); + outOfRangeRadixTest(); for (int j = 0; j < NUM_SOURCE_TYPES; j++) { hasNextTest(j); @@ -1509,6 +1511,48 @@ report("Reset test"); } + static List> methodWRList = Arrays.asList( + (s, r) -> s.hasNextByte(r), + (s, r) -> s.nextByte(r), + (s, r) -> s.hasNextShort(r), + (s, r) -> s.nextShort(r), + (s, r) -> s.hasNextInt(r), + (s, r) -> s.nextInt(r), + (s, r) -> s.hasNextLong(r), + (s, r) -> s.nextLong(r), + (s, r) -> s.hasNextBigInteger(r), + (s, r) -> s.nextBigInteger(r) + ); + + /* + * Test that setting the radix to an out of range value triggers + * an IllegalArgumentException + */ + public static void outOfRangeRadixTest() throws Exception { + int[] bad = new int[] { -1, 0, 1, 37, 38 }; + int[] good = IntStream.rangeClosed(Character.MIN_RADIX, Character.MAX_RADIX) + .toArray(); + + methodWRList.stream().forEach( m -> { + for (int r : bad) { + try (Scanner sc = new Scanner("10 10 10 10")) { + m.accept(sc, r); + failCount++; + } catch (IllegalArgumentException ise) {} + } + }); + methodWRList.stream().forEach( m -> { + for (int r : good) { + try (Scanner sc = new Scanner("10 10 10 10")) { + m.accept(sc, r); + } catch (Exception x) { + failCount++; + } + } + }); + report("Radix out of range test"); + } + /* * Test that closing the stream also closes the underlying Scanner. * The cases of attempting to open streams on a closed Scanner are