8055251: Re-examine Integer.parseInt and Long.parseLong methods
authoralanb
Wed, 10 Sep 2014 13:51:17 +0100
changeset 26462 d6d34934be12
parent 26461 47fae3bfe8ed
child 26463 d9800c220d8b
8055251: Re-examine Integer.parseInt and Long.parseLong methods Reviewed-by: alanb Contributed-by: claes.redestad@oracle.com
jdk/src/java.base/share/classes/java/lang/Integer.java
jdk/src/java.base/share/classes/java/lang/Long.java
jdk/src/java.base/share/classes/java/time/Duration.java
jdk/src/java.base/share/classes/java/time/Period.java
jdk/src/java.base/share/classes/java/util/UUID.java
jdk/test/java/lang/Integer/ParsingTest.java
jdk/test/java/lang/Integer/Unsigned.java
jdk/test/java/lang/Long/ParsingTest.java
jdk/test/java/lang/Long/Unsigned.java
--- a/jdk/src/java.base/share/classes/java/lang/Integer.java	Wed Sep 10 10:37:12 2014 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/Integer.java	Wed Sep 10 13:51:17 2014 +0100
@@ -595,37 +595,6 @@
     /**
      * Parses the {@link CharSequence} argument as a signed {@code int} in the
      * specified {@code radix}, beginning at the specified {@code beginIndex}
-     * and extending to the end of the sequence.
-     *
-     * <p>The method does not take steps to guard against the
-     * {@code CharSequence} being mutated while parsing.
-     *
-     * @param      s   the {@code CharSequence} containing the {@code int}
-     *                  representation to be parsed
-     * @param      radix   the radix to be used while parsing {@code s}.
-     * @param      beginIndex   the beginning index, inclusive.
-     * @return     the signed {@code int} represented by the subsequence in
-     *             the specified radix.
-     * @throws     NullPointerException  if {@code s} is null.
-     * @throws     IndexOutOfBoundsException  if {@code beginIndex} is
-     *             negative, or if {@code beginIndex} is greater than
-     *             {@code s.length()}.
-     * @throws     NumberFormatException  if the {@code CharSequence} does not
-     *             contain a parsable {@code int} in the specified
-     *             {@code radix}, or if {@code radix} is either smaller than
-     *             {@link java.lang.Character#MIN_RADIX} or larger than
-     *             {@link java.lang.Character#MAX_RADIX}.
-     * @since  1.9
-     */
-    public static int parseInt(CharSequence s, int radix, int beginIndex)
-                throws NumberFormatException {
-        // forces an implicit null check of s
-        return parseInt(s, radix, beginIndex, s.length());
-    }
-
-    /**
-     * Parses the {@link CharSequence} argument as a signed {@code int} in the
-     * specified {@code radix}, beginning at the specified {@code beginIndex}
      * and extending to {@code endIndex - 1}.
      *
      * <p>The method does not take steps to guard against the
@@ -633,9 +602,9 @@
      *
      * @param      s   the {@code CharSequence} containing the {@code int}
      *                  representation to be parsed
-     * @param      radix   the radix to be used while parsing {@code s}.
      * @param      beginIndex   the beginning index, inclusive.
      * @param      endIndex     the ending index, exclusive.
+     * @param      radix   the radix to be used while parsing {@code s}.
      * @return     the signed {@code int} represented by the subsequence in
      *             the specified radix.
      * @throws     NullPointerException  if {@code s} is null.
@@ -650,7 +619,7 @@
      *             {@link java.lang.Character#MAX_RADIX}.
      * @since  1.9
      */
