diff --git a/src/java.base/share/classes/jdk/internal/io/JdkConsoleImpl.java b/src/java.base/share/classes/jdk/internal/io/JdkConsoleImpl.java index 7930e00fbc059..a1086b245d1b6 100644 --- a/src/java.base/share/classes/jdk/internal/io/JdkConsoleImpl.java +++ b/src/java.base/share/classes/jdk/internal/io/JdkConsoleImpl.java @@ -127,7 +127,9 @@ public char[] readPassword(Locale locale, String format, Object ... args) { synchronized(readLock) { installShutdownHook(); try { - restoreEcho = echo(false); + synchronized(restoreEchoLock) { + restoreEcho = echo(false); + } } catch (IOException x) { throw new IOError(x); } @@ -140,8 +142,11 @@ public char[] readPassword(Locale locale, String format, Object ... args) { ioe = new IOError(x); } finally { try { - if (restoreEcho) - restoreEcho = echo(true); + synchronized(restoreEchoLock) { + if (restoreEcho) { + restoreEcho = echo(true); + } + } } catch (IOException x) { if (ioe == null) ioe = new IOError(x); @@ -154,7 +159,7 @@ public char[] readPassword(Locale locale, String format, Object ... args) { if (reader instanceof LineReader lr) { lr.zeroOut(); } - } catch (IOException x) { + } catch (IOException _) { // ignore } throw ioe; @@ -178,13 +183,15 @@ private void installShutdownHook() { new Runnable() { public void run() { try { - if (restoreEcho) { - echo(true); + synchronized(restoreEchoLock) { + if (restoreEcho) { + echo(true); + } } - } catch (IOException x) { } + } catch (IOException _) { } } }); - } catch (IllegalStateException e) { + } catch (IllegalStateException _) { // shutdown is already in progress and readPassword is first used // by a shutdown hook } @@ -209,6 +216,8 @@ public Charset charset() { private final Charset charset; private final Object readLock; private final Object writeLock; + // Must not block while holding this. It is used in the shutdown hook. + private final Object restoreEchoLock; private final Reader reader; private final Writer out; private final PrintWriter pw; @@ -379,6 +388,7 @@ public JdkConsoleImpl(Charset charset) { this.charset = charset; readLock = new Object(); writeLock = new Object(); + restoreEchoLock = new Object(); out = StreamEncoder.forOutputStreamWriter( new FileOutputStream(FileDescriptor.out), writeLock,