1
0
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:
Luck
2021-03-19 19:59:15 +00:00
parent ad1ba3c126
commit 1c7e2dfb8c
3 changed files with 32 additions and 30 deletions

View File

@@ -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;
} }
} }

View File

@@ -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;
} }
} }

View File

@@ -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"));
} }
} }