src/share/classes/java/lang/Long.java
Print this page
rev 8975 : 8030814: Long.parseUnsignedLong should throwexception on too large input
Summary: Change test for overflow of unsigned long
Reviewed-by: TBD
*** 63,72 ****
--- 63,78 ----
* have, 2<sup>63</sup>-1.
*/
@Native public static final long MAX_VALUE = 0x7fffffffffffffffL;
/**
+ * A constant holding the maximum value a 64-bit unsigned long could
+ * have, 2<sup>64</sup>-1.
+ */
+ private static long MAX_UNSIGNED = 0xffffffffffffffffL;
+
+ /**
* The {@code Class} instance representing the primitive type
* {@code long}.
*
* @since JDK1.1
*/
*** 629,638 ****
--- 635,659 ----
*/
public static long parseLong(String s) throws NumberFormatException {
return parseLong(s, 10);
}
+ private static class ParseUnsignedCache {
+ private ParseUnsignedCache(){}
+
+ static final long[] div = new long[Character.MAX_RADIX];
+ static final long[] rem = new long[Character.MAX_RADIX];
+
+ static {
+ // div[0] and rem[0] are unused.
+ for(int radix = 1; radix < Character.MAX_RADIX; radix++) {
+ div[radix] = divideUnsigned(MAX_UNSIGNED, radix);
+ rem[radix] = remainderUnsigned(MAX_UNSIGNED, radix);
+ }
+ }
+ }
+
/**
* Parses the string argument as an unsigned {@code long} in the
* radix specified by the second argument. An unsigned integer
* maps the values usually associated with negative numbers to
* positive numbers larger than {@code MAX_VALUE}.
*** 697,708 ****
long first = parseLong(s.substring(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);
}
! long result = first * radix + second;
! if (compareUnsigned(result, first) < 0) {
/*
* The maximum unsigned value, (2^64)-1, takes at
* most one more digit to represent than the
* maximum signed value, (2^63)-1. Therefore,
* parsing (len - 1) digits will be appropriately
--- 718,730 ----
long first = parseLong(s.substring(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);
}
! if (compareUnsigned(first, ParseUnsignedCache.div[radix]) > 0 ||
! (first == ParseUnsignedCache.div[radix] &&
! second > ParseUnsignedCache.rem[radix])) {
/*
* The maximum unsigned value, (2^64)-1, takes at
* most one more digit to represent than the
* maximum signed value, (2^63)-1. Therefore,
* parsing (len - 1) digits will be appropriately
*** 717,727 ****
* digit.
*/
throw new NumberFormatException(String.format("String value %s exceeds " +
"range of unsigned long.", s));
}
! return result;
}
} else {
throw NumberFormatException.forInputString(s);
}
}
--- 739,749 ----
* digit.
*/
throw new NumberFormatException(String.format("String value %s exceeds " +
"range of unsigned long.", s));
}
! return first * radix + second;
}
} else {
throw NumberFormatException.forInputString(s);
}
}