From 4ca4afddeb44d4c4420ff2674d836acc1a15d752 Mon Sep 17 00:00:00 2001 From: Chewing_Bever Date: Sun, 15 Jan 2023 08:48:32 +0100 Subject: [PATCH] fix(cron): prevent some illegal expressions; add some tests --- src/cron/c/parse.c | 11 ++++++++--- src/cron/expression.c.v | 39 ++++++++++++++++++++++++++++++++++++++ src/cron/expression_test.v | 10 ---------- src/cron/parse_test.v | 37 ++++++++++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+), 13 deletions(-) create mode 100644 src/cron/parse_test.v diff --git a/src/cron/c/parse.c b/src/cron/c/parse.c index c536237..1ac23c0 100644 --- a/src/cron/c/parse.c +++ b/src/cron/c/parse.c @@ -67,9 +67,14 @@ cron_parse_error ce_parse_range(uint64_t *out, char *s, uint8_t min, uint8_t max uint8_t end = max; uint8_t interval = 0; - if (s[0] == '*' && strlen(s) == 1) { - start = min; - interval = 1; + if (s[0] == '*') { + // A star character is only allowed on its own + if (s[1] == '\0' && dash_index == 0) { + start = min; + interval = 1; + } else { + return cron_parse_invalid_expression; + } }else { SAFE_ATOI(start, s, min, max); diff --git a/src/cron/expression.c.v b/src/cron/expression.c.v index cd4b8b0..0217ca3 100644 --- a/src/cron/expression.c.v +++ b/src/cron/expression.c.v @@ -18,6 +18,45 @@ pub struct C.cron_expression { pub type Expression = C.cron_expression +// == returns whether the two expressions are equal by value. +fn (ce1 Expression) == (ce2 Expression) bool { + if ce1.month_count != ce2.month_count || ce1.day_count != ce2.day_count + || ce1.hour_count != ce2.hour_count || ce1.minute_count != ce2.minute_count { + return false + } + + for i in 0 .. ce1.month_count { + unsafe { + if ce1.months[i] != ce2.months[i] { + return false + } + } + } + for i in 0 .. ce1.day_count { + unsafe { + if ce1.days[i] != ce2.days[i] { + return false + } + } + } + for i in 0 .. ce1.hour_count { + unsafe { + if ce1.hours[i] != ce2.hours[i] { + return false + } + } + } + for i in 0 .. ce1.minute_count { + unsafe { + if ce1.minutes[i] != ce2.minutes[i] { + return false + } + } + } + + return true +} + struct C.cron_simple_time { year int month int diff --git a/src/cron/expression_test.v b/src/cron/expression_test.v index 4023012..a8ec5a5 100644 --- a/src/cron/expression_test.v +++ b/src/cron/expression_test.v @@ -34,13 +34,3 @@ fn test_next_simple() ! { //// Overlap to next year util_test_time('0 3', '2002-12-31 04:00:00', '2003-01-01 03:00:00')! } - -fn test_leading_star() { - mut x := false - parse_expression('*5 8') or { x = true } - assert x - - x = false - parse_expression('x 8') or { x = true } - assert x -} diff --git a/src/cron/parse_test.v b/src/cron/parse_test.v new file mode 100644 index 0000000..692a381 --- /dev/null +++ b/src/cron/parse_test.v @@ -0,0 +1,37 @@ +module cron + +fn test_not_allowed() { + mut res := false + parse_expression('4 *-7') or { res = true } + assert res + + res = false + parse_expression('4 *-7/4') or { res = true } + assert res + + res = false + parse_expression('4 7/*') or { res = true } + assert res + + res = false + parse_expression('0 0 30 2') or { res = true } + assert res +} + +fn test_leading_star() { + mut x := false + parse_expression('*5 8') or { x = true } + assert x + + x = false + parse_expression('x 8') or { x = true } + assert x +} + +fn test_auto_extend() ! { + ce1 := parse_expression('5 5')! + ce2 := parse_expression('5 5 *')! + ce3 := parse_expression('5 5 * *')! + + assert ce1 == ce2 && ce2 == ce3 +}