src/share/classes/java/lang/Long.java

Print this page
rev 9020 : 8030814: Long.parseUnsignedLong should throw exception on too large input
Summary: Change test for overflow of unsigned long
Reviewed-by: TBD
Contributed-by: Dmitry Nadezhin <dmitry.nadezhin@oracle.com>


 683         int len = s.length();
 684         if (len > 0) {
 685             char firstChar = s.charAt(0);
 686             if (firstChar == '-') {
 687                 throw new
 688                     NumberFormatException(String.format("Illegal leading minus sign " +
 689                                                        "on unsigned string %s.", s));
 690             } else {
 691                 if (len <= 12 || // Long.MAX_VALUE in Character.MAX_RADIX is 13 digits
 692                     (radix == 10 && len <= 18) ) { // Long.MAX_VALUE in base 10 is 19 digits
 693                     return parseLong(s, radix);
 694                 }
 695 
 696                 // No need for range checks on len due to testing above.
 697                 long first = parseLong(s.substring(0, len - 1), radix);
 698                 int second = Character.digit(s.charAt(len - 1), radix);
 699                 if (second < 0) {
 700                     throw new NumberFormatException("Bad digit at end of " + s);
 701                 }
 702                 long result = first * radix + second;
 703                 if (compareUnsigned(result, first) < 0) {






 704                     /*
 705                      * The maximum unsigned value, (2^64)-1, takes at
 706                      * most one more digit to represent than the
 707                      * maximum signed value, (2^63)-1.  Therefore,
 708                      * parsing (len - 1) digits will be appropriately
 709                      * in-range of the signed parsing.  In other
 710                      * words, if parsing (len -1) digits overflows
 711                      * signed parsing, parsing len digits will
 712                      * certainly overflow unsigned parsing.
 713                      *
 714                      * The compareUnsigned check above catches
 715                      * situations where an unsigned overflow occurs
 716                      * incorporating the contribution of the final
 717                      * digit.
 718                      */
 719                     throw new NumberFormatException(String.format("String value %s exceeds " +
 720                                                                   "range of unsigned long.", s));
 721                 }
 722                 return result;
 723             }




 683         int len = s.length();
 684         if (len > 0) {
 685             char firstChar = s.charAt(0);
 686             if (firstChar == '-') {
 687                 throw new
 688                     NumberFormatException(String.format("Illegal leading minus sign " +
 689                                                        "on unsigned string %s.", s));
 690             } else {
 691                 if (len <= 12 || // Long.MAX_VALUE in Character.MAX_RADIX is 13 digits
 692                     (radix == 10 && len <= 18) ) { // Long.MAX_VALUE in base 10 is 19 digits
 693                     return parseLong(s, radix);
 694                 }
 695 
 696                 // No need for range checks on len due to testing above.
 697                 long first = parseLong(s.substring(0, len - 1), radix);
 698                 int second = Character.digit(s.charAt(len - 1), radix);
 699                 if (second < 0) {
 700                     throw new NumberFormatException("Bad digit at end of " + s);
 701                 }
 702                 long result = first * radix + second;
 703 //                final int GUARD_BIT = 7;
 704 //                int guard = radix * (int) (first >>> (64 - GUARD_BIT));
 705                 int guard = radix * (int) (first >>> 57);
 706 //                if (guard >= (1 << GUARD_BIT) - Character.MAX_RADIX
 707 //                        && (guard >= (1 << GUARD_BIT) || result >= 0)) {
 708                 if (guard >= 128 ||
 709                         (result >= 0 && guard >= 128 - Character.MAX_RADIX)) {
 710                     /*
 711                      * The maximum unsigned value, (2^64)-1, takes at
 712                      * most one more digit to represent than the
 713                      * maximum signed value, (2^63)-1.  Therefore,
 714                      * parsing (len - 1) digits will be appropriately
 715                      * in-range of the signed parsing.  In other
 716                      * words, if parsing (len -1) digits overflows
 717                      * signed parsing, parsing len digits will
 718                      * certainly overflow unsigned parsing.
 719                      *
 720                      * The compareUnsigned check above catches
 721                      * situations where an unsigned overflow occurs
 722                      * incorporating the contribution of the final
 723                      * digit.
 724                      */
 725                     throw new NumberFormatException(String.format("String value %s exceeds " +
 726                                                                   "range of unsigned long.", s));
 727                 }
 728                 return result;
 729             }