Skip to content
Permalink
Browse files
8242919: Paste locks up jshell
Not waiting until the full block is available while reading from input.

Reviewed-by: rfield
  • Loading branch information
Jan Lahoda committed May 8, 2020
1 parent 13d6b49 commit 3beee2cd93a8fb352da019b9a16b35632048477e
@@ -76,6 +76,8 @@
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 @@
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 @@ public void replaceLastHistoryEntry(String source) {

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 @@ private History getHistory() {

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 @@ public TestTerminal(StopDetectingInputStream input, OutputStream output) throws
// 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();
}

}
@@ -107,6 +107,19 @@ public synchronized int read() {
}
}

@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();
@@ -23,14 +23,15 @@

/**
* @test
* @bug 8182297
* @bug 8182297 8242919
* @summary Verify that pasting multi-line snippets works properly.
* @library /tools/lib
* @modules
* java.base/java.lang:open
* 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 void testPrevNextSnippet() throws Exception {
});
}
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;");
});
}
}

0 comments on commit 3beee2c

Please sign in to comment.