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:
parent
13d6b49ed8
commit
3beee2cd93
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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;");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user