diff --git a/src/main/java/org/springframework/shell/core/Tokenizer.java b/src/main/java/org/springframework/shell/core/Tokenizer.java index 41387ffa..f9e77f90 100644 --- a/src/main/java/org/springframework/shell/core/Tokenizer.java +++ b/src/main/java/org/springframework/shell/core/Tokenizer.java @@ -144,8 +144,8 @@ public class Tokenizer { private String eatValue(boolean emptyKey) { StringBuilder sb = new StringBuilder(); char endDelimiter = ' '; - if (buffer[pos] == '"') { - endDelimiter = '"'; + if (buffer[pos] == '"' || buffer[pos] == '\'') { + endDelimiter = buffer[pos]; pos++; } // So that it can be retrieved later (if this is actually the last value) @@ -180,9 +180,9 @@ public class Tokenizer { // When here, we either ran out of input, or encountered our delim, or both // Fail, unless we allow an unfinished quoted string to be reported - if (endDelimiter == '"' && // we're using quotes + if (endDelimiter != ' ' && // we're using quotes pos == buffer.length && // we ran of input - (buffer[pos - 1] != '"' || // quotes are not properly closed + (buffer[pos - 1] != endDelimiter || // quotes are not properly closed sb.length() == 0)) { // BUT it's ok if consumed nothing (pos-1 is *opening* quote then) if (allowUnbalancedLastQuotedValue) { openingQuotesHaveNotBeenClosed = true; diff --git a/src/test/java/org/springframework/shell/core/TokenizerTests.java b/src/test/java/org/springframework/shell/core/TokenizerTests.java index c41dbcbd..84b4c46e 100644 --- a/src/test/java/org/springframework/shell/core/TokenizerTests.java +++ b/src/test/java/org/springframework/shell/core/TokenizerTests.java @@ -211,6 +211,20 @@ public class TokenizerTests { // backslash escape result = tokenize("--foo \\\\u\\g"); assertEquals(Collections.singletonMap("foo", "\\u\\g"), result); + } + + public void testSingleAndDoubleQuotingBehavior() { + Map result = tokenize("--foo 'i have a double \" in me'"); + assertEquals(Collections.singletonMap("foo", "i have a double \" in me"), result); + + result = tokenize("--foo \"i have a double \\\" in me\""); + assertEquals(Collections.singletonMap("foo", "i have a double \" in me"), result); + + result = tokenize("--foo \"i have a single ' in me\""); + assertEquals(Collections.singletonMap("foo", "i have a single ' in me"), result); + + result = tokenize("--foo 'i have a single \\' in me'"); + assertEquals(Collections.singletonMap("foo", "i have a single ' in me"), result); }