Skip to content

Commit

Permalink
DefaultParser: ArrayIndexOutOfBoundsException, fixes #567
Browse files Browse the repository at this point in the history
  • Loading branch information
mattirn committed Sep 8, 2020
1 parent bb8b6fe commit a30080a
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 21 deletions.
5 changes: 4 additions & 1 deletion builtins/src/test/java/org/jline/example/Example.java
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
41 changes: 22 additions & 19 deletions reader/src/main/java/org/jline/reader/impl/DefaultParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -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();
Expand Down

0 comments on commit a30080a

Please sign in to comment.