Prevent infinite loop in CronAdjuster with invalid date combinations (#4548)
Signed-off-by: Jimmy Tanagra <jcode@tanagra.id.au>pull/4553/head
parent
f00c7700cb
commit
a7b8c1a9b3
|
@ -71,6 +71,7 @@ public class CronAdjuster implements SchedulerTemporalAdjuster {
|
||||||
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
|
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
|
||||||
|
|
||||||
private final List<Field> fields = new ArrayList<>(7);
|
private final List<Field> fields = new ArrayList<>(7);
|
||||||
|
private String cronExpression;
|
||||||
private final Map<String, String> environmentMap;
|
private final Map<String, String> environmentMap;
|
||||||
private final boolean reboot;
|
private final boolean reboot;
|
||||||
|
|
||||||
|
@ -82,6 +83,7 @@ public class CronAdjuster implements SchedulerTemporalAdjuster {
|
||||||
environmentMap = parseEnvironment(entries);
|
environmentMap = parseEnvironment(entries);
|
||||||
|
|
||||||
String cronExpression = entries[entries.length - 1].trim();
|
String cronExpression = entries[entries.length - 1].trim();
|
||||||
|
this.cronExpression = cronExpression;
|
||||||
|
|
||||||
reboot = "@reboot".equals(cronExpression);
|
reboot = "@reboot".equals(cronExpression);
|
||||||
|
|
||||||
|
@ -515,6 +517,7 @@ public class CronAdjuster implements SchedulerTemporalAdjuster {
|
||||||
// we start over with this new time.
|
// we start over with this new time.
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
int restarts = 0;
|
||||||
final int length = fields.size();
|
final int length = fields.size();
|
||||||
|
|
||||||
while (index < length) {
|
while (index < length) {
|
||||||
|
@ -525,6 +528,10 @@ public class CronAdjuster implements SchedulerTemporalAdjuster {
|
||||||
if (out == null) {
|
if (out == null) {
|
||||||
index++;
|
index++;
|
||||||
} else {
|
} else {
|
||||||
|
if (restarts++ > 1000) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
String.format("Cron expression '%s' is not valid, too many restarts", cronExpression));
|
||||||
|
}
|
||||||
ret = out;
|
ret = out;
|
||||||
index = 0;
|
index = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ package org.openhab.core.internal.scheduler;
|
||||||
|
|
||||||
import static org.hamcrest.CoreMatchers.equalTo;
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.temporal.Temporal;
|
import java.time.temporal.Temporal;
|
||||||
|
@ -25,6 +26,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.junit.jupiter.api.Timeout;
|
import org.junit.jupiter.api.Timeout;
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.jupiter.params.provider.MethodSource;
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
import org.junit.jupiter.params.provider.ValueSource;
|
||||||
import org.openhab.core.scheduler.CronAdjuster;
|
import org.openhab.core.scheduler.CronAdjuster;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -197,4 +199,13 @@ public class CronAdjusterTest {
|
||||||
equalTo(out));
|
equalTo(out));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@ValueSource(strings = { "0 0 0 31 2 *", "* * *", "80 * * * * *" })
|
||||||
|
public void testInvalidCronExpression(String cron) {
|
||||||
|
assertThrows(IllegalArgumentException.class, () -> {
|
||||||
|
final CronAdjuster cronAdjuster = new CronAdjuster(cron);
|
||||||
|
cronAdjuster.adjustInto(java.time.ZonedDateTime.now());
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue