From eacfcd86d38f4acf0165275a42d246ba6c5fae56 Mon Sep 17 00:00:00 2001 From: Volkan Yazici Date: Mon, 16 Jun 2025 07:27:05 +0000 Subject: [PATCH] 8357995: Use "stdin.encoding" for reading System.in with InputStreamReader/Scanner [core] Reviewed-by: naoto, cjplummer --- .../sun/security/tools/keytool/Main.java | 23 ++-- .../security/util/ConsoleCallbackHandler.java | 8 +- .../com/sun/tools/script/shell/Main.java | 12 +- .../javax/script/SimpleScriptContext.java | 10 +- .../security/krb5/internal/tools/Ktab.java | 16 ++- .../com/sun/tools/example/debug/tty/TTY.java | 7 +- .../jdk/com/sun/jdi/MultiBreakpointsTest.java | 104 ++++++++---------- .../security/sasl/ClientCallbackHandler.java | 4 +- .../sasl/digest/ClientCallbackHandler.java | 4 +- test/jdk/java/lang/ProcessBuilder/Basic.java | 2 +- .../jdk/java/nio/charset/spi/CharsetTest.java | 9 +- 11 files changed, 102 insertions(+), 97 deletions(-) diff --git a/src/java.base/share/classes/sun/security/tools/keytool/Main.java b/src/java.base/share/classes/sun/security/tools/keytool/Main.java index 89cad63dc65..6bea35a996f 100644 --- a/src/java.base/share/classes/sun/security/tools/keytool/Main.java +++ b/src/java.base/share/classes/sun/security/tools/keytool/Main.java @@ -26,6 +26,7 @@ package sun.security.tools.keytool; import java.io.*; +import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; import java.security.*; @@ -1473,7 +1474,7 @@ public final class Main { info.setVersion(new CertificateVersion(CertificateVersion.V3)); info.setIssuer(issuer); - BufferedReader reader = new BufferedReader(new InputStreamReader(in)); + BufferedReader reader = stdinAwareReader(in); boolean canRead = false; StringBuilder sb = new StringBuilder(); while (true) { @@ -2828,7 +2829,7 @@ public final class Main { private void doPrintCertReq(InputStream in, PrintStream out) throws Exception { - BufferedReader reader = new BufferedReader(new InputStreamReader(in)); + BufferedReader reader = stdinAwareReader(in); StringBuilder sb = new StringBuilder(); boolean started = false; while (true) { @@ -3533,8 +3534,7 @@ public final class Main { } else { System.err.print(rb.getString("Enter.alias.name.")); } - return (new BufferedReader(new InputStreamReader( - System.in))).readLine(); + return stdinAwareReader(System.in).readLine(); } /** @@ -3544,8 +3544,14 @@ public final class Main { */ private String inputStringFromStdin(String prompt) throws Exception { System.err.print(prompt); - return (new BufferedReader(new InputStreamReader( - System.in))).readLine(); + return stdinAwareReader(System.in).readLine(); + } + + private static BufferedReader stdinAwareReader(InputStream in) { + InputStreamReader reader = in == System.in + ? new InputStreamReader(in, Charset.forName(System.getProperty("stdin.encoding"), Charset.defaultCharset())) + : new InputStreamReader(in); + return new BufferedReader(reader); } /** @@ -3732,7 +3738,7 @@ public final class Main { */ private X500Name getX500Name() throws IOException { BufferedReader in; - in = new BufferedReader(new InputStreamReader(System.in)); + in = stdinAwareReader(System.in); String commonName = "Unknown"; String organizationalUnit = "Unknown"; String organization = "Unknown"; @@ -4238,8 +4244,7 @@ public final class Main { } System.err.print(prompt); System.err.flush(); - reply = (new BufferedReader(new InputStreamReader - (System.in))).readLine(); + reply = stdinAwareReader(System.in).readLine(); if (reply == null || collator.compare(reply, "") == 0 || collator.compare(reply, rb.getString("n")) == 0 || diff --git a/src/java.base/share/classes/sun/security/util/ConsoleCallbackHandler.java b/src/java.base/share/classes/sun/security/util/ConsoleCallbackHandler.java index 83ac503b460..66140824bec 100644 --- a/src/java.base/share/classes/sun/security/util/ConsoleCallbackHandler.java +++ b/src/java.base/share/classes/sun/security/util/ConsoleCallbackHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, 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 @@ -36,6 +36,7 @@ import javax.security.auth.callback.UnsupportedCallbackException; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; +import java.nio.charset.Charset; /** * A {@code CallbackHandler} that prompts and reads from the command line @@ -130,8 +131,9 @@ public class ConsoleCallbackHandler implements CallbackHandler { /* Reads a line of input */ private String readLine() throws IOException { - String result = new BufferedReader - (new InputStreamReader(System.in)).readLine(); + Charset charset = Charset.forName(System.getProperty("stdin.encoding"), Charset.defaultCharset()); + InputStreamReader reader = new InputStreamReader(System.in, charset); + String result = new BufferedReader(reader).readLine(); if (result == null) { throw new IOException("Cannot read from System.in"); } diff --git a/src/java.scripting/share/classes/com/sun/tools/script/shell/Main.java b/src/java.scripting/share/classes/com/sun/tools/script/shell/Main.java index f1ac21bbfbb..96fd6d010ac 100644 --- a/src/java.scripting/share/classes/com/sun/tools/script/shell/Main.java +++ b/src/java.scripting/share/classes/com/sun/tools/script/shell/Main.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, 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 @@ -27,6 +27,7 @@ package com.sun.tools.script.shell; import java.io.*; import java.net.*; +import java.nio.charset.Charset; import java.text.*; import java.util.*; import javax.script.*; @@ -255,8 +256,8 @@ public class Main { private static void processSource(ScriptEngine se, String filename, String encoding) { if (filename.equals("-")) { - BufferedReader in = new BufferedReader - (new InputStreamReader(getIn())); + Charset charset = Charset.forName(System.getProperty("stdin.encoding"), Charset.defaultCharset()); + BufferedReader in = new BufferedReader(new InputStreamReader(System.in, charset)); boolean hitEOF = false; String prompt = getPrompt(se); se.put(ScriptEngine.FILENAME, ""); @@ -402,11 +403,6 @@ public class Main { return MessageFormat.format(msgRes.getString(key), params); } - // input stream from where we will read - private static InputStream getIn() { - return System.in; - } - // stream to print error messages private static PrintStream getError() { return System.err; diff --git a/src/java.scripting/share/classes/javax/script/SimpleScriptContext.java b/src/java.scripting/share/classes/javax/script/SimpleScriptContext.java index 5fcb0209107..89f5978601f 100644 --- a/src/java.scripting/share/classes/javax/script/SimpleScriptContext.java +++ b/src/java.scripting/share/classes/javax/script/SimpleScriptContext.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, 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 @@ -25,6 +25,7 @@ package javax.script; +import java.nio.charset.Charset; import java.util.*; import java.io.*; @@ -86,13 +87,18 @@ public class SimpleScriptContext implements ScriptContext { * Create a {@code SimpleScriptContext}. */ public SimpleScriptContext() { - this(new InputStreamReader(System.in), + this(stdinReader(), new PrintWriter(System.out , true), new PrintWriter(System.err, true)); engineScope = new SimpleBindings(); globalScope = null; } + private static InputStreamReader stdinReader() { + Charset charset = Charset.forName(System.getProperty("stdin.encoding"), Charset.defaultCharset()); + return new InputStreamReader(System.in, charset); + } + /** * Package-private constructor to avoid needless creation of reader and writers. * It is the caller's responsibility to initialize the engine scope. diff --git a/src/java.security.jgss/windows/classes/sun/security/krb5/internal/tools/Ktab.java b/src/java.security.jgss/windows/classes/sun/security/krb5/internal/tools/Ktab.java index 21002f3369a..ffe2e3196c1 100644 --- a/src/java.security.jgss/windows/classes/sun/security/krb5/internal/tools/Ktab.java +++ b/src/java.security.jgss/windows/classes/sun/security/krb5/internal/tools/Ktab.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -35,6 +35,8 @@ import sun.security.krb5.internal.ktab.*; import java.io.IOException; import java.io.BufferedReader; import java.io.InputStreamReader; +import java.io.Reader; +import java.nio.charset.Charset; import java.text.DateFormat; import java.util.Arrays; import java.util.Date; @@ -304,8 +306,7 @@ public class Ktab { } if (password == null) { try { - BufferedReader cis = - new BufferedReader(new InputStreamReader(System.in)); + BufferedReader cis = stdinReader(); System.out.print("Password for " + pname.toString() + ":"); System.out.flush(); password = cis.readLine().toCharArray(); @@ -403,6 +404,12 @@ public class Ktab { } } + private static BufferedReader stdinReader() { + Charset charset = Charset.forName(System.getProperty("stdin.encoding"), Charset.defaultCharset()); + Reader reader = new InputStreamReader(System.in, charset); + return new BufferedReader(reader); + } + /** * Deletes an entry from the key table. */ @@ -412,8 +419,7 @@ public class Ktab { pname = new PrincipalName(principal); if (!fopt) { String answer; - BufferedReader cis = - new BufferedReader(new InputStreamReader(System.in)); + BufferedReader cis = stdinReader(); System.out.print("Are you sure you want to delete "+ "service key(s) for " + pname.toString() + " (" + (etype==-1?"all etypes":("etype="+etype)) + ", " + diff --git a/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/TTY.java b/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/TTY.java index acdd6c45f6e..94d06363dd1 100644 --- a/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/TTY.java +++ b/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/TTY.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, 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 @@ -39,6 +39,7 @@ import com.sun.jdi.event.*; import com.sun.jdi.request.*; import com.sun.jdi.connect.*; +import java.nio.charset.Charset; import java.util.*; import java.util.concurrent.CopyOnWriteArrayList; import java.io.*; @@ -796,8 +797,8 @@ public class TTY implements EventNotifier { this.handler = new EventHandler(this, true, trackVthreads); } try { - BufferedReader in = - new BufferedReader(new InputStreamReader(System.in)); + Charset charset = Charset.forName(System.getProperty("stdin.encoding"), Charset.defaultCharset()); + BufferedReader in = new BufferedReader(new InputStreamReader(System.in, charset)); Thread.currentThread().setPriority(Thread.NORM_PRIORITY); diff --git a/test/jdk/com/sun/jdi/MultiBreakpointsTest.java b/test/jdk/com/sun/jdi/MultiBreakpointsTest.java index 6304aef96b9..bdbe36e7860 100644 --- a/test/jdk/com/sun/jdi/MultiBreakpointsTest.java +++ b/test/jdk/com/sun/jdi/MultiBreakpointsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, 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 @@ -50,13 +50,8 @@ import com.sun.jdi.*; import com.sun.jdi.event.*; import com.sun.jdi.request.*; -import java.util.*; - /********** target program **********/ -import java.io.*; -import java.text.*; - class MultiBreakpointsTarg { MultiBreakpointsTarg(int numThreads, int numHits) { @@ -136,66 +131,57 @@ class MultiBreakpointsTarg { void bkpt29() {} Thread console(final int num, final int nhits) { - final InputStreamReader isr = new InputStreamReader(System.in); - final BufferedReader br = new BufferedReader(isr); - // Create the threads // //final String threadName = "DebuggeeThread: " + num; final String threadName = "" + num; Thread thrd = DebuggeeWrapper.newThread(() -> { - synchronized( isr ) { - boolean done = false; - try { - // For each thread, run until numHits bkpts have been hit - for( int i = 0; i < nhits; i++ ) { - // This is a tendril from the original jdb test. - // It could probably be deleted. - System.out.println("Thread " + threadName + " Enter a string: "); - String s = "test" + num; - switch (num) { - case 0: bkpt0(); break; - case 1: bkpt1(); break; - case 2: bkpt2(); break; - case 3: bkpt3(); break; - case 4: bkpt4(); break; - case 5: bkpt5(); break; - case 6: bkpt6(); break; - case 7: bkpt7(); break; - case 8: bkpt8(); break; - case 9: bkpt9(); break; - case 10: bkpt10(); break; - case 11: bkpt11(); break; - case 12: bkpt12(); break; - case 13: bkpt13(); break; - case 14: bkpt14(); break; - case 15: bkpt15(); break; - case 16: bkpt16(); break; - case 17: bkpt17(); break; - case 18: bkpt18(); break; - case 19: bkpt19(); break; - case 20: bkpt20(); break; - case 21: bkpt21(); break; - case 22: bkpt22(); break; - case 23: bkpt23(); break; - case 24: bkpt24(); break; - case 25: bkpt25(); break; - case 26: bkpt26(); break; - case 27: bkpt27(); break; - case 28: bkpt28(); break; - case 29: bkpt29(); break; - } - System.out.println("Thread " + threadName + " You entered : " + s); - - if( s.compareTo( "quit" ) == 0 ) - done = true; - } - } catch(Exception e) { - System.out.println("WOOPS"); - } + try { + // For each thread, run until numHits bkpts have been hit + for( int i = 0; i < nhits; i++ ) { + // This is a tendril from the original jdb test. + // It could probably be deleted. + System.out.println("Thread " + threadName + " Enter a string: "); + String s = "test" + num; + switch (num) { + case 0: bkpt0(); break; + case 1: bkpt1(); break; + case 2: bkpt2(); break; + case 3: bkpt3(); break; + case 4: bkpt4(); break; + case 5: bkpt5(); break; + case 6: bkpt6(); break; + case 7: bkpt7(); break; + case 8: bkpt8(); break; + case 9: bkpt9(); break; + case 10: bkpt10(); break; + case 11: bkpt11(); break; + case 12: bkpt12(); break; + case 13: bkpt13(); break; + case 14: bkpt14(); break; + case 15: bkpt15(); break; + case 16: bkpt16(); break; + case 17: bkpt17(); break; + case 18: bkpt18(); break; + case 19: bkpt19(); break; + case 20: bkpt20(); break; + case 21: bkpt21(); break; + case 22: bkpt22(); break; + case 23: bkpt23(); break; + case 24: bkpt24(); break; + case 25: bkpt25(); break; + case 26: bkpt26(); break; + case 27: bkpt27(); break; + case 28: bkpt28(); break; + case 29: bkpt29(); break; } + System.out.println("Thread " + threadName + " You entered : " + s); + } - ); + } catch (Exception e) { + System.out.println("WOOPS"); + } + }); thrd.setName(threadName); thrd.setPriority(Thread.MAX_PRIORITY-1); thrd.start(); diff --git a/test/jdk/com/sun/security/sasl/ClientCallbackHandler.java b/test/jdk/com/sun/security/sasl/ClientCallbackHandler.java index 33a4be4823a..23ee550a2a7 100644 --- a/test/jdk/com/sun/security/sasl/ClientCallbackHandler.java +++ b/test/jdk/com/sun/security/sasl/ClientCallbackHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -130,6 +130,6 @@ public final class ClientCallbackHandler extends TextCallbackHandler { /* Reads a line of input */ private String readLine() throws IOException { return new BufferedReader - (new InputStreamReader(System.in)).readLine(); + (new InputStreamReader(System.in, System.getProperty("stdin.encoding"))).readLine(); } } diff --git a/test/jdk/com/sun/security/sasl/digest/ClientCallbackHandler.java b/test/jdk/com/sun/security/sasl/digest/ClientCallbackHandler.java index 33a4be4823a..23ee550a2a7 100644 --- a/test/jdk/com/sun/security/sasl/digest/ClientCallbackHandler.java +++ b/test/jdk/com/sun/security/sasl/digest/ClientCallbackHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -130,6 +130,6 @@ public final class ClientCallbackHandler extends TextCallbackHandler { /* Reads a line of input */ private String readLine() throws IOException { return new BufferedReader - (new InputStreamReader(System.in)).readLine(); + (new InputStreamReader(System.in, System.getProperty("stdin.encoding"))).readLine(); } } diff --git a/test/jdk/java/lang/ProcessBuilder/Basic.java b/test/jdk/java/lang/ProcessBuilder/Basic.java index ed9a0f9fb70..1995e9cecd1 100644 --- a/test/jdk/java/lang/ProcessBuilder/Basic.java +++ b/test/jdk/java/lang/ProcessBuilder/Basic.java @@ -337,7 +337,7 @@ public class Basic { } else if (action.equals("testIO")) { String expected = "standard input"; char[] buf = new char[expected.length()+1]; - int n = new InputStreamReader(System.in).read(buf,0,buf.length); + int n = new InputStreamReader(System.in, System.getProperty("stdin.encoding")).read(buf,0,buf.length); if (n != expected.length()) System.exit(5); if (! new String(buf,0,n).equals(expected)) diff --git a/test/jdk/java/nio/charset/spi/CharsetTest.java b/test/jdk/java/nio/charset/spi/CharsetTest.java index 4ac3d14b1d3..c6932d36bd7 100644 --- a/test/jdk/java/nio/charset/spi/CharsetTest.java +++ b/test/jdk/java/nio/charset/spi/CharsetTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2025, 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 @@ -21,6 +21,7 @@ * questions. */ +import java.io.ByteArrayInputStream; import java.io.InputStreamReader; import java.io.PrintStream; import java.nio.charset.Charset; @@ -72,8 +73,10 @@ public class CharsetTest { public static void main(String [] args) { - out.println("Default: " - + new InputStreamReader(System.in).getEncoding()); + for (String property : new String[]{"stdin.encoding", "stdout.encoding", "stderr.encoding"}) { + String name = System.getProperty(property); + out.printf("%s: %s (%s)%n", property, name, Charset.forName(name)); + } out.print("Available:"); for (Iterator i = available.keySet().iterator(); i.hasNext();)