8332065: Calling readLine(null...) or readPassword(null...) on System.console() hangs jshell

Reviewed-by: prappo
This commit is contained in:
Jan Lahoda 2024-05-30 06:02:42 +00:00
parent 9a72068ef0
commit 57bfd0e393
2 changed files with 25 additions and 6 deletions

View File

@ -35,6 +35,7 @@ import java.io.Writer;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Locale;
import java.util.Objects;
import jdk.internal.io.JdkConsole;
import jdk.internal.io.JdkConsoleProvider;
@ -218,10 +219,11 @@ public class ConsoleImpl {
*/
@Override
public String readln(String prompt) {
char[] chars = (prompt == null ? "null" : prompt).toCharArray();
try {
return sendAndReceive(() -> {
remoteInput.write(Task.READ_LINE.ordinal());
char[] chars = (prompt == null ? "null" : prompt).toCharArray();
sendChars(chars, 0, chars.length);
char[] line = readChars();
return new String(line);
@ -245,11 +247,14 @@ public class ConsoleImpl {
*/
@Override
public String readLine(Locale locale, String format, Object... args) {
Objects.requireNonNull(format, "the format String must be non-null");
String prompt = String.format(locale, format, args);
char[] chars = prompt.toCharArray();
try {
return sendAndReceive(() -> {
remoteInput.write(Task.READ_LINE.ordinal());
String prompt = String.format(locale, format, args);
char[] chars = prompt.toCharArray();
sendChars(chars, 0, chars.length);
char[] line = readChars();
return new String(line);
@ -272,11 +277,14 @@ public class ConsoleImpl {
*/
@Override
public char[] readPassword(Locale locale, String format, Object... args) {
Objects.requireNonNull(format, "the format String must be non-null");
String prompt = String.format(locale, format, args);
char[] chars = prompt.toCharArray();
try {
return sendAndReceive(() -> {
remoteInput.write(Task.READ_PASSWORD.ordinal());
String prompt = String.format(locale, format, args);
char[] chars = prompt.toCharArray();
sendChars(chars, 0, chars.length);
return readChars();
});

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2023, 2024, 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
@ -40,8 +40,10 @@ import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
import jdk.jshell.EvalException;
import jdk.jshell.JShell;
import jdk.jshell.JShellConsole;
import jdk.jshell.Snippet.Status;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
@ -183,6 +185,15 @@ public class ConsoleTest extends KullaTesting {
assertEquals(sb.toString(), expected);
}
@Test
public void testNPE() {
console = new ThrowingJShellConsole();
assertEval("System.console().readLine(null)", DiagCheck.DIAG_OK, DiagCheck.DIAG_OK, chain(added(Status.VALID), null, EvalException.class));
assertEval("System.console().readPassword(null)", DiagCheck.DIAG_OK, DiagCheck.DIAG_OK, chain(added(Status.VALID), null, EvalException.class));
assertEval("System.console().readLine(\"%d\", \"\")", DiagCheck.DIAG_OK, DiagCheck.DIAG_OK, chain(added(Status.VALID), null, EvalException.class));
assertEval("System.console().readPassword(\"%d\", \"\")", DiagCheck.DIAG_OK, DiagCheck.DIAG_OK, chain(added(Status.VALID), null, EvalException.class));
}
@Override
public void setUp(Consumer<JShell.Builder> bc) {
super.setUp(bc.andThen(b -> b.console(new JShellConsole() {