calendarspec: allow ranges in date and time specifications
Resolves #3042
This commit is contained in:
+45
-19
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user