mail 2.1.5.3 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of mail might be problematic. Click here for more details.

Files changed (60) hide show
  1. data/CHANGELOG.rdoc +16 -0
  2. data/Rakefile +1 -1
  3. data/lib/mail.rb +3 -1
  4. data/lib/mail/body.rb +3 -2
  5. data/lib/mail/core_extensions/string.rb +4 -0
  6. data/lib/mail/elements/address.rb +3 -3
  7. data/lib/mail/elements/content_transfer_encoding_element.rb +1 -1
  8. data/lib/mail/encodings.rb +48 -8
  9. data/lib/mail/encodings/quoted_printable.rb +1 -14
  10. data/lib/mail/field.rb +44 -44
  11. data/lib/mail/fields/bcc_field.rb +3 -2
  12. data/lib/mail/fields/cc_field.rb +3 -2
  13. data/lib/mail/fields/comments_field.rb +3 -3
  14. data/lib/mail/fields/common/common_address.rb +19 -10
  15. data/lib/mail/fields/common/common_field.rb +6 -6
  16. data/lib/mail/fields/common/common_message_id.rb +1 -1
  17. data/lib/mail/fields/content_description_field.rb +3 -3
  18. data/lib/mail/fields/content_disposition_field.rb +3 -3
  19. data/lib/mail/fields/content_id_field.rb +6 -6
  20. data/lib/mail/fields/content_location_field.rb +3 -3
  21. data/lib/mail/fields/content_transfer_encoding_field.rb +6 -3
  22. data/lib/mail/fields/content_type_field.rb +8 -7
  23. data/lib/mail/fields/date_field.rb +8 -8
  24. data/lib/mail/fields/from_field.rb +3 -3
  25. data/lib/mail/fields/in_reply_to_field.rb +3 -2
  26. data/lib/mail/fields/keywords_field.rb +3 -2
  27. data/lib/mail/fields/message_id_field.rb +4 -3
  28. data/lib/mail/fields/mime_version_field.rb +5 -6
  29. data/lib/mail/fields/received_field.rb +3 -2
  30. data/lib/mail/fields/references_field.rb +3 -3
  31. data/lib/mail/fields/reply_to_field.rb +3 -3
  32. data/lib/mail/fields/resent_bcc_field.rb +3 -3
  33. data/lib/mail/fields/resent_cc_field.rb +3 -3
  34. data/lib/mail/fields/resent_date_field.rb +7 -7
  35. data/lib/mail/fields/resent_from_field.rb +3 -3
  36. data/lib/mail/fields/resent_message_id_field.rb +3 -3
  37. data/lib/mail/fields/resent_sender_field.rb +3 -3
  38. data/lib/mail/fields/resent_to_field.rb +3 -3
  39. data/lib/mail/fields/return_path_field.rb +3 -3
  40. data/lib/mail/fields/sender_field.rb +3 -3
  41. data/lib/mail/fields/structured_field.rb +12 -3
  42. data/lib/mail/fields/subject_field.rb +3 -2
  43. data/lib/mail/fields/to_field.rb +3 -3
  44. data/lib/mail/fields/unstructured_field.rb +68 -26
  45. data/lib/mail/header.rb +20 -4
  46. data/lib/mail/message.rb +36 -26
  47. data/lib/mail/parsers/content_disposition.rb +1 -1
  48. data/lib/mail/parsers/content_disposition.treetop +1 -1
  49. data/lib/mail/parsers/content_transfer_encoding.rb +1 -8
  50. data/lib/mail/parsers/content_transfer_encoding.treetop +1 -1
  51. data/lib/mail/parsers/content_type.rb +1 -1
  52. data/lib/mail/parsers/content_type.treetop +1 -1
  53. data/lib/mail/parsers/rfc2045.rb +6 -6
  54. data/lib/mail/parsers/rfc2045.treetop +1 -1
  55. data/lib/mail/parsers/rfc2822.rb +236 -236
  56. data/lib/mail/parsers/rfc2822.treetop +12 -12
  57. data/lib/mail/patterns.rb +6 -4
  58. data/lib/mail/utilities.rb +8 -5
  59. data/lib/mail/version.rb +3 -4
  60. metadata +16 -17
