diff --git a/src/cron/expression/c/expression.c b/src/cron/expression/c/expression.c index c990b4f..f9dc534 100644 --- a/src/cron/expression/c/expression.c +++ b/src/cron/expression/c/expression.c @@ -48,7 +48,7 @@ int ce_next(struct cron_simple_time *out, struct cron_expression *ce, struct cro // Minute is the only value where we explicitely make sure we // can't match sref's value exactly. This is to ensure we only // return values in the future. - while (minute_index < ce->minute_count && ref->minute > ce->minutes[minute_index]) { + while (minute_index < ce->minute_count && ref->minute >= ce->minutes[minute_index]) { minute_index++; } } @@ -91,7 +91,7 @@ int ce_next(struct cron_simple_time *out, struct cron_expression *ce, struct cro } } - out->month = ce->months[month_index * ce->month_count]; + out->month = ce->months[month_index % ce->month_count]; if (month_index >= ce->month_count) { out->year = ref->year + 1; diff --git a/src/cron/expression/c/parse.c b/src/cron/expression/c/parse.c index b49b5dd..e664dd8 100644 --- a/src/cron/expression/c/parse.c +++ b/src/cron/expression/c/parse.c @@ -80,10 +80,10 @@ enum cron_parse_error ce_parse_range(uint64_t *out, char *s, uint8_t min, uint8_ // Single number doesn't need to loop if (end == 0 && slash_index == 0) { - *out |= 1 << (start - min); + *out |= ((uint64_t) 1) << (start - min); } else { for (;start <= end; start += interval) { - *out |= 1 << (start - min); + *out |= ((uint64_t) 1) << (start - min); start += interval; } } @@ -109,13 +109,7 @@ enum cron_parse_error ce_parse_part(uint64_t *out, char *s, uint8_t min, uint8_t } // Make sure to parse the final range as well - res = ce_parse_range(out, s, min, max); - - if (res != CPEParseOk) { - return res; - } - - return CPEParseOk; + return ce_parse_range(out, s, min, max); } uint8_t bf_to_nums(uint8_t **out, uint64_t bf, uint8_t min, uint8_t max) { @@ -125,7 +119,7 @@ uint8_t bf_to_nums(uint8_t **out, uint64_t bf, uint8_t min, uint8_t max) { uint8_t *buf = malloc(capacity * sizeof(uint8_t)); for (uint8_t i = 0; i <= max - min; i++) { - if ((1 << i) & bf) { + if (((uint64_t) 1 << i) & bf) { // Resize buffer if needed if (size == capacity) { capacity *= 2; @@ -150,11 +144,12 @@ uint8_t bf_to_nums(uint8_t **out, uint64_t bf, uint8_t min, uint8_t max) { enum cron_parse_error ce_parse_expression(struct cron_expression *out, char *s) { // The parsing functions modify the input string in-place s = strdup(s); + char *orig_s = s; uint8_t part_count = 0; char *next; - enum cron_parse_error res; + enum cron_parse_error res = CPEParseOk; uint64_t bfs[4]; // Skip leading spaces @@ -167,10 +162,9 @@ enum cron_parse_error ce_parse_expression(struct cron_expression *out, char *s) res = ce_parse_part(&bfs[part_count], s, min[part_count], max[part_count]); if (res != CPEParseOk) { - return res; + goto end; } - s = next + 1; size_t offset = 1; // Skip multiple spaces @@ -188,7 +182,7 @@ enum cron_parse_error ce_parse_expression(struct cron_expression *out, char *s) res = ce_parse_part(&bfs[part_count], s, min[part_count], max[part_count]); if (res != CPEParseOk) { - return res; + goto end; } part_count++; @@ -196,7 +190,8 @@ enum cron_parse_error ce_parse_expression(struct cron_expression *out, char *s) // At least two parts need to be provided if (part_count < 2) { - return CPEParseInvalidExpression; + res = CPEParseInvalidExpression; + goto end; } // Ensure there's always 4 parts, as expressions can have between 2 and 4 parts @@ -211,5 +206,9 @@ enum cron_parse_error ce_parse_expression(struct cron_expression *out, char *s) out->day_count = bf_to_nums(&out->days, bfs[2], min[2], max[2]); out->month_count = bf_to_nums(&out->months, bfs[3], min[3], max[3]); - return CPEParseOk; +end: + // s is cloned + free(orig_s); + + return res; }