From 52211370a27b5d1a5c64a5132b4356b5c303e34b Mon Sep 17 00:00:00 2001 From: Florian Knigge Date: Mon, 18 Nov 2024 14:28:32 +0100 Subject: [PATCH 1/4] Allow `W` with ranges in OTHER subfields Especially now these shouldn't be any problems, as they're simply marked in the "static" bitarray. --- ccronexpr_test.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ccronexpr_test.c b/ccronexpr_test.c index e87dc7d..a4da0cc 100644 --- a/ccronexpr_test.c +++ b/ccronexpr_test.c @@ -409,7 +409,8 @@ 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 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")); @@ -425,6 +426,7 @@ 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-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")); @@ -526,6 +528,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 * * ?")); From f465771811243105a526ad9db98ff23d64e3c231 Mon Sep 17 00:00:00 2001 From: Florian Knigge Date: Mon, 18 Nov 2024 14:35:30 +0100 Subject: [PATCH 2/4] Fix test results Were simple copies, now with the real values --- ccronexpr_test.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ccronexpr_test.c b/ccronexpr_test.c index a4da0cc..54e8c56 100644 --- a/ccronexpr_test.c +++ b/ccronexpr_test.c @@ -411,6 +411,8 @@ void test_expr() { 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 * ?", "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")); @@ -426,7 +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-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")); From 020869c2e33ba640188cfa96bf97198cf606270e Mon Sep 17 00:00:00 2001 From: Florian Knigge Date: Mon, 18 Nov 2024 14:36:28 +0100 Subject: [PATCH 3/4] Fix acceptance of `W` with ranges in other list fields Check each sub-field for '-' and '/', not the whole field --- ccronexpr.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/ccronexpr.c b/ccronexpr.c index b0e4e34..da6084a 100644 --- a/ccronexpr.c +++ b/ccronexpr.c @@ -1586,16 +1586,8 @@ 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"; @@ -1603,6 +1595,11 @@ static char *w_check(char *field, cron_expr *target, const char **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"; From b7004c069c7c3beca3cfd6a52718a82e684a4216 Mon Sep 17 00:00:00 2001 From: Florian Knigge Date: Mon, 18 Nov 2024 14:39:40 +0100 Subject: [PATCH 4/4] Update changelog --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index a1167f4..935ad85 100644 --- a/README.md +++ b/README.md @@ -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`