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); } }