@@ -3,14 +3,23 @@ require 'mail/fields/common/address_container'
3
3
 
4
4
  module Mail
5
5
  module CommonAddress # :nodoc:
6
+
6
7
  def parse(val = value)
7
8
  unless val.blank?
8
- @tree = AddressList.new(val)
9
+ @tree = AddressList.new(encode_if_needed(val))
9
10
  else
10
11
  nil
11
12
  end
12
13
  end
13
14
 
15
+ def charset
16
+ @charset
17
+ end
18
+
19
+ def encode_if_needed(val)
20
+ Encodings.address_encode(val, charset)
21
+ end
22
+
14
23
  # Allows you to iterate through each address object in the syntax tree
15
24
  def each
16
25
  tree.addresses.each do |address|
@@ -29,28 +38,28 @@ module Mail
29
38
  list = tree.addresses.map { |a| a.format }
30
39
  Mail::AddressContainer.new(self, list)
31
40
  end
32
-
41
+
33
42
  # Returns the display name of all the addresses in the address list
34
43
  def display_names
35
44
  list = tree.addresses.map { |a| a.display_name }
36
45
  Mail::AddressContainer.new(self, list)
37
46
  end
38
-
47
+
39
48
  # Returns the actual address objects in the address list
40
49
  def addrs
41
50
  list = tree.addresses
42
51
  Mail::AddressContainer.new(self, list)
43
52
  end
44
-
53
+
45
54
  # Returns a hash of group name => address strings for the address list
46
55
  def groups
47
56
  @groups = Hash.new
48
57
  tree.group_recipients.each do |group|
49
- @groups[group.group_name.text_value] = get_group_addresses(group.group_list)
58
+ @groups[group.group_name.text_value.to_str] = get_group_addresses(group.group_list)
50
59
  end
51
60
  @groups
52
61
  end
53
-
62
+
54
63
  # Returns the addresses that are part of groups
55
64
  def group_addresses
56
65
  groups.map { |k,v| v.map { |a| a.format } }.flatten
@@ -60,7 +69,7 @@ module Mail
60
69
  def group_names # :nodoc:
61
70
  tree.group_names
62
71
  end
63
-
72
+
64
73
  def default
65
74
  addresses
66
75
  end
@@ -75,9 +84,9 @@ module Mail
75
84
  parse((formatted + [val]).join(", "))
76
85
  end
77
86
  end
78
-
87
+
79
88
  private
80
-
89
+
81
90
  def do_encode(field_name)
82
91
  return '' if value.blank?
83
92
  address_array = tree.addresses.reject { |a| group_addresses.include?(a.encoded) }.compact.map { |a| a.encoded }
@@ -102,7 +111,7 @@ module Mail
102
111
  def tree # :nodoc:
103
112
  @tree ||= AddressList.new(value)
104
113
  end
105
-
114
+
106
115
  def get_group_addresses(group_list)
107
116
  if group_list.respond_to?(:addresses)
108
117
  group_list.addresses.map do |address_tree|
@@ -29,20 +29,20 @@ module Mail
29
29
  end
30
30
 
31
31
  def field_length
32
- @length ||= name.length + value.length + ': '.length
32
+ @length ||= "#{name}: #{encode(decoded)}".length
33
33
  end
34
34
 
35
35
  def responsible_for?( val )
36
36
  name.to_s.downcase == val.to_s.downcase
37
37
  end
38
-
38
+
39
39
  private
40
40
 
41
- def strip_field(field_name, string)
42
- if string.is_a?(Array)
43
- string.join(', ')
41
+ def strip_field(field_name, value)
42
+ if value.is_a?(Array)
43
+ value
44
44
  else
