/* * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /* * @test * @bug 8285517 * @summary System.getenv() and argument don't return locale dependent data by JEP400 * @requires (os.family == "linux") * @modules jdk.charsets * @library /test/lib * @build jdk.test.lib.process.* * @run main i18nEnvArg */ import java.io.ByteArrayOutputStream; import java.io.PrintStream; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.nio.charset.Charset; import java.util.Arrays; import java.util.ArrayList; import java.util.HexFormat; import java.util.HashMap; import java.util.List; import java.util.Map; import jdk.test.lib.process.ProcessTools; public class i18nEnvArg { final static String EUC_JP_TEXT = "\u6F22\u5B57"; /* * Checks OS is Linux and OS has ja_JP.eucjp locale or not. * Sets EUC_JP's environment variable and argunments against ProcessBuilder */ public static void main(String[] args) throws Exception { ProcessBuilder pb; List cmds = new ArrayList<>(); cmds.addAll(List.of( "--add-modules=" + System.getProperty("test.modules"), "-classpath", System.getProperty("test.class.path"), "-Dtest.class.path=" + System.getProperty("test.class.path"), "-Dtest.modules=" + System.getProperty("test.modules"))); if (args.length == 0) { cmds.addAll( List.of("-Dtest.jdk=" + System.getProperty("test.jdk"), "i18nEnvArg", "Start")); } else { String jnuEncoding = System.getProperty("sun.jnu.encoding"); Charset dcs = jnuEncoding != null ? Charset.forName(jnuEncoding) : Charset.defaultCharset(); Charset cs = Charset.forName("x-euc-jp-linux"); if (!dcs.equals(cs)) { return; } cmds.addAll( List.of("--add-opens=java.base/java.lang=ALL-UNNAMED", "i18nEnvArg$Verify", EUC_JP_TEXT)); } pb = ProcessTools.createTestJvm(cmds); Map environ = pb.environment(); environ.clear(); environ.put("LANG", "ja_JP.eucjp"); if (args.length != 0) { environ.put(EUC_JP_TEXT, EUC_JP_TEXT); } ProcessTools.executeProcess(pb) .outputTo(System.out) .errorTo(System.err) .shouldHaveExitValue(0); } public static class Verify { private static String toReadable(String s) { if (s == null) return "null"; StringBuilder sb = new StringBuilder(); for(char ch : s.toCharArray()) { sb.append(String.format("\\u%04X", (int)ch)); } return sb.toString(); } /* * Verify environment variable and argument are encoded by Linux's * eucjp or not */ public static void main(String[] args) throws Exception { Charset cs = Charset.forName("x-euc-jp-linux"); byte[] euc = EUC_JP_TEXT.getBytes(cs); try ( ByteArrayOutputStream baos = new ByteArrayOutputStream(); PrintStream ps = new PrintStream(baos); ) { if (!EUC_JP_TEXT.equals(args[0])) { ps.println("argument EUC_JP_TEXT is:"); ps.println(" Actual: " + toReadable(args[0])); ps.println(" Expected: " + toReadable(EUC_JP_TEXT)); } String s = System.getenv(EUC_JP_TEXT); if (!EUC_JP_TEXT.equals(s)) { ps.println("getenv(\"EUC_JP_TEXT\") is:"); ps.println(" Actual: " + toReadable(s)); ps.println(" Expected: " + toReadable(EUC_JP_TEXT)); } else { try { Class ProcessEnvironment_cls = Class.forName("java.lang.ProcessEnvironment"); Field theEnvironment_fid = ProcessEnvironment_cls.getDeclaredField("theEnvironment"); theEnvironment_fid.setAccessible(true); HashMap theEnvironment = (HashMap) theEnvironment_fid.get(null); Class ExternalData_cls = Class.forName("java.lang.ProcessEnvironment$ExternalData"); Method getBytes_mid = ExternalData_cls.getDeclaredMethod("getBytes"); getBytes_mid.setAccessible(true); HexFormat hf = HexFormat.of() .withUpperCase() .withPrefix("\\x"); for (Object k : theEnvironment.keySet()) { if (EUC_JP_TEXT.equals(k.toString())) { byte[] ba = (byte[]) getBytes_mid.invoke(k, (Object[])null); if (!Arrays.equals(euc, ba)) { ps.println( "Variable EUC_JP_TEXT is encoded by:"); ps.println(" Actual: " + hf.formatHex(ba)); ps.println(" Expected: " + hf.formatHex(euc)); } ba = (byte[]) getBytes_mid.invoke( theEnvironment.get(k), (Object[])null); if (!Arrays.equals(euc, ba)) { ps.println( "Value EUC_JP_TEXT is encoded by:"); ps.println(" Actual: " + hf.formatHex(ba)); ps.println(" Expected: " + hf.formatHex(euc)); } } } } catch (Exception e) { ps.println( "Check ProcessEnvironment class implementation"); e.printStackTrace(ps); } } byte[] ba = baos.toByteArray(); if (ba.length > 0) { System.err.write(ba); System.exit(1); } } } } }