Skip to content

Commit

Permalink
8332065: Calling readLine(null...) or readPassword(null...) on System…
Browse files Browse the repository at this point in the history
….console() hangs jshell

Reviewed-by: prappo
  • Loading branch information
lahodaj committed May 30, 2024
1 parent 9a72068 commit 57bfd0e
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
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;
Expand Down Expand Up @@ -218,10 +219,11 @@ public JdkConsole print(Object obj) {
*/
@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);
Expand All @@ -245,11 +247,14 @@ public JdkConsole format(Locale locale, String format, Object... args) {
*/
@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);
Expand All @@ -272,11 +277,14 @@ public String readLine() {
*/
@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();
});
Expand Down
13 changes: 12 additions & 1 deletion test/langtools/jdk/jshell/ConsoleTest.java
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -40,8 +40,10 @@
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.*;
Expand Down Expand Up @@ -183,6 +185,15 @@ public void close() throws IOException {}
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() {
Expand Down

1 comment on commit 57bfd0e

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.