summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/basic/calendarspec.c64
-rw-r--r--src/test/test-calendarspec.c5
2 files changed, 50 insertions, 19 deletions
diff --git a/src/basic/calendarspec.c b/src/basic/calendarspec.c
index 6e0bab9b94..54ab909ddf 100644
--- a/src/basic/calendarspec.c
+++ b/src/basic/calendarspec.c
@@ -32,6 +32,8 @@
#include "parse-util.h"
#include "string-util.h"
+/* Longest valid date/time range is 1970..2199 */
+#define MAX_RANGE_LEN 230
#define BITS_WEEKDAYS 127
static void free_chain(CalendarComponent *c) {
@@ -448,8 +450,26 @@ static int parse_component_decimal(const char **p, bool usec, unsigned long *res
return 0;
}
+static int const_chain(int value, CalendarComponent **c) {
+ CalendarComponent *cc = NULL;
+
+ assert(c);
+
+ cc = new0(CalendarComponent, 1);
+ if (!cc)
+ return -ENOMEM;
+
+ cc->value = value;
+ cc->repeat = 0;
+ cc->next = *c;
+
+ *c = cc;
+
+ return 0;
+}
+
static int prepend_component(const char **p, bool usec, CalendarComponent **c) {
- unsigned long value, repeat = 0;
+ unsigned long i, value, range_end, range_inc, repeat = 0;
CalendarComponent *cc;
int r;
const char *e;
@@ -471,6 +491,30 @@ static int prepend_component(const char **p, bool usec, CalendarComponent **c) {
if (repeat == 0)
return -ERANGE;
+ } else if (e[0] == '.' && e[1] == '.') {
+ e += 2;
+ r = parse_component_decimal(&e, usec, &range_end);
+ if (r < 0)
+ return r;
+
+ if (value >= range_end)
+ return -EINVAL;
+
+ range_inc = usec ? USEC_PER_SEC : 1;
+
+ /* Don't allow impossibly large ranges... */
+ if (range_end - value >= MAX_RANGE_LEN * range_inc)
+ return -EINVAL;
+
+ /* ...or ranges with only a single element */
+ if (range_end - value < range_inc)
+ return -EINVAL;
+
+ for (i = value; i <= range_end; i += range_inc) {
+ r = const_chain(i, c);
+ if (r < 0)
+ return r;
+ }
}
if (*e != 0 && *e != ' ' && *e != ',' && *e != '-' && *e != ':')
@@ -495,24 +539,6 @@ static int prepend_component(const char **p, bool usec, CalendarComponent **c) {
return 0;
}
-static int const_chain(int value, CalendarComponent **c) {
- CalendarComponent *cc = NULL;
-
- assert(c);
-
- cc = new0(CalendarComponent, 1);
- if (!cc)
- return -ENOMEM;
-
- cc->value = value;
- cc->repeat = 0;
- cc->next = *c;
-
- *c = cc;
-
- return 0;
-}
-
static int parse_chain(const char **p, bool usec, CalendarComponent **c) {
const char *t;
CalendarComponent *cc = NULL;
diff --git a/src/test/test-calendarspec.c b/src/test/test-calendarspec.c
index 5a8c6cbfb6..cb2538ed7f 100644
--- a/src/test/test-calendarspec.c
+++ b/src/test/test-calendarspec.c
@@ -124,6 +124,10 @@ int main(int argc, char* argv[]) {
test_one("2016-03-27 03:17:00.4200005", "2016-03-27 03:17:00.420001");
test_one("2016-03-27 03:17:00/0.42", "2016-03-27 03:17:00/0.420000");
test_one("2016-03-27 03:17:00/0.42", "2016-03-27 03:17:00/0.420000");
+ test_one("9..11,13:00,30", "*-*-* 09,10,11,13:00,30:00");
+ test_one("1..3-1..3 1..3:1..3", "*-01,02,03-01,02,03 01,02,03:01,02,03:00");
+ test_one("00:00:1.125..2.125", "*-*-* 00:00:01.125000,02.125000");
+ test_one("00:00:1.0..3.8", "*-*-* 00:00:01,02,03");
test_next("2016-03-27 03:17:00", "", 12345, 1459048620000000);
test_next("2016-03-27 03:17:00", "CET", 12345, 1459041420000000);
@@ -146,6 +150,7 @@ int main(int argc, char* argv[]) {
assert_se(calendar_spec_from_string("2000-03-05.23 00:00:00", &c) < 0);
assert_se(calendar_spec_from_string("2000-03-05 00:00.1:00", &c) < 0);
assert_se(calendar_spec_from_string("00:00:00/0.00000001", &c) < 0);
+ assert_se(calendar_spec_from_string("00:00:00.0..00.9", &c) < 0);
return 0;
}