45
- string.to_s.gsub(/#{field_name}:\s+/i, '')
45
+ value.to_s.gsub(/#{field_name}:\s+/i, '')
46
46
  end
47
47
  end
48
48
 
@@ -4,7 +4,7 @@ module Mail
4
4
  def element
5
5
  @element ||= Mail::MessageIdsElement.new(value)
6
6
  end
7
-
7
+
8
8
  def parse(val = value)
9
9
  unless val.blank?
10
10
  @element = Mail::MessageIdsElement.new(val)
@@ -8,11 +8,11 @@ module Mail
8
8
  FIELD_NAME = 'content-description'
9
9
  CAPITALIZED_FIELD = 'Content-Description'
10
10
 
11
- def initialize(*args)
12
- super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, args.last))
11
+ def initialize(value = nil, charset = 'utf-8')
12
+ self.charset = charset
13
+ super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
13
14
  self.parse
14
15
  self
15
-
16
16
  end
17
17
 
18
18
  end
@@ -7,11 +7,11 @@ module Mail
7
7
  FIELD_NAME = 'content-disposition'
8
8
  CAPITALIZED_FIELD = 'Content-Disposition'
9
9
 
10
- def initialize(*args)
11
- super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, args.last))
10
+ def initialize(value = nil, charset = 'utf-8')
11
+ self.charset = charset
12
+ super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
12
13
  self.parse
13
14
  self
14
-
15
15
  end
16
16
 
17
17
  def parse(val = value)
@@ -8,17 +8,17 @@ module Mail
8
8
  FIELD_NAME = 'content-id'
9
9
  CAPITALIZED_FIELD = "Content-ID"
10
10
 
11
- def initialize(*args)
11
+ def initialize(value = nil, charset = 'utf-8')
12
+ self.charset = charset
12
13
  @uniq = 1
13
- if args.last.blank?
14
- self.name = CAPITALIZED_FIELD
15
- self.value = generate_content_id
14
+ if value.blank?
15
+ value = generate_content_id
16
16
  else
17
- super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, args.last))
17
+ value = strip_field(FIELD_NAME, value)
18
18
  end
19
+ super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
19
20
  self.parse
20
21
  self
21
-
22
22
  end
23
23
 
24
24
  def parse(val = value)
@@ -8,11 +8,11 @@ module Mail
8
8
  FIELD_NAME = 'content-location'
9
9
  CAPITALIZED_FIELD = 'Content-Location'
10
10
 
11
- def initialize(*args)
12
- super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, args.last))
11
+ def initialize(value = nil, charset = 'utf-8')
12
+ self.charset = charset
13
+ super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
13
14
  self.parse
14
15
  self
15
-
16
16
  end
17
17
 
18
18
  def parse(val = value)
@@ -8,9 +8,12 @@ module Mail
8
8
  FIELD_NAME = 'content-transfer-encoding'
9
9
  CAPITALIZED_FIELD = 'Content-Transfer-Encoding'
10
10
 
11
- def initialize(*args)
12
- super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, args.last.to_s.downcase))
13
- parse(value)
11
+ def initialize(value = nil, charset = 'utf-8')
12
+ self.charset = charset
13
+ value = '7bit' if value.to_s =~ /7-bit/i
14
+ value = '8bit' if value.to_s =~ /8-bit/i
15
+ super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
16
+ self.parse
14
17
  self
15
18
  end
16
19
 
@@ -7,18 +7,19 @@ module Mail
7
7
  FIELD_NAME = 'content-type'
8
8
  CAPITALIZED_FIELD = 'Content-Type'
9
9
 
10
- def initialize(*args)
11
- if args.last.class == Array
12
- @main_type = args.last[0]
13
- @sub_type = args.last[1]
14
- @parameters = ParameterHash.new.merge!(args.last.last)
15
- super(CAPITALIZED_FIELD, args.last)
10
+ def initialize(value = nil, charset = 'utf-8')
11
+ self.charset = charset
12
+ if value.class == Array
13
+ @main_type = value[0]
14
+ @sub_type = value[1]
15
+ @parameters = ParameterHash.new.merge!(value.last)
16
16
  else