-    public static int parseInt(CharSequence s, int radix, int beginIndex, int endIndex)
+    public static int parseInt(CharSequence s, int beginIndex, int endIndex, int radix)
                 throws NumberFormatException {
         s = Objects.requireNonNull(s);
 
@@ -690,7 +659,7 @@
             int result = 0;
             while (i < endIndex) {
                 // Accumulating negatively avoids surprises near MAX_VALUE
-                int digit = Character.digit(s.charAt(i++), radix);
+                int digit = Character.digit(s.charAt(i), radix);
                 if (digit < 0 || result < multmin) {
                     throw NumberFormatException.forCharSequence(s, beginIndex,
                             endIndex, i);
@@ -700,6 +669,7 @@
                     throw NumberFormatException.forCharSequence(s, beginIndex,
                             endIndex, i);
                 }
+                i++;
                 result -= digit;
             }
             return negative ? result : -result;
@@ -808,37 +778,6 @@
     /**
      * Parses the {@link CharSequence} argument as an unsigned {@code int} in
      * the specified {@code radix}, beginning at the specified
-     * {@code beginIndex} and extending to the end of the sequence.
-     *
-     * <p>The method does not take steps to guard against the
-     * {@code CharSequence} being mutated while parsing.
-     *
-     * @param      s   the {@code CharSequence} containing the unsigned
-     *                 {@code int} representation to be parsed
-     * @param      radix   the radix to be used while parsing {@code s}.
-     * @param      beginIndex   the beginning index, inclusive.
-     * @return     the unsigned {@code int} represented by the subsequence in
-     *             the specified radix.
-     * @throws     NullPointerException  if {@code s} is null.
-     * @throws     IndexOutOfBoundsException  if {@code beginIndex} is
-     *             negative, or if {@code beginIndex} is greater than
-     *             {@code s.length()}.
-     * @throws     NumberFormatException  if the {@code CharSequence} does not
-     *             contain a parsable unsigned {@code int} in the specified
-     *             {@code radix}, or if {@code radix} is either smaller than
-     *             {@link java.lang.Character#MIN_RADIX} or larger than
-     *             {@link java.lang.Character#MAX_RADIX}.
-     * @since  1.9
-     */
-    public static int parseUnsignedInt(CharSequence s, int radix, int beginIndex)
-                throws NumberFormatException {
-        // forces an implicit null check of s
-        return parseUnsignedInt(s, radix, beginIndex, s.length());
-    }
-
-    /**
-     * Parses the {@link CharSequence} argument as an unsigned {@code int} in
-     * the specified {@code radix}, beginning at the specified
      * {@code beginIndex} and extending to {@code endIndex - 1}.
      *
      * <p>The method does not take steps to guard against the
@@ -846,9 +785,9 @@
      *
      * @param      s   the {@code CharSequence} containing the unsigned
      *                 {@code int} representation to be parsed
-     * @param      radix   the radix to be used while parsing {@code s}.
      * @param      beginIndex   the beginning index, inclusive.
      * @param      endIndex     the ending index, exclusive.
+     * @param      radix   the radix to be used while parsing {@code s}.
      * @return     the unsigned {@code int} represented by the subsequence in
      *             the specified radix.
      * @throws     NullPointerException  if {@code s} is null.
@@ -863,7 +802,7 @@
      *             {@link java.lang.Character#MAX_RADIX}.
      * @since  1.9
      */
-    public static int parseUnsignedInt(CharSequence s, int radix, int beginIndex, int endIndex)
+    public static int parseUnsignedInt(CharSequence s, int beginIndex, int endIndex, int radix)
                 throws NumberFormatException {
         s = Objects.requireNonNull(s);
 
@@ -881,9 +820,9 @@
             } else {
                 if (len <= 5 || // Integer.MAX_VALUE in Character.MAX_RADIX is 6 digits
                         (radix == 10 && len <= 9)) { // Integer.MAX_VALUE in base 10 is 10 digits
-                    return parseInt(s, radix, start, start + len);
+                    return parseInt(s, start, start + len, radix);
                 } else {
-                    long ell = Long.parseLong(s, radix, start, start + len);
+                    long ell = Long.parseLong(s, start, start + len, radix);
                     if ((ell & 0xffff_ffff_0000_0000L) == 0) {
                         return (int) ell;
                     } else {
--- a/jdk/src/java.base/share/classes/java/lang/Long.java	Wed Sep 10 10:37:12 2014 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/Long.java	Wed Sep 10 13:51:17 2014 +0100
@@ -606,37 +606,6 @@
 
     /**
      * Parses the {@link CharSequence} argument as a signed {@code long} in
-     * the specified {@code radix}, beginning at the specified {@code beginIndex}
-     * and extending to the end of the sequence.
-     *
-     * <p>The method does not take steps to guard against the
-     * {@code CharSequence} being mutated while parsing.
-     *
-     * @param      s   the {@code CharSequence} containing the {@code long}
-     *                  representation to be parsed
-     * @param      radix   the radix to be used while parsing {@code s}.
-     * @param      beginIndex   the beginning index, inclusive.
-     * @return     the signed {@code long} represented by the subsequence in
-     *             the specified radix.
-     * @throws     NullPointerException  if {@code s} is null.
-     * @throws     IndexOutOfBoundsException  if {@code beginIndex} is
-     *             negative, or if {@code beginIndex} is greater than
-     *             {@code s.length()}.
-     * @throws     NumberFormatException  if the {@code CharSequence} does not
-     *             contain a parsable {@code long} in the specified
-     *             {@code radix}, or if {@code radix} is either smaller than
-     *             {@link java.lang.Character#MIN_RADIX} or larger than
-     *             {@link java.lang.Character#MAX_RADIX}.
-     * @since  1.9
-     */
-    public static long parseLong(CharSequence s, int radix, int beginIndex)
-            throws NumberFormatException {
-        // forces a null check of s
-        return parseLong(s, radix, beginIndex, s.length());
-    }
-
-    /**
-     * Parses the {@link CharSequence} argument as a signed {@code long} in
      * the specified {@code radix}, beginning at the specified
      * {@code beginIndex} and extending to {@code endIndex - 1}.
      *
@@ -645,9 +614,9 @@
      *
      * @param      s   the {@code CharSequence} containing the {@code long}
      *                  representation to be parsed
-     * @param      radix   the radix to be used while parsing {@code s}.
      * @param      beginIndex   the beginning index, inclusive.
      * @param      endIndex     the ending index, exclusive.
+     * @param      radix   the radix to be used while parsing {@code s}.
      * @return     the signed {@code long} represented by the subsequence in
      *             the specified radix.
      * @throws     NullPointerException  if {@code s} is null.
@@ -662,7 +631,7 @@
      *             {@link java.lang.Character#MAX_RADIX}.
      * @since  1.9
      */
-    public static long parseLong(CharSequence s, int radix, int beginIndex, int endIndex)
+    public static long parseLong(CharSequence s, int beginIndex, int endIndex, int radix)
                 throws NumberFormatException {
         s = Objects.requireNonNull(s);
 
@@ -702,7 +671,7 @@
             long result = 0;
             while (i < endIndex) {
                 // Accumulating negatively avoids surprises near MAX_VALUE
-                int digit = Character.digit(s.charAt(i++), radix);
+                int digit = Character.digit(s.charAt(i), radix);
                 if (digit < 0 || result < multmin) {
                     throw NumberFormatException.forCharSequence(s, beginIndex,
                             endIndex, i);
@@ -712,6 +681,7 @@
                     throw NumberFormatException.forCharSequence(s, beginIndex,
                             endIndex, i);
                 }
+                i++;
                 result -= digit;
             }
             return negative ? result : -result;
@@ -811,7 +781,7 @@
                 }
 
                 // No need for range checks on len due to testing above.
-                long first = parseLong(s, radix, 0, len - 1);
+                long first = parseLong(s, 0, len - 1, radix);
                 int second = Character.digit(s.charAt(len - 1), radix);
                 if (second < 0) {
                     throw new NumberFormatException("Bad digit at end of " + s);
@@ -883,37 +853,6 @@
     /**
      * Parses the {@link CharSequence} argument as an unsigned {@code long} in
      * the specified {@code radix}, beginning at the specified
-     * {@code beginIndex} and extending to the end of the sequence.
-     *
-     * <p>The method does not take steps to guard against the
-     * {@code CharSequence} being mutated while parsing.
-     *
-     * @param      s   the {@code CharSequence} containing the unsigned
-     *                 {@code long} representation to be parsed
-     * @param      radix   the radix to be used while parsing {@code s}.
-     * @param      beginIndex   the beginning index, inclusive.
-     * @return     the unsigned {@code long} represented by the subsequence in
-     *             the specified radix.
-     * @throws     NullPointerException  if {@code s} is null.
-     * @throws     IndexOutOfBoundsException  if {@code beginIndex} is
-     *             negative, or if {@code beginIndex} is greater than
-     *             {@code s.length()}.
-     * @throws     NumberFormatException  if the {@code CharSequence} does not
-     *             contain a parsable unsigned {@code long} in the specified
-     *             {@code radix}, or if {@code radix} is either smaller than
-     *             {@link java.lang.Character#MIN_RADIX} or larger than
-     *             {@link java.lang.Character#MAX_RADIX}.
-     * @since  1.9
-     */
-    public static long parseUnsignedLong(CharSequence s, int radix, int beginIndex)
-                throws NumberFormatException {
-        // forces a null check of s
-        return parseUnsignedLong(s, radix, beginIndex, s.length());
-    }
-
-    /**
-     * Parses the {@link CharSequence} argument as an unsigned {@code long} in
-     * the specified {@code radix}, beginning at the specified
      * {@code beginIndex} and extending to {@code endIndex - 1}.
      *
      * <p>The method does not take steps to guard against the
@@ -921,9 +860,9 @@
      *
      * @param      s   the {@code CharSequence} containing the unsigned
      *                 {@code long} representation to be parsed
-     * @param      radix   the radix to be used while parsing {@code s}.
      * @param      beginIndex   the beginning index, inclusive.
      * @param      endIndex     the ending index, exclusive.
+     * @param      radix   the radix to be used while parsing {@code s}.
      * @return     the unsigned {@code long} represented by the subsequence in
      *             the specified radix.
      * @throws     NullPointerException  if {@code s} is null.
@@ -938,7 +877,7 @@
      *             {@link java.lang.Character#MAX_RADIX}.
      * @since  1.9
      */
-    public static long parseUnsignedLong(CharSequence s, int radix, int beginIndex, int endIndex)
+    public static long parseUnsignedLong(CharSequence s, int beginIndex, int endIndex, int radix)
                 throws NumberFormatException {
         s = Objects.requireNonNull(s);
 
@@ -955,11 +894,11 @@
             } else {
                 if (len <= 12 || // Long.MAX_VALUE in Character.MAX_RADIX is 13 digits
                     (radix == 10 && len <= 18) ) { // Long.MAX_VALUE in base 10 is 19 digits
-                    return parseLong(s, radix, start, start + len);
+                    return parseLong(s, start, start + len, radix);
                 }
 
                 // No need for range checks on end due to testing above.
-                long first = parseLong(s, radix, start, start + len - 1);
+                long first = parseLong(s, start, start + len - 1, radix);
                 int second = Character.digit(s.charAt(start + len - 1), radix);
                 if (second < 0) {
                     throw new NumberFormatException("Bad digit at end of " +
--- a/jdk/src/java.base/share/classes/java/time/Duration.java	Wed Sep 10 10:37:12 2014 +0200
+++ b/jdk/src/java.base/share/classes/java/time/Duration.java	Wed Sep 10 13:51:17 2014 +0100
@@ -424,7 +424,7 @@
             return 0;
         }
         try {
-            long val = Long.parseLong(text, 10, start, end);
+            long val = Long.parseLong(text, start, end, 10);
             return Math.multiplyExact(val, multiplier);
         } catch (NumberFormatException | ArithmeticException ex) {
             throw (DateTimeParseException) new DateTimeParseException("Text cannot be parsed to a Duration: " + errorText, text, 0).initCause(ex);
@@ -437,7 +437,7 @@
             return 0;
         }
         try {
-            int fraction = Integer.parseInt(text, 10, start, end);
+            int fraction = Integer.parseInt(text, start, end, 10);
 
             // for number strings smaller than 9 digits, interpret as if there
             // were trailing zeros
--- a/jdk/src/java.base/share/classes/java/time/Period.java	Wed Sep 10 10:37:12 2014 +0200
+++ b/jdk/src/java.base/share/classes/java/time/Period.java	Wed Sep 10 13:51:17 2014 +0100
@@ -358,7 +358,7 @@
         if (start < 0 || end < 0) {
             return 0;
         }
-        int val = Integer.parseInt(text, 10, start, end);
+        int val = Integer.parseInt(text, start, end, 10);
         try {
             return Math.multiplyExact(val, negate);
         } catch (ArithmeticException ex) {
--- a/jdk/src/java.base/share/classes/java/util/UUID.java	Wed Sep 10 10:37:12 2014 +0200
+++ b/jdk/src/java.base/share/classes/java/util/UUID.java	Wed Sep 10 13:51:17 2014 +0100
@@ -194,7 +194,8 @@
      *
      */
     public static UUID fromString(String name) {
-        if (name.length() > 36) {
+        int len = name.length();
+        if (len > 36) {
             throw new IllegalArgumentException("UUID string too large");
         }
 
@@ -214,15 +215,14 @@
             throw new IllegalArgumentException("Invalid UUID string: " + name);
         }
 
-        long mostSigBits = Long.parseLong(name, 16, 0, dash1) & 0xffffffffL;
+        long mostSigBits = Long.parseLong(name, 0, dash1, 16) & 0xffffffffL;
         mostSigBits <<= 16;
-        mostSigBits |= Long.parseLong(name, 16, dash1 + 1, dash2) & 0xffffL;
+        mostSigBits |= Long.parseLong(name, dash1 + 1, dash2, 16) & 0xffffL;
         mostSigBits <<= 16;
-        mostSigBits |= Long.parseLong(name, 16, dash2 + 1, dash3) & 0xffffL;
-
-        long leastSigBits = Long.parseLong(name, 16, dash3 + 1, dash4) & 0xffffL;
+        mostSigBits |= Long.parseLong(name, dash2 + 1, dash3, 16) & 0xffffL;
+        long leastSigBits = Long.parseLong(name, dash3 + 1, dash4, 16) & 0xffffL;
         leastSigBits <<= 48;
-        leastSigBits |= Long.parseLong(name, 16, dash4 + 1) & 0xffffffffffffL;
+        leastSigBits |= Long.parseLong(name, dash4 + 1, len, 16) & 0xffffffffffffL;
 
         return new UUID(mostSigBits, leastSigBits);
     }
--- a/jdk/test/java/lang/Integer/ParsingTest.java	Wed Sep 10 10:37:12 2014 +0200
+++ b/jdk/test/java/lang/Integer/ParsingTest.java	Wed Sep 10 13:51:17 2014 +0100
@@ -23,24 +23,22 @@
 
 /*
  * @test
- * @bug 5017980 6576055 8041972
+ * @bug 5017980 6576055 8041972 8055251
  * @summary Test parsing methods
  * @author Joseph D. Darcy
  */
 
-import java.lang.IllegalArgumentException;
 import java.lang.IndexOutOfBoundsException;
 import java.lang.NullPointerException;
 import java.lang.RuntimeException;
 
 /**
- * There are eight methods in java.lang.Integer which transform strings
+ * There are seven methods in java.lang.Integer which transform strings
  * into an int or Integer value:
  *
  * public Integer(String s)
  * public static Integer decode(String nm)
- * public static int parseInt(CharSequence s, int radix, int beginIndex, int endIndex)
- * public static int parseInt(CharSequence s, int radix, int beginIndex)
+ * public static int parseInt(CharSequence s, int beginIndex, int endIndex, int radix)
  * public static int parseInt(String s, int radix)
  * public static int parseInt(String s)
  * public static Integer valueOf(String s, int radix)
@@ -55,20 +53,17 @@
 public class ParsingTest {
 
     public static void main(String... argv) {
-        check("+100", +100);
-        check("-100", -100);
+        check(+100, "+100");
+        check(-100, "-100");
 
-        check("+0", 0);
-        check("-0", 0);
-        check("+00000", 0);
-        check("-00000", 0);
+        check(0, "+0");
+        check(0, "-0");
+        check(0, "+00000");
+        check(0, "-00000");
 
-        check("+00000", 0, 0, 6);
-        check("-00000", 0, 0, 6);
-
-        check("0", 0);
-        check("1", 1);
-        check("9", 9);
+        check(0, "0");
+        check(1, "1");
+        check(9, "9");
 
         checkFailure("");
         checkFailure("\u0000");
@@ -85,41 +80,37 @@
         checkFailure("-+6");
         checkFailure("*100");
 
-        check("test-00000", 0, 4, 10);
-        check("test-12345", -12345, 4, 10);
-        check("xx12345yy", 12345, 2, 7);
+        // check offset based methods
+        check(0, "+00000", 0, 6, 10);
+        check(0, "-00000", 0, 6, 10);
+        check(0, "test-00000", 4, 10, 10);
+        check(-12345, "test-12345", 4, 10, 10);
+        check(12345, "xx12345yy", 2, 7, 10);
+        check(15, "xxFyy", 2, 3, 16);
 
-        checkNumberFormatException("", 10, 0);
-        checkNumberFormatException("100", 10, 3);
-        checkNumberFormatException("+1000000", 10, 8);
-        checkNumberFormatException("-1000000", 10, 8);
-
-        checkNumberFormatException("", 10, 0, 0);
-        checkNumberFormatException("+-6", 10, 0, 3);
-        checkNumberFormatException("1000000", 10, 7);
-        checkNumberFormatException("1000000", 10, 7, 7);
-        checkNumberFormatException("1000000", Character.MAX_RADIX + 1, 0, 2);
-        checkNumberFormatException("1000000", Character.MIN_RADIX - 1, 0, 2);
+        checkNumberFormatException("", 0, 0, 10);
+        checkNumberFormatException("+-6", 0, 3, 10);
+        checkNumberFormatException("1000000", 7, 7, 10);
+        checkNumberFormatException("1000000", 0, 2, Character.MAX_RADIX + 1);
+        checkNumberFormatException("1000000", 0, 2, Character.MIN_RADIX - 1);
 
-        checkIndexOutOfBoundsException("1000000", 10, 8);
-        checkIndexOutOfBoundsException("1000000", 10, -1);
-        checkIndexOutOfBoundsException("1000000", 10, 10, 4);
-        checkIndexOutOfBoundsException("1000000", Character.MAX_RADIX + 1, -1, 2);
-        checkIndexOutOfBoundsException("1000000", Character.MIN_RADIX - 1, -1, 2);
-        checkIndexOutOfBoundsException("1000000", Character.MAX_RADIX + 1, 10, 2);
-        checkIndexOutOfBoundsException("1000000", Character.MIN_RADIX - 1, 10, 2);
-        checkIndexOutOfBoundsException("-1", 10, 0, 3);
-        checkIndexOutOfBoundsException("-1", 10, 2, 3);
-        checkIndexOutOfBoundsException("-1", 10, -1, 2);
+        checkIndexOutOfBoundsException("1000000", 10, 4, 10);
+        checkIndexOutOfBoundsException("1000000", -1, 2, Character.MAX_RADIX + 1);
+        checkIndexOutOfBoundsException("1000000", -1, 2, Character.MIN_RADIX - 1);
+        checkIndexOutOfBoundsException("1000000", 10, 2, Character.MAX_RADIX + 1);
+        checkIndexOutOfBoundsException("1000000", 10, 2, Character.MIN_RADIX - 1);
+        checkIndexOutOfBoundsException("-1", 0, 3, 10);
+        checkIndexOutOfBoundsException("-1", 2, 3, 10);
+        checkIndexOutOfBoundsException("-1", -1, 2, 10);
 
-        checkNull(10, 0, 1);
-        checkNull(10, -1, 0);
-        checkNull(10, 0, 0);
-        checkNull(10, 0, -1);
+        checkNull(0, 1, 10);
+        checkNull(-1, 0, 10);
+        checkNull(0, 0, 10);
+        checkNull(0, -1, 10);
         checkNull(-1, -1, -1);
     }
 
-    private static void check(String val, int expected) {
+    private static void check(int expected, String val) {
         int n = Integer.parseInt(val);
         if (n != expected)
             throw new RuntimeException("Integer.parseInt failed. String:" +
@@ -137,23 +128,11 @@
         }
     }
 
-    private static void checkNumberFormatException(String val, int radix, int start) {
+    private static void checkNumberFormatException(String val, int start, int end, int radix) {
         int n = 0;
         try {
-            n = Integer.parseInt(val, radix, start);
-            System.err.println("parseInt(" + val + ", " + radix + ", " + start +
-                    ") incorrectly returned " + n);
-            throw new RuntimeException();
-        } catch (NumberFormatException nfe) {
-            ; // Expected
-        }
-    }
-
-    private static void checkNumberFormatException(String val, int radix, int start, int end) {
-        int n = 0;
-        try {
-            n = Integer.parseInt(val, radix, start, end);
-            System.err.println("parseInt(" + val + ", " + radix + ", " + start + ", " + end +
+            n = Integer.parseInt(val, start, end, radix);
+            System.err.println("parseInt(" + val + ", " + start + ", " + end + ", " + radix +
                     ") incorrectly returned " + n);
             throw new RuntimeException();
         } catch (NumberFormatException nfe) {
@@ -161,11 +140,11 @@
         }
     }
 
-    private static void checkIndexOutOfBoundsException(String val, int radix, int start) {
+    private static void checkIndexOutOfBoundsException(String val, int start, int end, int radix) {
         int n = 0;
         try {
-            n = Integer.parseInt(val, radix, start);
-            System.err.println("parseInt(" + val + ", " + radix + ", " + start +
+            n = Integer.parseInt(val, start, end, radix);
+            System.err.println("parseInt(" + val + ", " + start + ", " + end + ", " + radix  +
                     ") incorrectly returned " + n);
             throw new RuntimeException();
         } catch (IndexOutOfBoundsException ioob) {
@@ -173,23 +152,11 @@
         }
     }
 
-    private static void checkIndexOutOfBoundsException(String val, int radix, int start, int end) {
+    private static void checkNull(int start, int end, int radix) {
         int n = 0;
         try {
-            n = Integer.parseInt(val, radix, start, end);
-            System.err.println("parseInt(" + val + ", " + radix + ", " + start + ", " + end +
-                    ") incorrectly returned " + n);
-            throw new RuntimeException();
-        } catch (IndexOutOfBoundsException ioob) {
-            ; // Expected
-        }
-    }
-
-    private static void checkNull(int radix, int start, int end) {
-        int n = 0;
-        try {
-            n = Integer.parseInt(null, 10, start, end);
-            System.err.println("parseInt(null, " + radix + ", " + start + ", " + end +
+            n = Integer.parseInt(null, start, end, radix);
+            System.err.println("parseInt(null, " + start + ", " + end + ", " + radix +
                     ") incorrectly returned " + n);
             throw new RuntimeException();
         } catch (NullPointerException npe) {
@@ -197,10 +164,10 @@
         }
     }
 
-    private static void check(String val, int expected, int start, int end) {
-        int n = Integer.parseInt(val, 10, start, end);
+    private static void check(int expected, String val, int start, int end, int radix) {
+        int n = Integer.parseInt(val, start, end, radix);
         if (n != expected)
-            throw new RuntimeException("Integer.parsedInt failed. String:" +
-                    val + ", start: " + start + ", end: " + end + " Result:" + n);
+            throw new RuntimeException("Integer.parsedInt failed. Expected: " + expected + " String: \"" +
+                    val + "\", start: " + start + ", end: " + end + ", radix: " + radix + " Result:" + n);
     }
 }
--- a/jdk/test/java/lang/Integer/Unsigned.java	Wed Sep 10 10:37:12 2014 +0200
+++ b/jdk/test/java/lang/Integer/Unsigned.java	Wed Sep 10 13:51:17 2014 +0100
@@ -303,6 +303,17 @@
                                       "\tconverting back ''%s'' resulted in %d%n",
                                       value, radix, longString,  intResult);
                 }
+
+                // test offset based parse method
+                intResult = Integer.parseUnsignedInt("prefix" + longString + "suffix",
+                        "prefix".length(), "prefix".length() + longString.length(), radix);
+
+                if (Integer.toUnsignedLong(intResult) != value) {
+                    errors++;
+                    System.err.printf("Bad roundtrip conversion of %d in base %d" +
+                            "\tconverting back ''%s'' resulted in %d%n",
+                            value, radix, longString,  intResult);
+                }
             }
         }
 
--- a/jdk/test/java/lang/Long/ParsingTest.java	Wed Sep 10 10:37:12 2014 +0200
+++ b/jdk/test/java/lang/Long/ParsingTest.java	Wed Sep 10 13:51:17 2014 +0100
@@ -23,19 +23,18 @@
 
 /*
  * @test
- * @bug 5017980 6576055 8041972
+ * @bug 5017980 6576055 8041972 8055251
  * @summary Test parsing methods
  * @author Joseph D. Darcy
  */
 
 /**
- * There are eight methods in java.lang.Long which transform strings
+ * There are seven methods in java.lang.Long which transform strings
  * into a long or Long value:
  *
  * public Long(String s)
  * public static Long decode(String nm)
  * public static long parseLong(CharSequence s, int radix, int beginIndex, int endIndex)
- * public static long parseLong(CharSequence s, int radix, int beginIndex)
  * public static long parseLong(String s, int radix)
  * public static long parseLong(String s)
  * public static Long valueOf(String s, int radix)
@@ -49,17 +48,17 @@
 public class ParsingTest {
 
     public static void main(String... argv) {
-        check("+100", +100L);
-        check("-100", -100L);
+        check(+100L, "+100");
+        check(-100L, "-100");
 
-        check("+0", 0L);
-        check("-0", 0L);
-        check("+00000", 0L);
-        check("-00000", 0L);
+        check(0L, "+0");
+        check(0L, "-0");
+        check(0L, "+00000");
+        check(0L, "-00000");
 
-        check("0", 0L);
-        check("1", 1L);
-        check("9", 9L);
+        check(0L, "0");
+        check(1L, "1");
+        check(9L, "9");
 
         checkFailure("");
         checkFailure("\u0000");
@@ -76,40 +75,36 @@
         checkFailure("-+6");
         checkFailure("*100");
 
-        check("test-00000", 0L, 4, 10);
-        check("test-12345", -12345L, 4, 10);
-        check("xx12345yy", 12345L, 2, 7);
-        check("xx123456789012345yy", 123456789012345L, 2, 17);
+        check(0L, "test-00000", 4, 10, 10);
+        check(-12345L, "test-12345", 4, 10, 10);
+        check(12345L, "xx12345yy", 2, 7, 10);
+        check(123456789012345L, "xx123456789012345yy", 2, 17, 10);
+        check(15L, "xxFyy", 2, 3, 16);
 
-        checkNumberFormatException("100", 10, 3);
-        checkNumberFormatException("", 10, 0);
-        checkNumberFormatException("+1000000", 10, 8);
-        checkNumberFormatException("-1000000", 10, 8);
+        checkNumberFormatException("", 0, 0, 10);
+        checkNumberFormatException("+-6", 0, 3, 10);
+        checkNumberFormatException("1000000", 7, 7, 10);
+        checkNumberFormatException("1000000", 0, 2, Character.MAX_RADIX + 1);
+        checkNumberFormatException("1000000", 0, 2, Character.MIN_RADIX - 1);
 
-        checkNumberFormatException("", 10, 0, 0);
-        checkNumberFormatException("+-6", 10, 0, 3);
-        checkNumberFormatException("1000000", 10, 7, 7);
-        checkNumberFormatException("1000000", Character.MAX_RADIX + 1, 0, 2);
-        checkNumberFormatException("1000000", Character.MIN_RADIX - 1, 0, 2);
+        checkIndexOutOfBoundsException("", 1, 1, 10);
+        checkIndexOutOfBoundsException("1000000", 10, 4, 10);
+        checkIndexOutOfBoundsException("1000000", 10, 2, Character.MAX_RADIX + 1);
+        checkIndexOutOfBoundsException("1000000", 10, 2, Character.MIN_RADIX - 1);
+        checkIndexOutOfBoundsException("1000000", -1, 2, Character.MAX_RADIX + 1);
+        checkIndexOutOfBoundsException("1000000", -1, 2, Character.MIN_RADIX - 1);
+        checkIndexOutOfBoundsException("-1", 0, 3, 10);
+        checkIndexOutOfBoundsException("-1", 2, 3, 10);
+        checkIndexOutOfBoundsException("-1", -1, 2, 10);
 
-        checkIndexOutOfBoundsException("", 10, 1, 1);
-        checkIndexOutOfBoundsException("1000000", 10, 10, 4);
-        checkIndexOutOfBoundsException("1000000", Character.MAX_RADIX + 1, 10, 2);
-        checkIndexOutOfBoundsException("1000000", Character.MIN_RADIX - 1, 10, 2);
-        checkIndexOutOfBoundsException("1000000", Character.MAX_RADIX + 1, -1, 2);
-        checkIndexOutOfBoundsException("1000000", Character.MIN_RADIX - 1, -1, 2);
-        checkIndexOutOfBoundsException("-1", 10, 0, 3);
-        checkIndexOutOfBoundsException("-1", 10, 2, 3);
-        checkIndexOutOfBoundsException("-1", 10, -1, 2);
-
-        checkNull(10, 0, 1);
-        checkNull(10, -1, 0);
-        checkNull(10, 0, 0);
-        checkNull(10, 0, -1);
+        checkNull(0, 1, 10);
+        checkNull(-1, 0, 10);
+        checkNull(0, 0, 10);
+        checkNull(0, -1, 10);
         checkNull(-1, -1, -1);
     }
 
-    private static void check(String val, long expected) {
+    private static void check(long expected, String val) {
         long n = Long.parseLong(val);
         if (n != expected)
             throw new RuntimeException("Long.parseLong failed. String:" +
@@ -127,23 +122,11 @@
         }
     }
 
-    private static void checkNumberFormatException(String val, int radix, int start) {
+    private static void checkNumberFormatException(String val, int start, int end, int radix) {
         long n = 0;
         try {
-            n = Long.parseLong(val, radix, start);
-            System.err.println("parseLong(" + val + ", " + radix + ", " + start +
-                    ") incorrectly returned " + n);
-            throw new RuntimeException();
-        } catch (NumberFormatException nfe) {
-            ; // Expected
-        }
-    }
-
-    private static void checkNumberFormatException(String val, int radix, int start, int end) {
-        long n = 0;
-        try {
-            n = Long.parseLong(val, radix, start, end);
-            System.err.println("parseLong(" + val + ", " + radix + ", " + start + ", " + end +
+            n = Long.parseLong(val, start, end, radix);
+            System.err.println("parseLong(" + val + ", " + start + ", " + end + ", " + radix +
                     ") incorrectly returned " + n);
             throw new RuntimeException();
         } catch (NumberFormatException nfe) {
@@ -151,11 +134,11 @@
         }
     }
 
-    private static void checkIndexOutOfBoundsException(String val, int radix, int start) {
+    private static void checkIndexOutOfBoundsException(String val, int start, int end, int radix) {
         long n = 0;
         try {
-            n = Long.parseLong(val, radix, start);
-            System.err.println("parseLong(" + val + ", " + radix + ", " + start +
+            n = Long.parseLong(val, start, end, radix);
+            System.err.println("parseLong(" + val + ", " + start + ", " + end + ", " + radix +
                     ") incorrectly returned " + n);
             throw new RuntimeException();
         } catch (IndexOutOfBoundsException ioob) {
@@ -163,23 +146,11 @@
         }
     }
 
-    private static void checkIndexOutOfBoundsException(String val, int radix, int start, int end) {
+    private static void checkNull(int start, int end, int radix) {
         long n = 0;
         try {
-            n = Long.parseLong(val, radix, start, end);
-            System.err.println("parseLong(" + val + ", " + radix + ", " + start + ", " + end +
-                    ") incorrectly returned " + n);
-            throw new RuntimeException();
-        } catch (IndexOutOfBoundsException ioob) {
-            ; // Expected
-        }
-    }
-
-    private static void checkNull(int radix, int start, int end) {
-        long n = 0;
-        try {
-            n = Long.parseLong(null, 10, start, end);
-            System.err.println("parseLong(null, " + radix + ", " + start + ", " + end +
+            n = Long.parseLong(null, start, end, radix);
+            System.err.println("parseLong(null, " + start + ", " + end + ", " + radix +
                     ") incorrectly returned " + n);
             throw new RuntimeException();
         } catch (NullPointerException npe) {
@@ -187,10 +158,10 @@
         }
     }
 
-    private static void check(String val, long expected, int start, int end) {
-        long n = Long.parseLong(val, 10, start, end);
+    private static void check(long expected, String val, int start, int end, int radix) {
+        long n = Long.parseLong(val, start, end, radix);
         if (n != expected)
-            throw new RuntimeException("Long.parseLong failed. String:" +
-                    val + ", start: " + start + ", end: " + end + " Result:" + n);
+            throw new RuntimeException("Long.parseLong failed. Expexted: " + expected + " String: \"" +
+                    val + "\", start: " + start + ", end: " + end + " radix: " + radix + " Result: " + n);
     }
 }
--- a/jdk/test/java/lang/Long/Unsigned.java	Wed Sep 10 10:37:12 2014 +0200
+++ b/jdk/test/java/lang/Long/Unsigned.java	Wed Sep 10 13:51:17 2014 +0100
@@ -289,6 +289,17 @@
                                       "\tconverting back ''%s'' resulted in %d%n",
                                       value, radix, bigString,  longResult);
                 }
+
+                // test offset based parse method
+                longResult = Long.parseUnsignedLong("prefix" + bigString + "suffix", "prefix".length(),
+                        "prefix".length() + bigString.length(), radix);
+
+                if (!toUnsignedBigInt(longResult).equals(value)) {
+                    errors++;
+                    System.err.printf("Bad roundtrip conversion of %d in base %d" +
+                            "\tconverting back ''%s'' resulted in %d%n",
+                            value, radix, bigString,  longResult);
+                }
             }
         }