🐛 Fixed quoted parsing in StringArgument
This commit is contained in:
parent
9bfb0f17d6
commit
720019b508
3 changed files with 51 additions and 23 deletions
|
|
@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
### Fixes
|
### Fixes
|
||||||
- Fixes chained optionals not allowing the command to be executed when more than one optional is omitted
|
- Fixes chained optionals not allowing the command to be executed when more than one optional is omitted
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Fixed quoted parsing in StringArgument
|
||||||
|
|
||||||
## [1.0.1] - 2020-10-14
|
## [1.0.1] - 2020-10-14
|
||||||
|
|
||||||
### Changes
|
### Changes
|
||||||
|
|
|
||||||
|
|
@ -37,10 +37,15 @@ import java.util.List;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.StringJoiner;
|
import java.util.StringJoiner;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public final class StringArgument<C> extends CommandArgument<C, String> {
|
public final class StringArgument<C> extends CommandArgument<C, String> {
|
||||||
|
|
||||||
|
private static final Pattern QUOTED_DOUBLE = Pattern.compile("\"(?<inner>(?:[^\"\\\\]|\\\\.)*)\"");
|
||||||
|
private static final Pattern QUOTED_SINGLE = Pattern.compile("'(?<inner>(?:[^'\\\\]|\\\\.)*)'");
|
||||||
|
|
||||||
private final StringMode stringMode;
|
private final StringMode stringMode;
|
||||||
|
|
||||||
private StringArgument(
|
private StringArgument(
|
||||||
|
|
@ -305,6 +310,40 @@ public final class StringArgument<C> extends CommandArgument<C, String> {
|
||||||
}
|
}
|
||||||
inputQueue.remove();
|
inputQueue.remove();
|
||||||
return ArgumentParseResult.success(input);
|
return ArgumentParseResult.success(input);
|
||||||
|
} else if (this.stringMode == StringMode.QUOTED) {
|
||||||
|
final StringJoiner sj = new StringJoiner(" ");
|
||||||
|
for (final String string : inputQueue) {
|
||||||
|
sj.add(string);
|
||||||
|
}
|
||||||
|
final String string = sj.toString();
|
||||||
|
|
||||||
|
Matcher matcher = QUOTED_DOUBLE.matcher(string);
|
||||||
|
String inner = null;
|
||||||
|
if (matcher.find()) {
|
||||||
|
inner = matcher.group("inner");
|
||||||
|
} else {
|
||||||
|
matcher = QUOTED_SINGLE.matcher(string);
|
||||||
|
if (matcher.find()) {
|
||||||
|
inner = matcher.group("inner");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inner != null) {
|
||||||
|
final int numSpaces = (int) inner.chars().filter(c -> c == ' ').count();
|
||||||
|
for (int i = 0; i <= numSpaces; i++) {
|
||||||
|
inputQueue.remove();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
inner = inputQueue.remove();
|
||||||
|
if (inner.startsWith("\"") || inner.startsWith("'")) {
|
||||||
|
return ArgumentParseResult.failure(new StringParseException(sj.toString(),
|
||||||
|
StringMode.QUOTED, commandContext));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inner = inner.replace("\\\"", "\"").replace("\\\'", "\"");
|
||||||
|
|
||||||
|
return ArgumentParseResult.success(inner);
|
||||||
}
|
}
|
||||||
|
|
||||||
final StringJoiner sj = new StringJoiner(" ");
|
final StringJoiner sj = new StringJoiner(" ");
|
||||||
|
|
@ -321,33 +360,10 @@ public final class StringArgument<C> extends CommandArgument<C, String> {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.stringMode == StringMode.QUOTED) {
|
|
||||||
if (!started) {
|
|
||||||
if (string.startsWith("\"") || string.startsWith("'")) {
|
|
||||||
start = string.charAt(0);
|
|
||||||
string = string.substring(1);
|
|
||||||
started = true;
|
|
||||||
} else {
|
|
||||||
/* Just read a single string instead */
|
|
||||||
inputQueue.remove();
|
|
||||||
return ArgumentParseResult.success(string);
|
|
||||||
}
|
|
||||||
} else if (string.endsWith(Character.toString(start))) {
|
|
||||||
sj.add(string.substring(0, string.length() - 1));
|
|
||||||
inputQueue.remove();
|
|
||||||
finished = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sj.add(string);
|
sj.add(string);
|
||||||
inputQueue.remove();
|
inputQueue.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.stringMode == StringMode.QUOTED && !finished) {
|
|
||||||
return ArgumentParseResult.failure(new StringParseException(sj.toString(), StringMode.QUOTED, commandContext));
|
|
||||||
}
|
|
||||||
|
|
||||||
return ArgumentParseResult.success(sj.toString());
|
return ArgumentParseResult.success(sj.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,8 @@ import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletionException;
|
||||||
|
|
||||||
class StringArgumentTest {
|
class StringArgumentTest {
|
||||||
|
|
||||||
private static final String[] storage = new String[2];
|
private static final String[] storage = new String[2];
|
||||||
|
|
@ -85,6 +87,13 @@ class StringArgumentTest {
|
||||||
manager.executeCommand(new TestCommandSender(), "quoted quoted unquoted");
|
manager.executeCommand(new TestCommandSender(), "quoted quoted unquoted");
|
||||||
Assertions.assertEquals("quoted", storage[0]);
|
Assertions.assertEquals("quoted", storage[0]);
|
||||||
Assertions.assertEquals("unquoted", storage[1]);
|
Assertions.assertEquals("unquoted", storage[1]);
|
||||||
|
clear();
|
||||||
|
manager.executeCommand(new TestCommandSender(), "quoted \"quoted \\\" string\" unquoted").join();
|
||||||
|
Assertions.assertEquals("quoted \" string", storage[0]);
|
||||||
|
Assertions.assertEquals("unquoted", storage[1]);
|
||||||
|
clear();
|
||||||
|
Assertions.assertThrows(CompletionException.class, () -> manager.executeCommand(new TestCommandSender(),
|
||||||
|
"'quoted quoted unquoted").join());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue