1 /* 2 * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 8038436 8158504 8065555 8167143 27 * @summary Test for changes in 8038436 28 * @modules java.base/sun.util.locale.provider 29 * java.base/sun.util.spi 30 * jdk.localedata 31 * @compile -XDignore.symbol.file Bug8038436.java 32 * @run main/othervm --limit-modules java.base Bug8038436 security 33 * @run main/othervm -Djava.locale.providers=COMPAT Bug8038436 availlocs 34 */ 35 36 import java.security.CodeSource; 37 import java.security.Permission; 38 import java.security.PermissionCollection; 39 import java.security.Permissions; 40 import java.security.Policy; 41 import java.security.ProtectionDomain; 42 import java.util.Arrays; 43 import java.util.Formatter; 44 import java.util.GregorianCalendar; 45 import java.util.List; 46 import java.util.Locale; 47 import java.util.stream.Collectors; 48 import sun.util.locale.provider.LocaleProviderAdapter; 49 50 public class Bug8038436 { 51 public static void main(String[] args) { 52 53 switch (args[0]) { 54 55 case "security": 56 securityTests(); 57 break; 58 case "availlocs": 59 availableLocalesTests(); 60 break; 61 default: 62 throw new RuntimeException("no test was specified."); 63 } 64 65 } 66 67 private static void securityTests() { 68 Policy.setPolicy(new MyPolicy()); 69 System.setSecurityManager(new SecurityManager()); 70 71 /* 72 * Test for AccessClassInPackage security exception. Confirms that 73 * exeption won't be thrown if an application sets a Permission that 74 * does not allow any RuntimePermission, on loading LocaleDataMetaInfo 75 * from jdk.localedata module. 76 */ 77 System.out.println(new Formatter(Locale.JAPAN).format("%1$tB %1$te, %1$tY", 78 new GregorianCalendar())); 79 80 /* 81 * Check only English/ROOT locales are returned if the jdk.localedata 82 * module is not loaded (implied by "--limit-modules java.base"). 83 */ 84 List<Locale> nonEnglishLocales= (Arrays.stream(Locale.getAvailableLocales()) 85 .filter(l -> (l != Locale.ROOT && !(l.getLanguage() == "en" && (l.getCountry() == "US" || l.getCountry() == "" )))) 86 .collect(Collectors.toList())); 87 88 if (!nonEnglishLocales.isEmpty()) { 89 throw new RuntimeException("non English locale(s)" + nonEnglishLocales + " included in available locales"); 90 } 91 } 92 93 94 static class MyPolicy extends Policy { 95 final PermissionCollection perms = new Permissions(); 96 97 MyPolicy() { 98 // allows no RuntimePermission 99 } 100 101 public PermissionCollection getPermissions(ProtectionDomain domain) { 102 return perms; 103 } 104 105 public PermissionCollection getPermissions(CodeSource codesource) { 106 return perms; 107 } 108 109 public boolean implies(ProtectionDomain domain, Permission perm) { 110 return perms.implies(perm); 111 } 112 } 113 114 static final String[] bipLocs = ("ar, ar-JO, ar-LB, ar-SY, be, be-BY, bg, " + 115 "bg-BG, ca, ca-ES, cs, cs-CZ, da, da-DK, de, de-AT, de-CH, de-DE, " + 116 "de-LU, el, el-CY, el-GR, en, en-AU, en-CA, en-GB, en-IE, en-IN, " + 117 "en-MT, en-NZ, en-PH, en-SG, en-US, en-ZA, es, es-AR, es-BO, es-CL, " + 118 "es-CO, es-CR, es-DO, es-EC, es-ES, es-GT, es-HN, es-MX, es-NI, " + 119 "es-PA, es-PE, es-PR, es-PY, es-SV, es-US, es-UY, es-VE, et, et-EE, " + 120 "fi, fi-FI, fr, fr-BE, fr-CA, fr-CH, fr-FR, ga, ga-IE, he, he-IL, " + 121 "hi-IN, hr, hr-HR, hu, hu-HU, id, id-ID, is, is-IS, it, it-CH, it-IT, " + 122 "ja, ja-JP, ko, ko-KR, lt, lt-LT, lv, lv-LV, mk, mk-MK, ms, ms-MY, mt, " + 123 "mt-MT, nb-NO, nl, nl-BE, nl-NL, nn-NO, no, no-NO, no-NO, pl, pl-PL, pt, pt-BR, " + 124 "pt-PT, ro, ro-RO, ru, ru-RU, sk, sk-SK, sl, sl-SI, sq, sq-AL, sr, " + 125 "sr-BA, sr-CS, sr-Latn, sr-Latn-ME, sr-ME, sr-RS, sv, sv-SE, th, th-TH, " + 126 "tr, tr-TR, uk, uk-UA, und, vi, vi-VN, zh, zh-CN, zh-HK, zh-Hans-CN, " + 127 "zh-Hans-SG, zh-Hant-HK, zh-Hant-TW, zh-SG, zh-TW, ").split(",\\s*"); 128 static final String[] dfpLocs = bipLocs; 129 static final String[] datefspLocs = bipLocs; 130 static final String[] decimalfspLocs = bipLocs; 131 static final String[] calnpLocs = bipLocs; 132 static final String[] cpLocs = ("ar, be, bg, ca, cs, da, el, es, et, fi, " + 133 "fr, he, hi, hr, hu, is, ja, ko, lt, lv, mk, nb-NO, nn-NO, no, pl, ro, ru, sk, sl, " + 134 "sq, sr, sr-Latn, sv, th, tr, uk, und, vi, zh, zh-HK, zh-Hant-HK, " + 135 "zh-Hant-TW, zh-TW, ").split(",\\s*"); 136 static final String[] nfpLocs = ("ar, ar-AE, ar-BH, ar-DZ, ar-EG, ar-IQ, " + 137 "ar-JO, ar-KW, ar-LB, ar-LY, ar-MA, ar-OM, ar-QA, ar-SA, ar-SD, ar-SY, " + 138 "ar-TN, ar-YE, be, be-BY, bg, bg-BG, ca, ca-ES, cs, cs-CZ, da, da-DK, " + 139 "de, de-AT, de-CH, de-DE, de-LU, el, el-CY, el-GR, en, en-AU, " + 140 "en-CA, en-GB, en-IE, en-IN, en-MT, en-NZ, en-PH, en-SG, en-US, en-ZA, " + 141 "es, es-AR, es-BO, es-CL, es-CO, es-CR, es-CU, es-DO, es-EC, es-ES, " + 142 "es-GT, es-HN, es-MX, es-NI, es-PA, es-PE, es-PR, es-PY, es-SV, es-US, " + 143 "es-UY, es-VE, et, et-EE, fi, fi-FI, fr, fr-BE, fr-CA, fr-CH, fr-FR, " + 144 "fr-LU, ga, ga-IE, he, he-IL, hi, hi-IN, hr, hr-HR, hu, hu-HU, id, " + 145 "id-ID, is, is-IS, it, it-CH, it-IT, ja, ja-JP, " + 146 "ja-JP-u-ca-japanese-x-lvariant-JP, ko, ko-KR, lt, lt-LT, lv, lv-LV, " + 147 "mk, mk-MK, ms, ms-MY, mt, mt-MT, nb-NO, nl, nl-BE, nl-NL, nn-NO, " + 148 "nn-NO, no, no-NO, pl, pl-PL, pt, pt-BR, pt-PT, ro, ro-RO, ru, ru-RU, " + 149 "sk, sk-SK, sl, sl-SI, sq, sq-AL, sr, sr-BA, sr-CS, sr-Latn, " + 150 "sr-Latn-BA, sr-Latn-ME, sr-Latn-RS, sr-ME, sr-RS, sv, sv-SE, th, " + 151 "th-TH, th-TH-u-nu-thai-x-lvariant-TH, tr, tr-TR, uk, uk-UA, und, vi, " + 152 "vi-VN, zh, zh-CN, zh-HK, zh-Hans-CN, zh-Hans-SG, zh-Hant-HK, " + 153 "zh-Hant-TW, zh-SG, zh-TW, ").split(",\\s*"); 154 static final String[] currencynpLocs = ("ar-AE, ar-BH, ar-DZ, ar-EG, ar-IQ, " + 155 "ar-JO, ar-KW, ar-LB, ar-LY, ar-MA, ar-OM, ar-QA, ar-SA, ar-SD, ar-SY, " + 156 "ar-TN, ar-YE, be-BY, bg-BG, ca-ES, cs-CZ, da-DK, de, de-AT, de-CH, " + 157 "de-DE, de-LU, el-CY, el-GR, en-AU, en-CA, en-GB, en-IE, en-IN, " + 158 "en-MT, en-NZ, en-PH, en-SG, en-US, en-ZA, es, es-AR, es-BO, es-CL, " + 159 "es-CO, es-CR, es-CU, es-DO, es-EC, es-ES, es-GT, es-HN, es-MX, es-NI, " + 160 "es-PA, es-PE, es-PR, es-PY, es-SV, es-US, es-UY, es-VE, et-EE, fi-FI, " + 161 "fr, fr-BE, fr-CA, fr-CH, fr-FR, fr-LU, ga-IE, he-IL, hi-IN, hr-HR, " + 162 "hu-HU, id-ID, is-IS, it, it-CH, it-IT, ja, ja-JP, ko, ko-KR, lt-LT, " + 163 "lv-LV, mk-MK, ms-MY, mt-MT, nb-NO, nl-BE, nl-NL, nn-NO, no-NO, pl-PL, pt, pt-BR, " + 164 "pt-PT, ro-RO, ru-RU, sk-SK, sl-SI, sq-AL, sr-BA, sr-CS, sr-Latn-BA, " + 165 "sr-Latn-ME, sr-Latn-RS, sr-ME, sr-RS, sv, sv-SE, th-TH, tr-TR, uk-UA, " + 166 "und, vi-VN, zh-CN, zh-HK, zh-Hans-CN, zh-Hans-SG, zh-Hant-HK, " + 167 "zh-Hant-TW, zh-SG, zh-TW, ").split(",\\s*"); 168 static final String[] lnpLocs = ("ar, be, bg, ca, cs, da, de, el, el-CY, " + 169 "en, en-MT, en-PH, en-SG, es, es-US, et, fi, fr, ga, he, hi, hr, hu, " + 170 "id, is, it, ja, ko, lt, lv, mk, ms, mt, nb-NO, nl, nn-NO, no, no-NO, pl, pt, pt-BR, " + 171 "pt-PT, ro, ru, sk, sl, sq, sr, sr-Latn, sv, th, tr, uk, und, vi, zh, " + 172 "zh-HK, zh-Hans-SG, zh-Hant-HK, zh-Hant-TW, zh-SG, zh-TW, ").split(",\\s*"); 173 static final String[] tznpLocs = ("de, en, en-CA, en-GB, en-IE, es, fr, hi, " + 174 "it, ja, ko, nb-NO, nn-NO, pt-BR, sv, und, zh-CN, zh-HK, zh-Hans-CN, zh-Hant-HK, " + 175 "zh-Hant-TW, zh-TW, ").split(",\\s*"); 176 static final String[] caldpLocs = ("ar, be, bg, ca, cs, da, de, el, el-CY, " + 177 "en, en-GB, en-IE, en-MT, es, es-ES, es-US, et, fi, fr, fr-CA, he, hi, " + 178 "hr, hu, id-ID, is, it, ja, ko, lt, lv, mk, ms-MY, mt, mt-MT, nb-NO, nl, nn-NO, no, " + 179 "pl, pt, pt-BR, pt-PT, ro, ru, sk, sl, sq, sr, sr-Latn-BA, sr-Latn-ME, " + 180 "sr-Latn-RS, sv, th, tr, uk, und, vi, zh, ").split(",\\s*"); 181 static final String[] calpLocs = caldpLocs; 182 183 /* 184 * Validate whether JRE's *Providers return supported locales list based on 185 * their actual resource bundle exsistence. The above golden data 186 * are manually extracted, so they need to be updated if new locale 187 * data resource bundle were added. 188 */ 189 private static void availableLocalesTests() { 190 LocaleProviderAdapter jre = LocaleProviderAdapter.forJRE(); 191 192 checkAvailableLocales("BreakIteratorProvider", 193 jre.getBreakIteratorProvider().getAvailableLocales(), bipLocs); 194 checkAvailableLocales("CollatorProvider", 195 jre.getCollatorProvider().getAvailableLocales(), cpLocs); 196 checkAvailableLocales("DateFormatProvider", 197 jre.getDateFormatProvider().getAvailableLocales(), dfpLocs); 198 checkAvailableLocales("DateFormatSymbolsProvider", 199 jre.getDateFormatSymbolsProvider().getAvailableLocales(), datefspLocs); 200 checkAvailableLocales("DecimalFormatSymbolsProvider", 201 jre.getDecimalFormatSymbolsProvider().getAvailableLocales(), decimalfspLocs); 202 checkAvailableLocales("NumberFormatProvider", 203 jre.getNumberFormatProvider().getAvailableLocales(), nfpLocs); 204 checkAvailableLocales("CurrencyNameProvider", 205 jre.getCurrencyNameProvider().getAvailableLocales(), currencynpLocs); 206 checkAvailableLocales("LocaleNameProvider", 207 jre.getLocaleNameProvider().getAvailableLocales(), lnpLocs); 208 checkAvailableLocales("TimeZoneNameProvider", 209 jre.getTimeZoneNameProvider().getAvailableLocales(), tznpLocs); 210 checkAvailableLocales("CalendarDataProvider", 211 jre.getCalendarDataProvider().getAvailableLocales(), caldpLocs); 212 checkAvailableLocales("CalendarNameProvider", 213 jre.getCalendarNameProvider().getAvailableLocales(), calnpLocs); 214 checkAvailableLocales("CalendarProvider", 215 jre.getCalendarProvider().getAvailableLocales(), calpLocs); 216 } 217 218 private static void checkAvailableLocales(String testName, Locale[] got, String[] expected) { 219 System.out.println("Testing available locales for " + testName); 220 List<Locale> gotList = Arrays.asList(got).stream() 221 .map(Locale::toLanguageTag) 222 .sorted() 223 .map(Locale::forLanguageTag) 224 .collect(Collectors.toList()); 225 List<Locale> expectedList = Arrays.asList(expected).stream() 226 .map(Locale::forLanguageTag) 227 .collect(Collectors.toList()); 228 229 if (!gotList.equals(expectedList)) { 230 throw new RuntimeException("\n" + gotList.toString() + "\n is not equal to \n" + 231 expectedList.toString()); 232 } 233 } 234 }