8242919: Paste locks up jshell

Not waiting until the full block is available while reading from input.

Reviewed-by: rfield
This commit is contained in:
Jan Lahoda 2020-05-08 09:16:12 +02:00
parent 13d6b49ed8
commit 3beee2cd93
3 changed files with 56 additions and 19 deletions

View File

@ -76,6 +76,8 @@ import jdk.internal.org.jline.terminal.Size;
import jdk.internal.org.jline.terminal.Terminal;
import jdk.internal.org.jline.terminal.TerminalBuilder;
import jdk.internal.org.jline.utils.Display;
import jdk.internal.org.jline.utils.NonBlocking;
import jdk.internal.org.jline.utils.NonBlockingInputStreamImpl;
import jdk.internal.org.jline.utils.NonBlockingReader;
import jdk.jshell.ExpressionSnippet;
import jdk.jshell.Snippet;
@ -103,14 +105,20 @@ class ConsoleIOContext extends IOContext {
Map<String, Object> variables = new HashMap<>();
this.input = new StopDetectingInputStream(() -> repl.stop(),
ex -> repl.hard("Error on input: %s", ex));
InputStream nonBlockingInput = new NonBlockingInputStreamImpl(null, input) {
@Override
public int readBuffered(byte[] b) throws IOException {
return input.read(b);
}
};
Terminal terminal;
if (System.getProperty("test.jdk") != null) {
terminal = new TestTerminal(input, cmdout);
terminal = new TestTerminal(nonBlockingInput, cmdout);
input.setInputStream(cmdin);
} else {
terminal = TerminalBuilder.builder().inputStreamWrapper(in -> {
input.setInputStream(in);
return input;
return nonBlockingInput;
}).build();
}
originalAttributes = terminal.getAttributes();
@ -827,7 +835,7 @@ class ConsoleIOContext extends IOContext {
private boolean fixes() {
try {
int c = in.getTerminal().input().read();
int c = in.getTerminal().reader().read();
if (c == (-1)) {
return true; //TODO: true or false???
@ -1234,11 +1242,11 @@ class ConsoleIOContext extends IOContext {
private static final int DEFAULT_HEIGHT = 24;
public TestTerminal(StopDetectingInputStream input, OutputStream output) throws Exception {
private final NonBlockingReader inputReader;
public TestTerminal(InputStream input, OutputStream output) throws Exception {
super("test", "ansi", output, Charset.forName("UTF-8"));
// setAnsiSupported(true);
// setEchoEnabled(false);
// this.input = input;
this.inputReader = NonBlocking.nonBlocking(getName(), input, encoding());
Attributes a = new Attributes(getAttributes());
a.setLocalFlag(LocalFlag.ECHO, false);
setAttributes(attributes);
@ -1252,18 +1260,18 @@ class ConsoleIOContext extends IOContext {
// ignore
}
setSize(new Size(80, h));
new Thread(() -> {
int r;
}
try {
while ((r = input.read()) != (-1)) {
processInputByte(r);
}
slaveInput.close();
} catch (IOException ex) {
throw new IllegalStateException(ex);
}
}).start();
@Override
public NonBlockingReader reader() {
return inputReader;
}
@Override
protected void doClose() throws IOException {
super.doClose();
slaveInput.close();
inputReader.close();
}
}

View File

@ -107,6 +107,19 @@ public final class StopDetectingInputStream extends InputStream {
}
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
if (len == 0) {
return 0;
}
int r = read();
if (r != (-1)) {
b[off] = (byte) r;
return 1;
}
return 0;
}
public synchronized void shutdown() {
state = State.CLOSED;
notifyAll();

View File

@ -23,7 +23,7 @@
/**
* @test
* @bug 8182297
* @bug 8182297 8242919
* @summary Verify that pasting multi-line snippets works properly.
* @library /tools/lib
* @modules
@ -31,6 +31,7 @@
* java.base/java.io:open
* jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
* jdk.internal.le/jdk.internal.org.jline.reader.impl
* jdk.jshell/jdk.internal.jshell.tool.resources:open
* jdk.jshell/jdk.jshell:open
* @build toolbox.ToolBox toolbox.JarTask toolbox.JavacTask
@ -42,6 +43,7 @@
import java.io.Console;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import jdk.internal.org.jline.reader.impl.LineReaderImpl;
import org.testng.annotations.Test;
@ -73,4 +75,18 @@ public class PasteAndMeasurementsUITest extends UITesting {
});
}
private static final String LOC = "\033[12;1R";
public void testBracketedPaste() throws Exception {
Field cons = System.class.getDeclaredField("cons");
cons.setAccessible(true);
Constructor console = Console.class.getDeclaredConstructor();
console.setAccessible(true);
cons.set(null, console.newInstance());
doRunTest((inputSink, out) -> {
inputSink.write(LineReaderImpl.BRACKETED_PASTE_BEGIN +
"int i;" +
LineReaderImpl.BRACKETED_PASTE_END);
waitOutput(out, "int i;");
});
}
}