Skip to content

Commit 87cc4e5

Browse files
GreenRecycleBinnaotoj
authored andcommitted
8276302: Locale.filterTags methods ignore actual weight when matching "*" (as if it is 1)
Reviewed-by: naoto
1 parent 214f98f commit 87cc4e5

File tree

2 files changed

+73
-75
lines changed

2 files changed

+73
-75
lines changed

src/java.base/share/classes/sun/util/locale/LocaleMatcher.java

Lines changed: 24 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,18 @@ private static List<String> filterBasic(List<LanguageRange> priorityList,
124124
for (LanguageRange lr : nonZeroRanges) {
125125
String range = lr.getRange();
126126
if (range.equals("*")) {
127-
tags = removeTagsMatchingBasicZeroRange(zeroRanges, tags);
128-
return new ArrayList<String>(tags);
127+
for (String tag : tags) {
128+
// change to lowercase for case-insensitive matching
129+
String lowerCaseTag = tag.toLowerCase(Locale.ROOT);
130+
131+
if (!caseInsensitiveMatch(list, lowerCaseTag)
132+
&& !shouldIgnoreFilterBasicMatch(zeroRanges, lowerCaseTag)) {
133+
// preserving the case of the input tag
134+
list.add(tag);
135+
}
136+
}
137+
138+
break;
129139
} else {
130140
for (String tag : tags) {
131141
// change to lowercase for case-insensitive matching
@@ -148,44 +158,6 @@ private static List<String> filterBasic(List<LanguageRange> priorityList,
148158
return list;
149159
}
150160

151-
/**
152-
* Removes the tag(s) which are falling in the basic exclusion range(s) i.e
153-
* range(s) with q=0 and returns the updated collection. If the basic
154-
* language ranges contains '*' as one of its non zero range then instead of
155-
* returning all the tags, remove those which are matching the range with
156-
* quality weight q=0.
157-
*/
158-
private static Collection<String> removeTagsMatchingBasicZeroRange(
159-
List<LanguageRange> zeroRange, Collection<String> tags) {
160-
if (zeroRange.isEmpty()) {
161-
tags = removeDuplicates(tags);
162-
return tags;
163-
}
164-
165-
List<String> matchingTags = new ArrayList<>();
166-
for (String tag : tags) {
167-
// change to lowercase for case-insensitive matching
168-
String lowerCaseTag = tag.toLowerCase(Locale.ROOT);
169-
if (!shouldIgnoreFilterBasicMatch(zeroRange, lowerCaseTag)
170-
&& !caseInsensitiveMatch(matchingTags, lowerCaseTag)) {
171-
matchingTags.add(tag); // preserving the case of the input tag
172-
}
173-
}
174-
175-
return matchingTags;
176-
}
177-
178-
/**
179-
* Remove duplicate tags from the given {@code tags} by
180-
* ignoring case considerations.
181-
*/
182-
private static Collection<String> removeDuplicates(
183-
Collection<String> tags) {
184-
Set<String> distinctTags = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
185-
return tags.stream().filter(x -> distinctTags.add(x))
186-
.toList();
187-
}
188-
189161
/**
190162
* Returns true if the given {@code list} contains an element which matches
191163
* with the given {@code tag} ignoring case considerations.
@@ -240,8 +212,18 @@ private static List<String> filterExtended(List<LanguageRange> priorityList,
240212
for (LanguageRange lr : nonZeroRanges) {
241213
String range = lr.getRange();
242214
if (range.equals("*")) {
243-
tags = removeTagsMatchingExtendedZeroRange(zeroRanges, tags);
244-
return new ArrayList<String>(tags);
215+
for (String tag : tags) {
216+
// change to lowercase for case-insensitive matching
217+
String lowerCaseTag = tag.toLowerCase(Locale.ROOT);
218+
219+
if (!caseInsensitiveMatch(list, lowerCaseTag)
220+
&& !shouldIgnoreFilterExtendedMatch(zeroRanges, lowerCaseTag)) {
221+
// preserving the case of the input tag
222+
list.add(tag);
223+
}
224+
}
225+
226+
break;
245227
}
246228
String[] rangeSubtags = range.split("-");
247229
for (String tag : tags) {
@@ -267,33 +249,6 @@ private static List<String> filterExtended(List<LanguageRange> priorityList,
267249
return list;
268250
}
269251

270-
/**
271-
* Removes the tag(s) which are falling in the extended exclusion range(s)
272-
* i.e range(s) with q=0 and returns the updated collection. If the extended
273-
* language ranges contains '*' as one of its non zero range then instead of
274-
* returning all the tags, remove those which are matching the range with
275-
* quality weight q=0.
276-
*/
277-
private static Collection<String> removeTagsMatchingExtendedZeroRange(
278-
List<LanguageRange> zeroRange, Collection<String> tags) {
279-
if (zeroRange.isEmpty()) {
280-
tags = removeDuplicates(tags);
281-
return tags;
282-
}
283-
284-
List<String> matchingTags = new ArrayList<>();
285-
for (String tag : tags) {
286-
// change to lowercase for case-insensitive matching
287-
String lowerCaseTag = tag.toLowerCase(Locale.ROOT);
288-
if (!shouldIgnoreFilterExtendedMatch(zeroRange, lowerCaseTag)
289-
&& !caseInsensitiveMatch(matchingTags, lowerCaseTag)) {
290-
matchingTags.add(tag); // preserve the case of the input tag
291-
}
292-
}
293-
294-
return matchingTags;
295-
}
296-
297252
/**
298253
* The tag which is falling in the extended exclusion range(s) should
299254
* not be considered as the matching tag. Ignores the tag matching with the

test/jdk/java/util/Locale/Bug7069824.java

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
2323

2424
/*
2525
* @test
26-
* @bug 7069824 8042360 8032842 8175539 8210443 8242010
26+
* @bug 7069824 8042360 8032842 8175539 8210443 8242010 8276302
2727
* @summary Verify implementation for Locale matching.
2828
* @run testng/othervm Bug7069824
2929
*/
@@ -208,27 +208,61 @@ Object[][] LFilterNPEData() {
208208
Object[][] LFilterTagsData() {
209209
return new Object[][] {
210210
// Range, LanguageTags, FilteringMode, Expected language tags
211+
{"fr-FR, fr-BG;q=0.8, *;q=0.5, en;q=0", "en-US, fr-FR, fr-CA, fr-BG",
212+
null, "fr-FR, fr-BG, fr-CA"},
213+
{"fr-FR, fr-*-BG;q=0.8, *;q=0.5, en;q=0", "en-US, fr-FR, fr-CA, fr-BG",
214+
null, "fr-FR, fr-BG, fr-CA"},
215+
211216
{"en;q=0.2, *;q=0.6, ja", "de-DE, en, ja-JP-hepburn, fr-JP, he",
212-
null, "de-DE, en, ja-JP-hepburn, fr-JP, he"},
217+
null, "ja-JP-hepburn, de-DE, en, fr-JP, he"},
213218
{"en;q=0.2, ja-JP, fr-JP", "de-DE, en, ja-JP-hepburn, fr, he",
214219
null, "ja-JP-hepburn, en"},
215220
{"en;q=0.2, ja-JP, fr-JP, iw", "de-DE, he, en, ja-JP-hepburn, fr, he-IL",
216221
null, "ja-JP-hepburn, he, he-IL, en"},
217222
{"en;q=0.2, ja-JP, fr-JP, he", "de-DE, en, ja-JP-hepburn, fr, iw-IL",
218223
null, "ja-JP-hepburn, iw-IL, en"},
224+
219225
{"de-DE", "de-DE, de-de, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, "
220226
+ "de-Latn-DE-1996, de-Deva-DE, de, de-x-DE, de-Deva",
221-
MAP_EXTENDED_RANGES, "de-DE, de-DE-x-goethe"},
227+
null, "de-DE, de-DE-x-goethe"},
228+
{"de-*-DE", "de-DE, de-de, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, "
229+
+ "de-Latn-DE-1996, de-Deva-DE, de, de-x-DE, de-Deva",
230+
null,
231+
"de-DE, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, "
232+
+ "de-Latn-DE-1996, de-Deva-DE"},
233+
222234
{"de-DE", "de-DE, de-de, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, "
223235
+ "de-Latn-DE-1996, de-Deva-DE, de, de-x-DE, de-Deva",
224236
EXTENDED_FILTERING,
225237
"de-DE, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, "
226-
+ "de-Latn-DE-1996, de-Deva-DE"},
238+
+ "de-Latn-DE-1996, de-Deva-DE"},
227239
{"de-*-DE", "de-DE, de-de, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, "
228240
+ "de-Latn-DE-1996, de-Deva-DE, de, de-x-DE, de-Deva",
229241
EXTENDED_FILTERING,
230242
"de-DE, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, "
231-
+ "de-Latn-DE-1996, de-Deva-DE"},
243+
+ "de-Latn-DE-1996, de-Deva-DE"},
244+
245+
{"de-DE", "de-DE, de-de, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, "
246+
+ "de-Latn-DE-1996, de-Deva-DE, de, de-x-DE, de-Deva",
247+
IGNORE_EXTENDED_RANGES,
248+
"de-DE, de-DE-x-goethe"},
249+
{"de-*-DE", "de-DE, de-de, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, "
250+
+ "de-Latn-DE-1996, de-Deva-DE, de, de-x-DE, de-Deva",
251+
IGNORE_EXTENDED_RANGES,
252+
""},
253+
254+
{"de-DE", "de-DE, de-de, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, "
255+
+ "de-Latn-DE-1996, de-Deva-DE, de, de-x-DE, de-Deva",
256+
MAP_EXTENDED_RANGES, "de-DE, de-DE-x-goethe"},
257+
{"de-*-DE", "de-DE, de-de, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, "
258+
+ "de-Latn-DE-1996, de-Deva-DE, de, de-x-DE, de-Deva",
259+
MAP_EXTENDED_RANGES, "de-DE, de-DE-x-goethe"},
260+
261+
{"de-DE", "de-DE, de-de, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, "
262+
+ "de-Latn-DE-1996, de-Deva-DE, de, de-x-DE, de-Deva",
263+
REJECT_EXTENDED_RANGES, "de-DE, de-DE-x-goethe"},
264+
265+
// The next test in this chain is in testLFilterTagsIAE.
232266
};
233267
}
234268

@@ -380,6 +414,15 @@ public void testLFilterTags(String ranges, String tags, FilteringMode mode, Stri
380414
ranges, tags, expectedTags, actualTags));
381415
}
382416

417+
@Test(expectedExceptions = IllegalArgumentException.class)
418+
public void testLFilterTagsIAE() {
419+
String ranges = "de-*-DE";
420+
String tags = "de-DE, de-de, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, "
421+
+ "de-Latn-DE-1996, de-Deva-DE, de, de-x-DE, de-Deva";
422+
List<LanguageRange> priorityList = LanguageRange.parse(ranges);
423+
showLanguageTags(Locale.filterTags(priorityList, generateLanguageTags(tags), REJECT_EXTENDED_RANGES));
424+
}
425+
383426
@Test(dataProvider = "LLookupData")
384427
public void testLLookup(String ranges, String tags, String expectedLocale) {
385428
List<LanguageRange> priorityList = LanguageRange.parse(ranges);

0 commit comments

Comments
 (0)