17
17
  @main_type = nil
18
18
  @sub_type = nil
19
19
  @parameters = nil
20
- super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, args.last))
20
+ value = strip_field(FIELD_NAME, value)
21
21
  end
22
+ super(CAPITALIZED_FIELD, value, charset)
22
23
  self.parse
23
24
  self
24
25
  end
@@ -31,16 +31,16 @@ module Mail
31
31
  FIELD_NAME = 'date'
32
32
  CAPITALIZED_FIELD = "Date"
33
33
 
34
- def initialize(*args)
35
- if args.last.blank?
36
- self.name = CAPITALIZED_FIELD
37
- self.value = Time.now.strftime('%a, %d %b %Y %H:%M:%S %z')
38
- self
34
+ def initialize(value = nil, charset = 'utf-8')
35
+ self.charset = charset
36
+ if value.blank?
37
+ value = Time.now.strftime('%a, %d %b %Y %H:%M:%S %z')
39
38
  else
40
- value = strip_field(FIELD_NAME, args.last)
41
- value = ::DateTime.parse(value.to_s).strftime('%a, %d %b %Y %H:%M:%S %z')
42
- super(CAPITALIZED_FIELD, value)
39
+ value = strip_field(FIELD_NAME, value)
40
+ value.to_s.gsub!(/\(.*?\)/, '')
41
+ value = ::DateTime.parse(value.to_s.squeeze(" ")).strftime('%a, %d %b %Y %H:%M:%S %z')
43
42
  end
43
+ super(CAPITALIZED_FIELD, value, charset)
44
44
  end
45
45
 
46
46
  def encoded
@@ -36,11 +36,11 @@ module Mail
36
36
  FIELD_NAME = 'from'
37
37
  CAPITALIZED_FIELD = 'From'
38
38
 
39
- def initialize(*args)
40
- super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, args.last))
39
+ def initialize(value = nil, charset = 'utf-8')
40
+ self.charset = charset
41
+ super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
41
42
  self.parse
42
43
  self
43
-
44
44
  end
45
45
 
46
46
  def encoded
@@ -36,8 +36,9 @@ module Mail
36
36
  FIELD_NAME = 'in-reply-to'
37
37
  CAPITALIZED_FIELD = 'In-Reply-To'
38
38
 
39
- def initialize(*args)
40
- super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, args.last))
39
+ def initialize(value = nil, charset = 'utf-8')
40
+ self.charset = charset
41
+ super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
41
42
  self.parse
42
43
  self
43
44
  end
@@ -7,8 +7,9 @@ module Mail
7
7
  FIELD_NAME = 'keywords'
8
8
  CAPITALIZED_FIELD = 'Keywords'
9
9
 
10
- def initialize(*args)
11
- super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, args.last))
10
+ def initialize(value = nil, charset = 'utf-8')
11
+ self.charset = charset
12
+ super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
12
13
  self.parse
13
14
  self
14
15
  end
@@ -38,13 +38,14 @@ module Mail
38
38
  FIELD_NAME = 'message-id'
39
39
  CAPITALIZED_FIELD = 'Message-ID'
40
40
 
41
- def initialize(*args)
41
+ def initialize(value = nil, charset = 'utf-8')
42
+ self.charset = charset
42
43
  @uniq = 1
43
- if args.last.blank?
44
+ if value.blank?
44
45
  self.name = CAPITALIZED_FIELD
45
46
  self.value = generate_message_id
46
47
  else
47
- super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, args.last))
48
+ super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
48
49
  end
49
50
  self.parse
50
51
  self
@@ -8,13 +8,12 @@ module Mail
8
8
  FIELD_NAME = 'mime-version'
