From e076af9c01fea947abfbe9498e3be925b74c832a Mon Sep 17 00:00:00 2001 From: Milton Mazzarri Date: Mon, 30 Oct 2023 09:37:39 -0500 Subject: [PATCH] bugfix(cron): handle invalid range expressions --- lib/oban/cron/expression.ex | 33 +++++++++++++++++++++++------- test/oban/cron/expression_test.exs | 14 +++++++++++++ 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/lib/oban/cron/expression.ex b/lib/oban/cron/expression.ex index 96da71e0..10c51648 100644 --- a/lib/oban/cron/expression.ex +++ b/lib/oban/cron/expression.ex @@ -110,12 +110,23 @@ defmodule Oban.Cron.Expression do defp parse_part(part, range) do cond do - part == "*" -> range - part =~ ~r/^\d+$/ -> parse_literal(part) - part =~ ~r/^\*\/[1-9]\d?$/ -> parse_step(part, range) - part =~ ~r/^\d+(\-\d+)?\/[1-9]\d?$/ -> parse_range_step(part, range) - part =~ ~r/^\d+\-\d+$/ -> parse_range(part, range) - true -> raise ArgumentError, "unrecognized cron expression: #{part}" + part == "*" -> + range + + part =~ ~r/^\d+$/ -> + parse_literal(part) + + part =~ ~r/^\*\/[1-9]\d?$/ -> + parse_step(part, range) + + part =~ ~r/^\d+(\-\d+)?\/[1-9]\d?$/ -> + parse_range_step(part, range) + + part =~ ~r/^\d+\-\d+$/ -> + parse_range(part, range) + + true -> + raise ArgumentError, "unrecognized cron expression: #{part}" end end @@ -146,7 +157,15 @@ defmodule Oban.Cron.Expression do String.to_integer(rall)..Enum.max(max_range) [rmin, rmax] -> - String.to_integer(rmin)..String.to_integer(rmax) + rmin = String.to_integer(rmin) + rmax = String.to_integer(rmax) + + if rmin <= rmax do + rmin..rmax + else + raise ArgumentError, + "left side (#{rmin}) of the range must be lower or equal than right side (#{rmax})" + end end end end diff --git a/test/oban/cron/expression_test.exs b/test/oban/cron/expression_test.exs index 0f05b975..d5b252fa 100644 --- a/test/oban/cron/expression_test.exs +++ b/test/oban/cron/expression_test.exs @@ -44,6 +44,20 @@ defmodule Oban.Cron.ExpressionTest do end end + test "parsing range expressions where left side is greater than the right side fails" do + expressions = [ + "* * * * SAT-SUN", + "* * * * 6-0", + "9-5 4 * * *", + "* 4-3 * * *", + "* * * 11-1 *" + ] + + for expression <- expressions do + assert_raise ArgumentError, fn -> Expr.parse!(expression) end + end + end + test "parsing non-standard expressions" do assert Expr.parse!("0 0 1 1 *") == Expr.parse!("@annually") assert Expr.parse!("0 0 1 1 *") == Expr.parse!("@yearly")