Mercurial > hg > release > icedtea6-1.8
view patches/security/20110209/4421494.patch @ 2131:04cd613daca9
S4421494, CVE-2010-4476: infinite loop while parsing double literal.
2011-02-09 Andrew John Hughes <ahughes@redhat.com>
* Makefile.am: Add patch.
* NEWS: Updated.
* patches/security/20110209/4421494.patch:
Add floating point bug fix.
author | Andrew John Hughes <ahughes@redhat.com> |
---|---|
date | Wed, 09 Feb 2011 12:36:05 +0000 |
parents | |
children |
line wrap: on
line source
# HG changeset patch # User alanb # Date 1297019854 0 # Node ID d00080320e439c339594d380f0322c865553a046 # Parent f7afe7a5e086a6af1f23dd6304bcbe7fb2b6226a 4421494: infinite loop while parsing double literal Reviewed-by: darcy, alanb Contributed-by: dmitry.nadezhin@oracle.com diff --git a/src/share/classes/sun/misc/FloatingDecimal.java b/src/share/classes/sun/misc/FloatingDecimal.java --- openjdk/jdk/src/share/classes/sun/misc/FloatingDecimal.java +++ openjdk/jdk/src/share/classes/sun/misc/FloatingDecimal.java @@ -1547,7 +1547,7 @@ public class FloatingDecimal{ 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 diff --git a/test/java/lang/Double/ParseDouble.java b/test/java/lang/Double/ParseDouble.java --- openjdk/jdk/test/java/lang/Double/ParseDouble.java +++ openjdk/jdk/test/java/lang/Double/ParseDouble.java @@ -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 @@ public class ParseDouble { "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 @@ public class ParseDouble { } + /** + * 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 @@ public class ParseDouble { testRegex(paddedGoodStrings, false); testRegex(badStrings, true); testRegex(paddedBadStrings, true); + + testSubnormalPowers(); } }