Skip to content

Commit 8a35ffa

Browse files
authored
Reject negative Duration in to_timeout (#15352)
Previously a negative timeout value violating the spec was returned
1 parent bb21320 commit 8a35ffa

2 files changed

Lines changed: 24 additions & 6 deletions

File tree

lib/elixir/lib/kernel.ex

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6421,12 +6421,20 @@ defmodule Kernel do
64216421
{microsecond, _precision} = duration.microsecond
64226422
millisecond = :erlang.convert_time_unit(microsecond, :microsecond, :millisecond)
64236423

6424-
duration.week * unquote(week_in_ms) +
6425-
duration.day * unquote(day_in_ms) +
6426-
duration.hour * unquote(hour_in_ms) +
6427-
duration.minute * 60_000 +
6428-
duration.second * 1000 +
6429-
millisecond
6424+
total =
6425+
duration.week * unquote(week_in_ms) +
6426+
duration.day * unquote(day_in_ms) +
6427+
duration.hour * unquote(hour_in_ms) +
6428+
duration.minute * 60_000 +
6429+
duration.second * 1000 +
6430+
millisecond
6431+
6432+
if total < 0 do
6433+
raise ArgumentError,
6434+
"duration must be positive, got: #{inspect(duration)}"
6435+
end
6436+
6437+
total
64306438
end
64316439
end
64326440

lib/elixir/test/elixir/kernel_test.exs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1550,6 +1550,16 @@ defmodule KernelTest do
15501550
end
15511551
end
15521552

1553+
test "raises on durations that result in a negative timeout" do
1554+
assert_raise ArgumentError,
1555+
~r"duration must be positive",
1556+
fn -> to_timeout(Duration.new!(second: -1)) end
1557+
1558+
assert_raise ArgumentError,
1559+
~r"duration must be positive",
1560+
fn -> to_timeout(Duration.new!(hour: 1, minute: -61)) end
1561+
end
1562+
15531563
test "works with timeouts" do
15541564
assert to_timeout(1_000) == 1_000
15551565
assert to_timeout(0) == 0

0 commit comments

Comments
 (0)