File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -367,6 +367,9 @@ defmodule Duration do
367367
368368 Only seconds may be specified with a decimal fraction, using either a comma or a full stop: `P1DT4,5S`.
369369
370+ Inputs longer than 192 bytes are rejected, which is enough to parse each unit as a maximum signed
371+ 64-bit integer (although it also allows parsing a single unit with 190 digits).
372+
370373 ## Examples
371374
372375 iex> Duration.from_iso8601("P1Y2M3DT4H5M6S")
Original file line number Diff line number Diff line change @@ -706,15 +706,15 @@ defmodule Calendar.ISO do
706706 """
707707 @ doc since: "1.17.0"
708708 @ spec parse_duration ( String . t ( ) ) :: { :ok , [ Duration . unit_pair ( ) ] } | { :error , atom }
709- def parse_duration ( "P" <> string ) when byte_size ( string ) > 0 do
709+ def parse_duration ( "P" <> string ) when byte_size ( string ) in 1 .. 191 do
710710 parse_duration_date ( string , 1 , [ ] , 0 )
711711 end
712712
713- def parse_duration ( "+P" <> string ) when byte_size ( string ) > 0 do
713+ def parse_duration ( "+P" <> string ) when byte_size ( string ) in 1 .. 190 do
714714 parse_duration_date ( string , 1 , [ ] , 0 )
715715 end
716716
717- def parse_duration ( "-P" <> string ) when byte_size ( string ) > 0 do
717+ def parse_duration ( "-P" <> string ) when byte_size ( string ) in 1 .. 190 do
718718 parse_duration_date ( string , - 1 , [ ] , 0 )
719719 end
720720
Original file line number Diff line number Diff line change @@ -246,6 +246,18 @@ defmodule DurationTest do
246246 assert Duration . from_iso8601 ( "PT.6S" ) == { :error , :invalid_time_component }
247247 assert Duration . from_iso8601 ( "PT0.5H" ) == { :error , :invalid_time_component }
248248 assert Duration . from_iso8601 ( "invalid" ) == { :error , :invalid_duration }
249+
250+ # Inputs are capped at 192 bytes
251+ digits = String . duplicate ( "9" , 189 )
252+ assert { :ok , % Duration { } } = Duration . from_iso8601 ( "P9#{ digits } D" )
253+ assert { :ok , % Duration { } } = Duration . from_iso8601 ( "-P#{ digits } D" )
254+ assert { :ok , % Duration { } } = Duration . from_iso8601 ( "+P#{ digits } D" )
255+ assert Duration . from_iso8601 ( "P99#{ digits } D" ) == { :error , :invalid_duration }
256+ assert Duration . from_iso8601 ( "-P9#{ digits } D" ) == { :error , :invalid_duration }
257+ assert Duration . from_iso8601 ( "+P9#{ digits } D" ) == { :error , :invalid_duration }
258+
259+ assert Duration . from_iso8601 ( "P#{ String . duplicate ( "9" , 4_000_000 ) } D" ) ==
260+ { :error , :invalid_duration }
249261 end
250262
251263 test "from_iso8601!/1" do
You can’t perform that action at this time.
0 commit comments