Skip to content

Commit

Permalink
bugfix(cron): handle invalid range expressions
Browse files Browse the repository at this point in the history
  • Loading branch information
milmazz committed Oct 30, 2023
1 parent e02c918 commit e076af9
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 7 deletions.
33 changes: 26 additions & 7 deletions lib/oban/cron/expression.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
14 changes: 14 additions & 0 deletions test/oban/cron/expression_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down

0 comments on commit e076af9

Please sign in to comment.