diff --git a/src/java.base/share/classes/java/util/Locale.java b/src/java.base/share/classes/java/util/Locale.java index f600afbb007a6..abd60dab71058 100644 --- a/src/java.base/share/classes/java/util/Locale.java +++ b/src/java.base/share/classes/java/util/Locale.java @@ -3204,18 +3204,20 @@ public LanguageRange(String range) { * * @param range a language range * @param weight a weight value between {@code MIN_WEIGHT} and - * {@code MAX_WEIGHT} + * {@code MAX_WEIGHT}, inclusive * @throws NullPointerException if the given {@code range} is * {@code null} * @throws IllegalArgumentException if the given {@code range} does not - * comply with the syntax of the language range mentioned in RFC 4647 - * or if the given {@code weight} is less than {@code MIN_WEIGHT} - * or greater than {@code MAX_WEIGHT} + * comply with the syntax of the language range mentioned in RFC 4647, + * or if the given {@code weight} is {@code Double.NaN}, less than {@code + * MIN_WEIGHT} or greater than {@code MAX_WEIGHT} */ public LanguageRange(String range, double weight) { Objects.requireNonNull(range); - if (weight < MIN_WEIGHT || weight > MAX_WEIGHT) { - throw new IllegalArgumentException("weight=" + weight); + if (weight < MIN_WEIGHT || weight > MAX_WEIGHT || Double.isNaN(weight)) { + throw new IllegalArgumentException( + "The weight " + weight + " must be between " + + MIN_WEIGHT + " and " + MAX_WEIGHT + ", inclusive."); } range = range.toLowerCase(Locale.ROOT); @@ -3338,6 +3340,11 @@ public double getWeight() { * matching locale (or language tag) even if the application or system * offers only {@code "he"} as a supported locale (or language tag). * + * @implNote This implementation interprets weights within the {@code ranges} + * string using {@link Double#parseDouble(String)}. As a result, some + * non-RFC 2616 forms of otherwise in-range values, such as leading + * signs, scientific notation, or more than three fractional digits, may be + * accepted. * @param ranges a list of comma-separated language ranges or a list of * language ranges in the form of the "Accept-Language" header * defined in RFC @@ -3360,6 +3367,11 @@ public static List parse(String ranges) { * This method is equivalent to * {@code mapEquivalents(parse(ranges), map)}. * + * @implNote This implementation interprets weights within the {@code ranges} + * string using {@link Double#parseDouble(String)}. As a result, some + * non-RFC 2616 forms of otherwise in-range values, such as leading + * signs, scientific notation, or more than three fractional digits, may be + * accepted. * @param ranges a list of comma-separated language ranges or a list * of language ranges in the form of the "Accept-Language" header * defined in RFC diff --git a/src/java.base/share/classes/sun/util/locale/LocaleMatcher.java b/src/java.base/share/classes/sun/util/locale/LocaleMatcher.java index bc5115e1ff17b..5385a5598b68b 100644 --- a/src/java.base/share/classes/sun/util/locale/LocaleMatcher.java +++ b/src/java.base/share/classes/sun/util/locale/LocaleMatcher.java @@ -467,17 +467,18 @@ public static List parse(String ranges) { try { w = Double.parseDouble(range.substring(index)); } - catch (Exception e) { - throw new IllegalArgumentException("weight=\"" + catch (NumberFormatException _) { + throw new IllegalArgumentException("The weight \"" + range.substring(index) - + "\" for language range \"" + r + "\""); + + "\" for language range \"" + r + "\"" + + " must be between " + MIN_WEIGHT + + " and " + MAX_WEIGHT + ", inclusive."); } - if (w < MIN_WEIGHT || w > MAX_WEIGHT) { - throw new IllegalArgumentException("weight=" + w - + " for language range \"" + r - + "\". It must be between " + MIN_WEIGHT - + " and " + MAX_WEIGHT + "."); + throw new IllegalArgumentException("The weight \"" + w + + "\" for language range \"" + r + "\"" + + " must be between " + MIN_WEIGHT + + " and " + MAX_WEIGHT + ", inclusive."); } } diff --git a/test/jdk/java/util/Locale/LocaleMatchingTest.java b/test/jdk/java/util/Locale/LocaleMatchingTest.java index c5d8a00d45882..806229ca8eb98 100644 --- a/test/jdk/java/util/Locale/LocaleMatchingTest.java +++ b/test/jdk/java/util/Locale/LocaleMatchingTest.java @@ -23,7 +23,7 @@ /* * @test - * @bug 7069824 8042360 8032842 8175539 8210443 8242010 8276302 8381644 + * @bug 7069824 8042360 8032842 8175539 8210443 8242010 8276302 8381644 8387261 * @summary Verify implementation for Locale matching. * @run junit/othervm LocaleMatchingTest */ @@ -93,6 +93,7 @@ static Object[][] LRConstructorIAEData() { {"1996-de-Latn", MAX_WEIGHT}, // Testcase for 8042360 {"en-Latn-1234567890", MAX_WEIGHT}, + {"en", Double.NaN}, }; } @@ -146,6 +147,7 @@ static Object[][] LRParseIAEData() { // Ranges {""}, {"ja;q=3"}, + {"en;q=NaN"} }; }