summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/shared/calendarspec.c27
-rw-r--r--src/test/test-calendarspec.c1
-rw-r--r--test/fuzz/fuzz-calendarspec/crash-parse-star-non-star1
3 files changed, 21 insertions, 8 deletions
diff --git a/src/shared/calendarspec.c b/src/shared/calendarspec.c
index 273a38f1fa..767c1b7856 100644
--- a/src/shared/calendarspec.c
+++ b/src/shared/calendarspec.c
@@ -288,17 +288,24 @@ static void format_weekdays(FILE *f, const CalendarSpec *c) {
}
}
-static void format_chain(FILE *f, int space, const CalendarComponent *c, bool usec) {
+static bool chain_is_star(const CalendarComponent *c, bool usec) {
+ /* Return true if the whole chain can be replaced by '*'.
+ * This happens when the chain is empty or one of the components covers all. */
+ if (!c)
+ return true;
+ if (usec)
+ for (; c; c = c->next)
+ if (c->start == 0 && c->stop < 0 && c->repeat == USEC_PER_SEC)
+ return true;
+ return false;
+}
+
+static void _format_chain(FILE *f, int space, const CalendarComponent *c, bool start, bool usec) {
int d = usec ? (int) USEC_PER_SEC : 1;
assert(f);
- if (!c) {
- fputc('*', f);
- return;
- }
-
- if (usec && c->start == 0 && c->stop < 0 && c->repeat == USEC_PER_SEC && !c->next) {
+ if (start && chain_is_star(c, usec)) {
fputc('*', f);
return;
}
@@ -321,10 +328,14 @@ static void format_chain(FILE *f, int space, const CalendarComponent *c, bool us
if (c->next) {
fputc(',', f);
- format_chain(f, space, c->next, usec);
+ _format_chain(f, space, c->next, false, usec);
}
}
+static void format_chain(FILE *f, int space, const CalendarComponent *c, bool usec) {
+ _format_chain(f, space, c, /* start = */ true, usec);
+}
+
int calendar_spec_to_string(const CalendarSpec *c, char **p) {
char *buf = NULL;
size_t sz = 0;
diff --git a/src/test/test-calendarspec.c b/src/test/test-calendarspec.c
index 5508f8b833..8a0684ed66 100644
--- a/src/test/test-calendarspec.c
+++ b/src/test/test-calendarspec.c
@@ -164,6 +164,7 @@ TEST(calendar_spec_one) {
test_one("00:00:01/2,02..03", "*-*-* 00:00:01/2,02..03");
test_one("*:4,30:0..3", "*-*-* *:04,30:00..03");
test_one("*:4,30:0/1", "*-*-* *:04,30:*");
+ test_one("*:4,30:0/1,3,5", "*-*-* *:04,30:*");
test_one("*-*~1 Utc", "*-*~01 00:00:00 UTC");
test_one("*-*~05,3 ", "*-*~03,05 00:00:00");
test_one("*-*~* 00:00:00", "*-*-* 00:00:00");
diff --git a/test/fuzz/fuzz-calendarspec/crash-parse-star-non-star b/test/fuzz/fuzz-calendarspec/crash-parse-star-non-star
new file mode 100644
index 0000000000..0c1edc2ce9
--- /dev/null
+++ b/test/fuzz/fuzz-calendarspec/crash-parse-star-non-star
@@ -0,0 +1 @@
+*:4,30:0/01,0 \ No newline at end of file