9
9
  CAPITALIZED_FIELD = 'Mime-Version'
10
10
 
11
- def initialize(*args)
12
- if args.last.blank?
13
- self.name = CAPITALIZED_FIELD
14
- self.value = '1.0'
15
- else
16
- super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, args.last))
11
+ def initialize(value = nil, charset = 'utf-8')
12
+ self.charset = charset
13
+ if value.blank?
14
+ value = '1.0'
17
15
  end
16
+ super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
18
17
  self.parse
19
18
  self
20
19
 
@@ -25,8 +25,9 @@ module Mail
25
25
  FIELD_NAME = 'received'
26
26
  CAPITALIZED_FIELD = 'Received'
27
27
 
28
- def initialize(*args)
29
- super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, args.last))
28
+ def initialize(value = nil, charset = 'utf-8')
29
+ self.charset = charset
30
+ super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
30
31
  self.parse
31
32
  self
32
33
 
@@ -36,11 +36,11 @@ module Mail
36
36
  FIELD_NAME = 'references'
37
37
  CAPITALIZED_FIELD = 'References'
38
38
 
39
- def initialize(*args)
40
- super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, args.last))
39
+ def initialize(value = nil, charset = 'utf-8')
40
+ self.charset = charset
41
+ super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
41
42
  self.parse
42
43
  self
43
-
44
44
  end
45
45
 
46
46
  def encoded
@@ -36,11 +36,11 @@ module Mail
36
36
  FIELD_NAME = 'reply-to'
37
37
  CAPITALIZED_FIELD = 'Reply-To'
38
38
 
39
- def initialize(*args)
40
- super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, args.last))
39
+ def initialize(value = nil, charset = 'utf-8')
40
+ self.charset = charset
41
+ super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
41
42
  self.parse
42
43
  self
43
-
44
44
  end
45
45
 
46
46
  def encoded
@@ -36,11 +36,11 @@ module Mail
36
36
  FIELD_NAME = 'resent-bcc'
37
37
  CAPITALIZED_FIELD = 'Resent-Bcc'
38
38
 
39
- def initialize(*args)
40
- super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, args.last))
39
+ def initialize(value = nil, charset = 'utf-8')
40
+ self.charset = charset
41
+ super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
41
42
  self.parse
42
43
  self
43
-
44
44
  end
45
45
 
46
46
  def encoded
@@ -36,11 +36,11 @@ module Mail
36
36
  FIELD_NAME = 'resent-cc'
37
37
  CAPITALIZED_FIELD = 'Resent-Cc'
38
38
 
39
- def initialize(*args)
40
- super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, args.last))
39
+ def initialize(value = nil, charset = 'utf-8')
40
+ self.charset = charset
41
+ super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
41
42
  self.parse
42
43
  self
43
-
44
44
  end
45
45
 
46
46
  def encoded
@@ -11,16 +11,16 @@ module Mail
11
11
  FIELD_NAME = 'resent-date'
12
12
  CAPITALIZED_FIELD = 'Resent-Date'
13
13
 
14
- def initialize(*args)
15
- if args.last.blank?
16
- self.name = CAPITALIZED_FIELD
17
- self.value = Time.now.strftime('%a, %d %b %Y %H:%M:%S %z')
18
- self
14
+ def initialize(value = nil, charset = 'utf-8')
15
+ self.charset = charset
16
+ if value.blank?
17
+ value = Time.now.strftime('%a, %d %b %Y %H:%M:%S %z')
19
18
  else
20
- value = strip_field(FIELD_NAME, args.last)
19
+ value = strip_field(FIELD_NAME, value)
21
20
  value = ::DateTime.parse(value.to_s).strftime('%a, %d %b %Y %H:%M:%S %z')
22
- super(CAPITALIZED_FIELD, value)
23
21
  end
22
+ super(CAPITALIZED_FIELD, value, charset)
23
+ self
24
24
  end
25
25
 
26
26
  def encoded