Skip to content

Commit 0d0341f

Browse files
committed
Handle too long dates passed to DateTime.parse
Since Ruby 3.0.3, this method raises an ArgumentError with a different message from the invalid date message, as mitigation for CVE-2021-41817. https://www.ruby-lang.org/en/news/2021/11/15/date-parsing-method-regexp-dos-cve-2021-41817/ Example: ArgumentError: string length (150) exceeds the limit 128 In this case we should just return nil, like when the date itself is invalid.
1 parent 6e5db59 commit 0d0341f

File tree

2 files changed

+31
-19
lines changed

2 files changed

+31
-19
lines changed

lib/mail/fields/common_date_field.rb

+25-19
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,32 @@
44

55
module Mail
66
class CommonDateField < NamedStructuredField #:nodoc:
7-
def self.singular?
8-
true
9-
end
7+
class << self
8+
def singular?
9+
true
10+
end
1011

11-
def self.normalize_datetime(string)
12-
if Utilities.blank?(string)
13-
datetime = ::DateTime.now
14-
else
15-
stripped = string.to_s.gsub(/\(.*?\)/, '').squeeze(' ')
16-
begin
17-
datetime = ::DateTime.parse(stripped)
18-
rescue ArgumentError => e
19-
raise unless 'invalid date' == e.message
12+
def normalize_datetime(string)
13+
if Utilities.blank?(string)
14+
datetime = ::DateTime.now
15+
else
16+
stripped = string.to_s.gsub(/\(.*?\)/, '').squeeze(' ')
17+
with_invalid_date_time_error_handling do
18+
datetime = ::DateTime.parse(stripped)
19+
end
20+
end
21+
22+
if datetime
23+
datetime.strftime('%a, %d %b %Y %H:%M:%S %z')
24+
else
25+
string
2026
end
2127
end
2228

23-
if datetime
24-
datetime.strftime('%a, %d %b %Y %H:%M:%S %z')
25-
else
26-
string
29+
def with_invalid_date_time_error_handling(&block)
30+
yield
31+
rescue ArgumentError => e
32+
raise unless e.message =~ /\A(invalid date|string length \(\d+\) exceeds the limit \d+)\z/
2733
end
2834
end
2935

@@ -33,9 +39,9 @@ def initialize(value = nil, charset = nil)
3339

3440
# Returns a date time object of the parsed date
3541
def date_time
36-
::DateTime.parse("#{element.date_string} #{element.time_string}")
37-
rescue ArgumentError => e
38-
raise e unless e.message == 'invalid date'
42+
self.class.with_invalid_date_time_error_handling do
43+
::DateTime.parse("#{element.date_string} #{element.time_string}")
44+
end
3945
end
4046

4147
def default

spec/mail/fields/date_field_spec.rb

+6
Original file line numberDiff line numberDiff line change
@@ -66,5 +66,11 @@
6666
field = Mail::DateField.new("12 Aug 2009 30:00:02 GMT")
6767
expect(field.date_time).to be_nil
6868
end
69+
70+
it "should handle too long invalid date" do
71+
# field = Mail::DateField.new("12 Aug 2009 30:00:02 GMT")
72+
field = Mail::DateField.new("Wed, 23 Jan 2019 30:51:32 -0500")
73+
expect(field.date_time).to be_nil
74+
end
6975
end
7076
end

0 commit comments

Comments
 (0)