mirror of
https://github.com/lucko/LuckPerms.git
synced 2025-09-08 21:30:55 +02:00
Fix very lenient duration parsing (#2940)
This commit is contained in:
@@ -34,13 +34,8 @@ import java.util.UUID;
|
|||||||
public abstract class DummyConsoleSender implements Sender {
|
public abstract class DummyConsoleSender implements Sender {
|
||||||
private final LuckPermsPlugin platform;
|
private final LuckPermsPlugin platform;
|
||||||
|
|
||||||
private final UUID uniqueId;
|
|
||||||
private final String name;
|
|
||||||
|
|
||||||
public DummyConsoleSender(LuckPermsPlugin plugin) {
|
public DummyConsoleSender(LuckPermsPlugin plugin) {
|
||||||
this.platform = plugin;
|
this.platform = plugin;
|
||||||
this.uniqueId = Sender.CONSOLE_UUID;
|
|
||||||
this.name = Sender.CONSOLE_NAME;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -70,11 +65,11 @@ public abstract class DummyConsoleSender implements Sender {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UUID getUniqueId() {
|
public UUID getUniqueId() {
|
||||||
return this.uniqueId;
|
return Sender.CONSOLE_UUID;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return this.name;
|
return Sender.CONSOLE_NAME;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -47,42 +47,37 @@ public final class DurationParser {
|
|||||||
.put(ChronoUnit.DAYS, "d(?:ay)?s?")
|
.put(ChronoUnit.DAYS, "d(?:ay)?s?")
|
||||||
.put(ChronoUnit.HOURS, "h(?:our|r)?s?")
|
.put(ChronoUnit.HOURS, "h(?:our|r)?s?")
|
||||||
.put(ChronoUnit.MINUTES, "m(?:inute|in)?s?")
|
.put(ChronoUnit.MINUTES, "m(?:inute|in)?s?")
|
||||||
.put(ChronoUnit.SECONDS, "(?:s(?:econd|ec)?s?)?")
|
.put(ChronoUnit.SECONDS, "s(?:econd|ec)?s?")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
private static final ChronoUnit[] UNITS = UNITS_PATTERNS.keySet().toArray(new ChronoUnit[0]);
|
private static final ChronoUnit[] UNITS = UNITS_PATTERNS.keySet().toArray(new ChronoUnit[0]);
|
||||||
|
|
||||||
private static final String PATTERN_STRING = UNITS_PATTERNS.values().stream()
|
private static final String PATTERN_STRING = UNITS_PATTERNS.values().stream()
|
||||||
.map(pattern -> "(?:(\\d+)\\s*" + pattern + "[,\\s]*)?")
|
.map(pattern -> "(?:(\\d+)\\s*" + pattern + "[,\\s]*)?")
|
||||||
.collect(Collectors.joining());
|
.collect(Collectors.joining("", "^\\s*", "$"));
|
||||||
|
|
||||||
private static final Pattern PATTERN = Pattern.compile(PATTERN_STRING, Pattern.CASE_INSENSITIVE);
|
private static final Pattern PATTERN = Pattern.compile(PATTERN_STRING, Pattern.CASE_INSENSITIVE);
|
||||||
|
|
||||||
public static Duration parseDuration(String input) throws IllegalArgumentException {
|
public static Duration parseDuration(String input) throws IllegalArgumentException {
|
||||||
Matcher matcher = PATTERN.matcher(input);
|
Matcher matcher = PATTERN.matcher(input);
|
||||||
|
if (!matcher.matches()) {
|
||||||
while (matcher.find()) {
|
throw new IllegalArgumentException("unable to parse duration: " + input);
|
||||||
if (matcher.group() == null || matcher.group().isEmpty()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Duration duration = Duration.ZERO;
|
|
||||||
for (int i = 0; i < UNITS.length; i++) {
|
|
||||||
ChronoUnit unit = UNITS[i];
|
|
||||||
int g = i + 1;
|
|
||||||
|
|
||||||
if (matcher.group(g) != null && !matcher.group(g).isEmpty()) {
|
|
||||||
int n = Integer.parseInt(matcher.group(g));
|
|
||||||
if (n > 0) {
|
|
||||||
duration = duration.plus(unit.getDuration().multipliedBy(n));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return duration;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new IllegalArgumentException("unable to parse duration: " + input);
|
Duration duration = Duration.ZERO;
|
||||||
|
for (int i = 0; i < UNITS.length; i++) {
|
||||||
|
ChronoUnit unit = UNITS[i];
|
||||||
|
int g = i + 1;
|
||||||
|
|
||||||
|
if (matcher.group(g) != null && !matcher.group(g).isEmpty()) {
|
||||||
|
int n = Integer.parseInt(matcher.group(g));
|
||||||
|
if (n > 0) {
|
||||||
|
duration = duration.plus(unit.getDuration().multipliedBy(n));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@@ -31,6 +31,7 @@ import java.time.Duration;
|
|||||||
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.ChronoUnit;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
|
||||||
public class DurationParserTest {
|
public class DurationParserTest {
|
||||||
|
|
||||||
@@ -111,6 +112,17 @@ public class DurationParserTest {
|
|||||||
test(expected, "5y 4mo 3w 2d 1h 6m 7s");
|
test(expected, "5y 4mo 3w 2d 1h 6m 7s");
|
||||||
test(expected, "5y4mo3w2d1h6m7s");
|
test(expected, "5y4mo3w2d1h6m7s");
|
||||||
test(expected, "5 years 4 months 3 weeks 2 days 1 hour 6 minutes 7 seconds");
|
test(expected, "5 years 4 months 3 weeks 2 days 1 hour 6 minutes 7 seconds");
|
||||||
|
|
||||||
|
test(expected, "5y, 4mo, 3w, 2d, 1h, 6m, 7s");
|
||||||
|
test(expected, "5y,4mo,3w,2d,1h,6m,7s");
|
||||||
|
test(expected, "5 years, 4 months, 3 weeks, 2 days, 1 hour, 6 minutes, 7 seconds");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFail() {
|
||||||
|
assertThrows(IllegalArgumentException.class, () -> DurationParser.parseDuration("definitely not a duration"));
|
||||||
|
assertThrows(IllegalArgumentException.class, () -> DurationParser.parseDuration("still 1 not a duration"));
|
||||||
|
assertThrows(IllegalArgumentException.class, () -> DurationParser.parseDuration("still 1s not a duration"));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user