Skip to content

Commit

Permalink
Merge pull request #8 from lobaro/fix/fk/w-field-other-ranges
Browse files Browse the repository at this point in the history
Fix acceptance of `W` with ranges in other list fields
  • Loading branch information
Kniggebrot authored Nov 18, 2024
2 parents ac5f0fa + b7004c0 commit c2ca479
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 10 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ This project is released under the [Apache License 2.0](http://www.apache.org/li

Changelog
---------
**2024-11-18**

* `W` allowed with ranges or iterators in OTHER list fields

**2024-10-25**

* `L` allowed multiple times in day-of-month (DOM) and day-of-week (DOW): Can be used in lists, additionally in DOM alongside W values such as `LW` or `10W`, but not `L-3W`
Expand Down
15 changes: 6 additions & 9 deletions ccronexpr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1586,23 +1586,20 @@ static char *w_check(char *field, cron_expr *target, const char **error) {
}
memset(newField, 0, sizeof(char) * strlen(field));
char *tracking = newField;
// Ensure only 1 day is specified, and W day is not the last in a range or list or iterator of days
if (has_char(field, '/') || has_char(field, '-')) {
*error = "W not allowed in iterators or ranges in 'day of month' field";
goto return_error;
}
// Ensure no specific days are set in day of week
if ((target->days_of_week[0] ^ 0x7f) != 0) {
*error = "Cannot set specific days of week when using 'W' in days of month.";
goto return_error;
}
// Already checked in cron_parse_expr
splitField = split_str(field, ',', &len_out);
if (!splitField) {
*error = "Error splitting 'day of month' field for W detection";
goto return_error;
}
for (size_t i = 0; i < len_out; i++) {
if ((has_w = strchr(splitField[i], 'W'))) {
// Ensure W day is not the end or beginning of a range or iterator
if (has_char(splitField[i], '/') || has_char(splitField[i], '-')) {
*error = "W not allowed in iterators or ranges in 'day of month' field";
goto return_error;
}
// Ensure nothing follows 'W'
if (*(has_w + 1) != '\0') {
*error = "If W is used, 'day of month' element needs to end with it";
Expand Down
10 changes: 9 additions & 1 deletion ccronexpr_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,10 @@ void test_expr() {
assert(check_next("0 0 1 8W,26W * ?", "2022-02-26_00:00:00", "2022-03-08_01:00:00"));
assert(check_next("0 0 1 8W,26W * ?", "2022-03-09_00:00:00", "2022-03-25_01:00:00"));
assert(check_next("0 0 1 29W * ?", "2022-02-28_00:00:00", "2022-03-29_01:00:00"));
assert(check_next("0 0 1 29W * ?", "2024-02-28_00:00:00", "2024-02-29_01:00:00"));
assert(check_next("0 0 1 29W * ?", "2022-02-28_00:00:00", "2022-03-29_01:00:00"));
assert(check_next("0 0 1 1-3,29W * ?", "2024-02-28_00:00:00", "2024-02-29_01:00:00"));
assert(check_next("0 0 1 1-3,29W * ?", "2024-03-01_00:00:00", "2024-03-01_01:00:00"));
assert(check_next("0 0 1 1-3,29W * ?", "2024-03-03_00:00:00", "2024-03-03_01:00:00"));
assert(check_next("0 0 1 31W * ?", "2022-02-28_00:00:00", "2022-03-31_01:00:00"));
assert(check_next("0 0 1 31W * ?", "2022-06-17_00:00:00", "2022-07-29_01:00:00"));
assert(check_next("0 0 1 31W * ?", "2022-07-30_00:00:00", "2022-08-31_01:00:00"));
Expand All @@ -425,6 +428,8 @@ void test_expr() {
assert(check_next("0 0 1 LW * ?", "2022-10-01_00:00:00", "2022-10-31_01:00:00"));
assert(check_next("0 0 1 LW * ?", "2022-07-31_00:00:00", "2022-08-31_01:00:00"));
assert(check_next("0 0 1 LW * ?", "2022-07-30_00:00:00", "2022-08-31_01:00:00"));
assert(check_next("0 0 1 LW,L-3 * ?", "2022-07-30_00:00:00", "2022-08-28_01:00:00"));
assert(check_next("0 0 1 LW,L-3 * ?", "2022-08-29_00:00:00", "2022-08-31_01:00:00"));
cron_init_hash(7);
assert(check_next("H 0 H LW * ?", "2022-10-01_00:00:00", "2022-10-31_14:00:00"));
assert(check_next("0 0 1 L * ?", "2022-05-12_00:00:00", "2022-05-31_01:00:00"));
Expand Down Expand Up @@ -526,6 +531,9 @@ void test_parse() {
assert(check_same("0 0 15 1,16,L * *", "0 0 15 1,L,16 * *"));
assert(check_expr_valid("0 0 15 1,16,L * *"));
assert(check_expr_valid("0 0 15 1,L,16 * *"));
assert(check_expr_valid("0 0 12 LW,L * *"));
assert(check_expr_valid("0 0 12 LW,L-3,L * *"));
assert(check_expr_valid("0 0 12 L-3,LW,L * *"));
// check default hash func has valid output
cron_init_custom_hash_fn(NULL);
assert(check_expr_valid("0 0 1 * * ?"));
Expand Down

0 comments on commit c2ca479

Please sign in to comment.