From a30080a87fed8137e7bc00ba627c5e7ffd68ce28 Mon Sep 17 00:00:00 2001 From: mattirn Date: Tue, 8 Sep 2020 22:57:24 +0200 Subject: [PATCH] DefaultParser: ArrayIndexOutOfBoundsException, fixes #567 --- .../test/java/org/jline/example/Example.java | 5 ++- .../org/jline/reader/impl/DefaultParser.java | 41 ++++++++++--------- .../completer/StringsCompleterTest.java | 16 +++++++- 3 files changed, 41 insertions(+), 21 deletions(-) diff --git a/builtins/src/test/java/org/jline/example/Example.java b/builtins/src/test/java/org/jline/example/Example.java index da0b969ff..791779389 100644 --- a/builtins/src/test/java/org/jline/example/Example.java +++ b/builtins/src/test/java/org/jline/example/Example.java @@ -160,7 +160,10 @@ public static void main(String[] args) throws IOException { completer = new Completers.FileNameCompleter(); break; case "simple": - completer = new StringsCompleter("foo", "bar", "baz"); + DefaultParser p3 = new DefaultParser(); + p3.setEscapeChars(new char[]{}); + parser = p3; + completer = new StringsCompleter("foo", "bar", "baz", "pip pop"); break; case "quotes": DefaultParser p = new DefaultParser(); diff --git a/reader/src/main/java/org/jline/reader/impl/DefaultParser.java b/reader/src/main/java/org/jline/reader/impl/DefaultParser.java index 36faa7ad7..69f4499dc 100644 --- a/reader/src/main/java/org/jline/reader/impl/DefaultParser.java +++ b/reader/src/main/java/org/jline/reader/impl/DefaultParser.java @@ -613,25 +613,28 @@ public CharSequence escape(CharSequence candidate, boolean complete) { } } if (escapeChars != null) { - // Completion is protected by an opening quote: - // Delimiters (spaces) don't need to be escaped, nor do other quotes, but everything else does. - // Also, close the quote at the end - if (openingQuote != null) { - needToBeEscaped = i -> isRawEscapeChar(sb.charAt(i)) || String.valueOf(sb.charAt(i)).equals(openingQuote); - } - // Completion is protected by middle quotes: - // Delimiters (spaces) don't need to be escaped, nor do quotes, but everything else does. - else if (middleQuotes) { - needToBeEscaped = i -> isRawEscapeChar(sb.charAt(i)); - } - // No quote protection, need to escape everything: delimiter chars (spaces), quote chars - // and escapes themselves - else { - needToBeEscaped = i -> isDelimiterChar(sb, i) || isRawEscapeChar(sb.charAt(i)) || isRawQuoteChar(sb.charAt(i)); - } - for (int i = 0; i < sb.length(); i++) { - if (needToBeEscaped.test(i)) { - sb.insert(i++, escapeChars[0]); + if (escapeChars.length > 0) { + // Completion is protected by an opening quote: + // Delimiters (spaces) don't need to be escaped, nor do other quotes, but everything else does. + // Also, close the quote at the end + if (openingQuote != null) { + needToBeEscaped = i -> isRawEscapeChar(sb.charAt(i)) || String.valueOf(sb.charAt(i)).equals(openingQuote); + } + // Completion is protected by middle quotes: + // Delimiters (spaces) don't need to be escaped, nor do quotes, but everything else does. + else if (middleQuotes) { + needToBeEscaped = i -> isRawEscapeChar(sb.charAt(i)); + } + // No quote protection, need to escape everything: delimiter chars (spaces), quote chars + // and escapes themselves + else { + needToBeEscaped = i -> isDelimiterChar(sb, i) || isRawEscapeChar(sb.charAt(i)) + || isRawQuoteChar(sb.charAt(i)); + } + for (int i = 0; i < sb.length(); i++) { + if (needToBeEscaped.test(i)) { + sb.insert(i++, escapeChars[0]); + } } } } else if (openingQuote == null && !middleQuotes) { diff --git a/reader/src/test/java/org/jline/reader/completer/StringsCompleterTest.java b/reader/src/test/java/org/jline/reader/completer/StringsCompleterTest.java index d5264de9e..5d21ca848 100644 --- a/reader/src/test/java/org/jline/reader/completer/StringsCompleterTest.java +++ b/reader/src/test/java/org/jline/reader/completer/StringsCompleterTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2016, the original author or authors. + * Copyright (c) 2002-2020, the original author or authors. * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -47,6 +47,20 @@ public void escapeCharsNull() throws Exception { assertBuffer("bar'f", new TestBuffer("bar'f").tab()); } + @Test + public void escapeCharsEmpty() throws Exception { + DefaultParser dp = (DefaultParser) reader.getParser(); + dp.setEscapeChars(new char[]{}); + reader.setVariable(LineReader.ERRORS, 0); + reader.setParser(dp); + reader.setCompleter(new StringsCompleter("foo bar", "bar")); + + assertBuffer("foo bar ", new TestBuffer("f").tab()); + assertBuffer("'foo bar' ", new TestBuffer("'f").tab()); + assertBuffer("foo'b", new TestBuffer("foo'b").tab()); + assertBuffer("bar'f", new TestBuffer("bar'f").tab()); + } + @Test public void escapeChars() throws Exception { DefaultParser dp = (DefaultParser) reader.getParser();