OpenJDK / jdk6 / jdk6 / jdk
changeset 475:d00080320e43
4421494: infinite loop while parsing double literal
Reviewed-by: darcy, alanb
Contributed-by: dmitry.nadezhin@oracle.com
author | alanb |
---|---|
date | Sun, 06 Feb 2011 19:17:34 +0000 |
parents | f7afe7a5e086 |
children | ab13e29156f7 4be1306cffe7 |
files | src/share/classes/sun/misc/FloatingDecimal.java test/java/lang/Double/ParseDouble.java |
diffstat | 2 files changed, 50 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/sun/misc/FloatingDecimal.java Fri Jan 21 16:21:28 2011 -0800 +++ b/src/share/classes/sun/misc/FloatingDecimal.java Sun Feb 06 19:17:34 2011 +0000 @@ -1547,7 +1547,7 @@ if ( (cmpResult = bigB.cmp( bigD ) ) > 0 ){ overvalue = true; // our candidate is too big. diff = bigB.sub( bigD ); - if ( (bigIntNBits == 1) && (bigIntExp > -expBias) ){ + if ( (bigIntNBits == 1) && (bigIntExp > -expBias+1) ){ // candidate is a normalized exact power of 2 and // is too big. We will be subtracting. // For our purposes, ulp is the ulp of the
--- a/test/java/lang/Double/ParseDouble.java Fri Jan 21 16:21:28 2011 -0800 +++ b/test/java/lang/Double/ParseDouble.java Sun Feb 06 19:17:34 2011 +0000 @@ -23,11 +23,12 @@ /* * @test - * @bug 4160406 4705734 4707389 4826774 4895911 + * @bug 4160406 4705734 4707389 4826774 4895911 4421494 * @summary Test for Double.parseDouble method and acceptance regex */ import java.util.regex.*; +import java.math.BigDecimal; public class ParseDouble { @@ -416,7 +417,15 @@ "0x00100p1", "0x00.100p1", - "0x001.100p1" + "0x001.100p1", + + // Limits + + "1.7976931348623157E308", // Double.MAX_VALUE + "4.9e-324", // Double.MIN_VALUE + "2.2250738585072014e-308", // Double.MIN_NORMAL + + "2.2250738585072012e-308", // near Double.MIN_NORMAL }; static String paddedBadStrings[]; @@ -546,6 +555,42 @@ } + /** + * For each subnormal power of two, test at boundaries of + * region that should convert to that value. + */ + private static void testSubnormalPowers() { + BigDecimal TWO = BigDecimal.valueOf(2); + // An ulp is the same for all subnormal values + BigDecimal ulp_BD = new BigDecimal(Double.MIN_VALUE); + + System.out.println("Testing subnormal powers of two."); + for(int i = -1074; i <= -1022; i++) { + double d = Math.scalb(1.0, i); + + /* + * The region [d - ulp/2, d + ulp/2] should round to d. + */ + BigDecimal d_BD = new BigDecimal(d); + + BigDecimal lowerBound = d_BD.subtract(ulp_BD.divide(TWO)); + BigDecimal upperBound = d_BD.add(ulp_BD.divide(TWO)); + + double convertedLowerBound = Double.parseDouble(lowerBound.toString()); + double convertedUpperBound = Double.parseDouble(upperBound.toString()); + + if (convertedLowerBound != d) { + System.out.printf("Exponent %d, unexpected lower bound converted to %a, not %a.%n", + i, convertedLowerBound, d); + } + + if (convertedUpperBound != d) { + System.out.printf("Exponent %d, unexpected upper bound converted to %a, not %a.%n", + i, convertedUpperBound, d); + } + } + } + public static void main(String[] args) throws Exception { rudimentaryTest(); @@ -558,5 +603,7 @@ testRegex(paddedGoodStrings, false); testRegex(badStrings, true); testRegex(paddedBadStrings, true); + + testSubnormalPowers(); } }