From 405f8fe0b47fcfafcdb4853c325a42feb0614ed5 Mon Sep 17 00:00:00 2001 From: Andrey Turbanov Date: Tue, 24 Oct 2023 07:13:38 +0300 Subject: [PATCH 1/3] org.jline.util.PumpReader signed byte problem (#879) Backport of https://bugs.openjdk.org/browse/JDK-8312475 --- terminal/src/main/java/org/jline/utils/PumpReader.java | 2 +- .../src/test/java/org/jline/utils/PumpReaderTest.java | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/terminal/src/main/java/org/jline/utils/PumpReader.java b/terminal/src/main/java/org/jline/utils/PumpReader.java index 34bc4fc3b..bc1d4ed02 100644 --- a/terminal/src/main/java/org/jline/utils/PumpReader.java +++ b/terminal/src/main/java/org/jline/utils/PumpReader.java @@ -413,7 +413,7 @@ public int read() throws IOException { return EOF; } - return buffer.get(); + return buffer.get() & 0xFF; } private boolean readUsingBuffer() throws IOException { diff --git a/terminal/src/test/java/org/jline/utils/PumpReaderTest.java b/terminal/src/test/java/org/jline/utils/PumpReaderTest.java index 42c76a11e..84a668bb5 100644 --- a/terminal/src/test/java/org/jline/utils/PumpReaderTest.java +++ b/terminal/src/test/java/org/jline/utils/PumpReaderTest.java @@ -101,10 +101,10 @@ public void testSplitSurrogatePair() throws IOException { InputStream inputStream = pump.createInputStream(StandardCharsets.UTF_8); byte[] expectedEncoded = "\uD83D\uDE0A".getBytes(StandardCharsets.UTF_8); assertEquals(4, expectedEncoded.length); // verify that test is correctly implemented - assertEquals(expectedEncoded[0], inputStream.read()); - assertEquals(expectedEncoded[1], inputStream.read()); - assertEquals(expectedEncoded[2], inputStream.read()); - assertEquals(expectedEncoded[3], inputStream.read()); + assertEquals(expectedEncoded[0] & 0xff, inputStream.read()); + assertEquals(expectedEncoded[1] & 0xff, inputStream.read()); + assertEquals(expectedEncoded[2] & 0xff, inputStream.read()); + assertEquals(expectedEncoded[3] & 0xff, inputStream.read()); assertEquals(-1, inputStream.read()); } From a20ba4b5b1326a6a4371f51ed0d4eb618848cb7d Mon Sep 17 00:00:00 2001 From: Guillaume Nodet Date: Mon, 23 Oct 2023 13:31:53 +0200 Subject: [PATCH 2/3] Force creation of a dumb terminal if TERM starts with dumb --- .../main/java/org/jline/terminal/TerminalBuilder.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/terminal/src/main/java/org/jline/terminal/TerminalBuilder.java b/terminal/src/main/java/org/jline/terminal/TerminalBuilder.java index 484809b93..fb1426937 100644 --- a/terminal/src/main/java/org/jline/terminal/TerminalBuilder.java +++ b/terminal/src/main/java/org/jline/terminal/TerminalBuilder.java @@ -29,6 +29,7 @@ import org.jline.terminal.impl.AbstractPosixTerminal; import org.jline.terminal.impl.AbstractTerminal; +import org.jline.terminal.impl.DumbTerminal; import org.jline.terminal.impl.DumbTerminalProvider; import org.jline.terminal.spi.SystemStream; import org.jline.terminal.spi.TerminalProvider; @@ -367,6 +368,8 @@ private Terminal doBuild() throws IOException { Charset encoding = computeEncoding(); String type = computeType(); + boolean forceDumb = + (DumbTerminal.TYPE_DUMB.equals(type) || type != null && type.startsWith(DumbTerminal.TYPE_DUMB_COLOR)); Boolean dumb = this.dumb; if (dumb == null) { dumb = getBoolean(PROP_DUMB, null); @@ -389,7 +392,7 @@ private Terminal doBuild() throws IOException { stream -> stream, stream -> providers.stream().anyMatch(p -> p.isSystemStream(stream)))); SystemStream systemStream = select(system, systemOutput); - if (system.get(SystemStream.Input) && systemStream != null) { + if (!forceDumb && system.get(SystemStream.Input) && systemStream != null) { if (attributes != null || size != null) { Log.warn("Attributes and size fields are ignored when creating a system terminal"); } @@ -437,8 +440,8 @@ private Terminal doBuild() throws IOException { terminal = null; } } - if (terminal == null && (dumb == null || dumb)) { - if (dumb == null) { + if (terminal == null && (forceDumb || dumb == null || dumb)) { + if (!forceDumb && dumb == null) { if (Log.isDebugEnabled()) { Log.warn("input is tty: {}", system.get(SystemStream.Input)); Log.warn("output is tty: {}", system.get(SystemStream.Output)); From 2c8891ab36346efca382527cf63f45ef47d058f1 Mon Sep 17 00:00:00 2001 From: Guillaume Nodet Date: Mon, 23 Oct 2023 14:20:11 +0200 Subject: [PATCH 3/3] Add a property to force a given provider --- .../org/jline/terminal/TerminalBuilder.java | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/terminal/src/main/java/org/jline/terminal/TerminalBuilder.java b/terminal/src/main/java/org/jline/terminal/TerminalBuilder.java index fb1426937..ec0f98761 100644 --- a/terminal/src/main/java/org/jline/terminal/TerminalBuilder.java +++ b/terminal/src/main/java/org/jline/terminal/TerminalBuilder.java @@ -48,6 +48,7 @@ public final class TerminalBuilder { public static final String PROP_ENCODING = "org.jline.terminal.encoding"; public static final String PROP_CODEPAGE = "org.jline.terminal.codepage"; public static final String PROP_TYPE = "org.jline.terminal.type"; + public static final String PROP_PROVIDER = "org.jline.terminal.provider"; public static final String PROP_PROVIDERS = "org.jline.terminal.providers"; public static final String PROP_PROVIDER_FFM = "ffm"; public static final String PROP_PROVIDER_JNI = "jni"; @@ -368,14 +369,17 @@ private Terminal doBuild() throws IOException { Charset encoding = computeEncoding(); String type = computeType(); + String forcedProvider = System.getProperty(PROP_PROVIDER, null); + boolean forceDumb = - (DumbTerminal.TYPE_DUMB.equals(type) || type != null && type.startsWith(DumbTerminal.TYPE_DUMB_COLOR)); + (DumbTerminal.TYPE_DUMB.equals(type) || type != null && type.startsWith(DumbTerminal.TYPE_DUMB_COLOR)) + || (forcedProvider != null && forcedProvider.equals(PROP_PROVIDER_DUMB)); Boolean dumb = this.dumb; if (dumb == null) { dumb = getBoolean(PROP_DUMB, null); } IllegalStateException exception = new IllegalStateException("Unable to create a terminal"); - List providers = getProviders(exception); + List providers = getProviders(forcedProvider, exception); Terminal terminal = null; if ((system != null && system) || (system == null && in == null && out == null)) { if (system != null @@ -596,18 +600,18 @@ public Charset computeEncoding() { return encoding; } - public List getProviders(IllegalStateException exception) { + public List getProviders(String forcedProvider, IllegalStateException exception) { List providers = new ArrayList<>(); // Check ffm provider - checkProvider(exception, providers, ffm, PROP_FFM, PROP_PROVIDER_FFM); + checkProvider(forcedProvider, exception, providers, ffm, PROP_FFM, PROP_PROVIDER_FFM); // Check jni provider - checkProvider(exception, providers, jni, PROP_JNI, PROP_PROVIDER_JNI); + checkProvider(forcedProvider, exception, providers, jni, PROP_JNI, PROP_PROVIDER_JNI); // Check jansi provider - checkProvider(exception, providers, jansi, PROP_JANSI, PROP_PROVIDER_JANSI); + checkProvider(forcedProvider, exception, providers, jansi, PROP_JANSI, PROP_PROVIDER_JANSI); // Check jna provider - checkProvider(exception, providers, jna, PROP_JNA, PROP_PROVIDER_JNA); + checkProvider(forcedProvider, exception, providers, jna, PROP_JNA, PROP_PROVIDER_JNA); // Check exec provider - checkProvider(exception, providers, exec, PROP_EXEC, PROP_PROVIDER_EXEC); + checkProvider(forcedProvider, exception, providers, exec, PROP_EXEC, PROP_PROVIDER_EXEC); // Order providers List order = Arrays.asList( (this.providers != null ? this.providers : System.getProperty(PROP_PROVIDERS, PROP_PROVIDERS_DEFAULT)) @@ -622,12 +626,13 @@ public List getProviders(IllegalStateException exception) { } private void checkProvider( + String forcedProvider, IllegalStateException exception, List providers, Boolean load, String property, String name) { - Boolean doLoad = load; + Boolean doLoad = forcedProvider != null ? (Boolean) name.equals(forcedProvider) : load; if (doLoad == null) { doLoad = getBoolean(property, true); }