mail 2.7.0.rc1 → 2.7.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +71 -98
  3. data/lib/mail.rb +1 -6
  4. data/lib/mail/attachments_list.rb +5 -2
  5. data/lib/mail/body.rb +39 -33
  6. data/lib/mail/check_delivery_params.rb +8 -6
  7. data/lib/mail/configuration.rb +2 -0
  8. data/lib/mail/elements/address.rb +19 -18
  9. data/lib/mail/encodings.rb +89 -31
  10. data/lib/mail/encodings/7bit.rb +5 -15
  11. data/lib/mail/encodings/8bit.rb +2 -21
  12. data/lib/mail/encodings/base64.rb +11 -12
  13. data/lib/mail/encodings/binary.rb +3 -22
  14. data/lib/mail/encodings/identity.rb +24 -0
  15. data/lib/mail/encodings/quoted_printable.rb +6 -6
  16. data/lib/mail/encodings/transfer_encoding.rb +38 -29
  17. data/lib/mail/encodings/unix_to_unix.rb +2 -1
  18. data/lib/mail/envelope.rb +1 -1
  19. data/lib/mail/field.rb +93 -61
  20. data/lib/mail/fields/bcc_field.rb +2 -2
  21. data/lib/mail/fields/cc_field.rb +1 -1
  22. data/lib/mail/fields/comments_field.rb +1 -1
  23. data/lib/mail/fields/common/common_address.rb +32 -7
  24. data/lib/mail/fields/common/common_field.rb +1 -10
  25. data/lib/mail/fields/content_description_field.rb +1 -1
  26. data/lib/mail/fields/content_disposition_field.rb +3 -3
  27. data/lib/mail/fields/content_id_field.rb +2 -2
  28. data/lib/mail/fields/content_location_field.rb +1 -1
  29. data/lib/mail/fields/content_transfer_encoding_field.rb +1 -1
  30. data/lib/mail/fields/content_type_field.rb +1 -1
  31. data/lib/mail/fields/date_field.rb +2 -3
  32. data/lib/mail/fields/from_field.rb +1 -1
  33. data/lib/mail/fields/in_reply_to_field.rb +1 -1
  34. data/lib/mail/fields/keywords_field.rb +1 -1
  35. data/lib/mail/fields/message_id_field.rb +1 -1
  36. data/lib/mail/fields/mime_version_field.rb +1 -1
  37. data/lib/mail/fields/optional_field.rb +4 -1
  38. data/lib/mail/fields/received_field.rb +1 -1
  39. data/lib/mail/fields/references_field.rb +1 -1
  40. data/lib/mail/fields/reply_to_field.rb +1 -1
  41. data/lib/mail/fields/resent_bcc_field.rb +1 -1
  42. data/lib/mail/fields/resent_cc_field.rb +1 -1
  43. data/lib/mail/fields/resent_date_field.rb +0 -1
  44. data/lib/mail/fields/resent_from_field.rb +1 -1
  45. data/lib/mail/fields/resent_message_id_field.rb +1 -1
  46. data/lib/mail/fields/resent_sender_field.rb +1 -1
  47. data/lib/mail/fields/resent_to_field.rb +1 -1
  48. data/lib/mail/fields/return_path_field.rb +1 -1
  49. data/lib/mail/fields/sender_field.rb +1 -1
  50. data/lib/mail/fields/subject_field.rb +1 -1
  51. data/lib/mail/fields/to_field.rb +1 -1
  52. data/lib/mail/fields/unstructured_field.rb +19 -2
  53. data/lib/mail/header.rb +9 -8
  54. data/lib/mail/mail.rb +2 -10
  55. data/lib/mail/matchers/has_sent_mail.rb +21 -1
  56. data/lib/mail/message.rb +64 -51
  57. data/lib/mail/multibyte.rb +14 -16
  58. data/lib/mail/multibyte/chars.rb +2 -1
  59. data/lib/mail/network.rb +1 -0
  60. data/lib/mail/network/delivery_methods/exim.rb +6 -10
  61. data/lib/mail/network/delivery_methods/logger_delivery.rb +37 -0
  62. data/lib/mail/network/delivery_methods/sendmail.rb +8 -4
  63. data/lib/mail/network/delivery_methods/smtp.rb +56 -55
  64. data/lib/mail/network/delivery_methods/smtp_connection.rb +9 -1
  65. data/lib/mail/network/retriever_methods/imap.rb +18 -5
  66. data/lib/mail/network/retriever_methods/pop3.rb +3 -1
  67. data/lib/mail/parser_tools.rb +15 -0
  68. data/lib/mail/parsers/address_lists_parser.rb +30462 -12597
  69. data/lib/mail/parsers/address_lists_parser.rl +18 -12
  70. data/lib/mail/parsers/content_disposition_parser.rb +405 -215
  71. data/lib/mail/parsers/content_disposition_parser.rl +11 -5
  72. data/lib/mail/parsers/content_location_parser.rb +443 -208
  73. data/lib/mail/parsers/content_location_parser.rl +9 -3
  74. data/lib/mail/parsers/content_transfer_encoding_parser.rb +180 -80
  75. data/lib/mail/parsers/content_transfer_encoding_parser.rl +8 -2
  76. data/lib/mail/parsers/content_type_parser.rb +436 -245
  77. data/lib/mail/parsers/content_type_parser.rl +12 -6
  78. data/lib/mail/parsers/date_time_parser.rb +172 -72
  79. data/lib/mail/parsers/date_time_parser.rl +10 -4
  80. data/lib/mail/parsers/envelope_from_parser.rb +2833 -1320
  81. data/lib/mail/parsers/envelope_from_parser.rl +9 -3
  82. data/lib/mail/parsers/message_ids_parser.rb +2325 -976
  83. data/lib/mail/parsers/message_ids_parser.rl +9 -3
  84. data/lib/mail/parsers/mime_version_parser.rb +164 -64
  85. data/lib/mail/parsers/mime_version_parser.rl +9 -3
  86. data/lib/mail/parsers/phrase_lists_parser.rb +582 -237
  87. data/lib/mail/parsers/phrase_lists_parser.rl +9 -3
  88. data/lib/mail/parsers/received_parser.rb +7036 -3004
  89. data/lib/mail/parsers/received_parser.rl +11 -5
  90. data/lib/mail/parsers/rfc2045_content_transfer_encoding.rl +1 -0
  91. data/lib/mail/parsers/rfc2045_content_type.rl +1 -0
  92. data/lib/mail/parsers/rfc2045_mime.rl +1 -0
  93. data/lib/mail/parsers/rfc2183_content_disposition.rl +1 -0
  94. data/lib/mail/parsers/rfc3629_utf8.rl +19 -0
  95. data/lib/mail/parsers/rfc5234_abnf_core_rules.rl +7 -1
  96. data/lib/mail/parsers/rfc5322.rl +3 -1
  97. data/lib/mail/parsers/rfc5322_address.rl +3 -1
  98. data/lib/mail/parsers/rfc5322_date_time.rl +1 -0
  99. data/lib/mail/parsers/rfc5322_lexical_tokens.rl +9 -5
  100. data/lib/mail/part.rb +1 -1
  101. data/lib/mail/utilities.rb +44 -15
  102. data/lib/mail/version.rb +1 -1
  103. data/lib/mail/version_specific/ruby_1_8.rb +12 -1
  104. data/lib/mail/version_specific/ruby_1_9.rb +13 -1
  105. metadata +7 -13
  106. data/CHANGELOG.rdoc +0 -822
  107. data/CONTRIBUTING.md +0 -60
  108. data/Dependencies.txt +0 -1
  109. data/Gemfile +0 -11
  110. data/Rakefile +0 -23
  111. data/TODO.rdoc +0 -9
  112. data/lib/mail/multibyte/exceptions.rb +0 -9
@@ -1,20 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
  require 'mail/utilities'
3
+ require 'mail/parser_tools'
3
4
 
4
5
  %%{
5
6
  machine date_time;
7
+ alphtype int;
6
8
 
7
9
  # Received Tokens
8
10
  action received_tokens_s { received_tokens_s = p }
9
- action received_tokens_e { received.info = data[received_tokens_s..(p-1)] }
11
+ action received_tokens_e { received.info = chars(data, received_tokens_s, p-1) }
10
12
 
11
13
  # Date
12
14
  action date_s { date_s = p }
13
- action date_e { received.date = data[date_s..(p-1)].strip }
15
+ action date_e { received.date = chars(data, date_s, p-1).strip }
14
16
 
15
17
  # Time
16
18
  action time_s { time_s = p }
17
- action time_e { received.time = data[time_s..(p-1)] }
19
+ action time_e { received.time = chars(data, time_s, p-1) }
18
20
 
19
21
  # No-op actions
20
22
  action address_s {}
@@ -49,12 +51,16 @@ require 'mail/utilities'
49
51
 
50
52
  module Mail::Parsers
51
53
  module ReceivedParser
54
+ extend Mail::ParserTools
55
+
52
56
  ReceivedStruct = Struct.new(:date, :time, :info, :error)
53
57
 
54
58
  %%write data noprefix;
55
59
 
56
60
  def self.parse(data)
57
- raise Mail::Field::ParseError.new(Mail::ReceivedElement, data, 'nil is invalid') if data.nil?
61
+ data = data.dup.force_encoding(Encoding::ASCII_8BIT) if data.respond_to?(:force_encoding)
62
+
63
+ raise Mail::Field::NilParseError.new(Mail::ReceivedElement) if data.nil?
58
64
 
59
65
  # Parser state
60
66
  received = ReceivedStruct.new
@@ -69,7 +75,7 @@ module Mail::Parsers
69
75
  %%write exec;
70
76
 
71
77
  if p != eof || cs < %%{ write first_final; }%%
72
- raise Mail::Field::ParseError.new(Mail::ReceivedElement, data, "Only able to parse up to #{data[0..p]}")
78
+ raise Mail::Field::IncompleteParseError.new(Mail::ReceivedElement, data, p)
73
79
  end
74
80
 
75
81
  received
@@ -2,6 +2,7 @@
2
2
  # RFC 2045 Section 6.1: Content-Transfer-Encoding Header Field
3
3
  # https://tools.ietf.org/html/rfc2045#section-6.1
4
4
  machine rfc2045_content_transfer_encoding;
5
+ alphtype int;
5
6
 
6
7
  include rfc2045_content_type "rfc2045_content_type.rl";
7
8
 
@@ -3,6 +3,7 @@
3
3
  # https://tools.ietf.org/html/rfc2045#section-5.1
4
4
  # Previously: https://tools.ietf.org/html/rfc1049#section-3
5
5
  machine rfc2045_content_type;
6
+ alphtype int;
6
7
 
7
8
  include rfc5322_lexical_tokens "rfc5322_lexical_tokens.rl";
8
9
 
@@ -2,6 +2,7 @@
2
2
  # RFC 2045 MIME
3
3
  # https://tools.ietf.org/html/rfc2045
4
4
  machine rfc2045_mime;
5
+ alphtype int;
5
6
 
6
7
  include rfc5322_lexical_tokens "rfc5322_lexical_tokens.rl";
7
8
 
@@ -4,6 +4,7 @@
4
4
  #
5
5
  # TODO: recognize filename, size, creation date, etc.
6
6
  machine rfc2183_content_disposition;
7
+ alphtype int;
7
8
 
8
9
  include rfc2045_content_type "rfc2045_content_type.rl";
9
10
 
@@ -0,0 +1,19 @@
1
+ %%{
2
+ # RFC 3629 4. Syntax of UTF-8 Byte Sequences
3
+ # https://tools.ietf.org/html/rfc3629#section-4
4
+ machine rfc3629_utf8;
5
+ alphtype int;
6
+
7
+ utf8_tail = 0x80..0xBF;
8
+
9
+ utf8_2byte = 0xC2..0xDF utf8_tail;
10
+ utf8_3byte = 0xE0 0xA0..0xBF utf8_tail |
11
+ 0xE1..0xEC utf8_tail utf8_tail |
12
+ 0xED 0x80..0x9F utf8_tail |
13
+ 0xEE..0xEF utf8_tail utf8_tail;
14
+ utf8_4byte = 0xF0 0x90..0xBF utf8_tail utf8_tail |
15
+ 0xF1..0xF3 utf8_tail utf8_tail utf8_tail |
16
+ 0xF4 0x80..0x8F utf8_tail utf8_tail;
17
+
18
+ utf8_non_ascii = utf8_2byte | utf8_3byte | utf8_4byte;
19
+ }%%
@@ -2,6 +2,9 @@
2
2
  # RFC 5234 B.1. Core Rules
3
3
  # https://tools.ietf.org/html/rfc5234#appendix-B.1
4
4
  machine rfc5234_abnf_core_rules;
5
+ alphtype int;
6
+
7
+ include rfc3629_utf8 "rfc3629_utf8.rl";
5
8
 
6
9
  LF = "\n";
7
10
  CR = "\r";
@@ -12,5 +15,8 @@
12
15
  DQUOTE = '"';
13
16
  DIGIT = [0-9];
14
17
  ALPHA = [a-zA-Z];
15
- VCHAR = 0x21..0x7e;
18
+
19
+ # RFC6532 extension for UTF-8 content
20
+ rfc5234_VCHAR = 0x21..0x7e;
21
+ VCHAR = rfc5234_VCHAR | utf8_non_ascii;
16
22
  }%%
@@ -5,6 +5,7 @@
5
5
  # RFC 6854 Update to Internet Message Format to Allow Group Syntax in the "From:" and "Sender:" Header Fields
6
6
  # https://tools.ietf.org/html/rfc6854
7
7
  machine rfc5322;
8
+ alphtype int;
8
9
 
9
10
  include rfc5234_abnf_core_rules "rfc5234_abnf_core_rules.rl";
10
11
 
@@ -18,7 +19,8 @@
18
19
  include rfc5322_address "rfc5322_address.rl";
19
20
 
20
21
  # 3.5. Overall Message Syntax
21
- #text = 0x01..0x09 | "\v" | "\f" | 0x0e..0x1f;
22
+ #rfc5322_text = 0x01..0x09 | "\v" | "\f" | 0x0e..0x1f;
23
+ #text = rfc5322_text | utf8_non_ascii; # RFC6532 for UTF-8
22
24
  #obs_body = ((LF* CR* ((0x00 | text) LF* CR*)*) | CRLF)*
23
25
  #body = ((text{,998} CRLF)* text{,998}) | obs_body;
24
26
  #message = (fields | obs_fields) (CRLF body)?;
@@ -3,6 +3,7 @@
3
3
  # Section 3.4. Address Specification
4
4
  # https://tools.ietf.org/html/rfc5322#section-3.4
5
5
  machine rfc5322_address;
6
+ alphtype int;
6
7
 
7
8
  include rfc5234_abnf_core_rules "rfc5234_abnf_core_rules.rl";
8
9
  include rfc5322_lexical_tokens "rfc5322_lexical_tokens.rl";
@@ -25,7 +26,8 @@
25
26
  # domain:
26
27
  domain_dot_atom_text = "."* domain_text ("."* domain_text)*;
27
28
  obs_dtext = obs_NO_WS_CTL | quoted_pair;
28
- dtext = 0x21..0x5a | 0x5e..0x7e | obs_dtext;
29
+ rfc5322_dtext = 0x21..0x5a | 0x5e..0x7e | obs_dtext;
30
+ dtext = rfc5322_dtext | utf8_non_ascii; # RFC6532 for UTF-8
29
31
  domain_dot_atom = CFWS? domain_dot_atom_text (CFWS? >(comment_after_address,1));
30
32
  domain_literal = CFWS? "[" (FWS? dtext)* FWS? "]" CFWS?;
31
33
  obs_domain = atom ("." atom)*;
@@ -3,6 +3,7 @@
3
3
  # Section 3.3. Date and Time Specification
4
4
  # https://tools.ietf.org/html/rfc5322#section-3.3
5
5
  machine rfc5322_date_time;
6
+ alphtype int;
6
7
 
7
8
  include rfc5322_lexical_tokens "rfc5322_lexical_tokens.rl";
8
9
 
@@ -3,6 +3,7 @@
3
3
  # Section 3.2. Lexical Tokens
4
4
  # https://tools.ietf.org/html/rfc5322#section-3.2
5
5
  machine rfc5322_lexical_tokens;
6
+ alphtype int;
6
7
 
7
8
  include rfc5234_abnf_core_rules "rfc5234_abnf_core_rules.rl";
8
9
 
@@ -16,7 +17,8 @@
16
17
  FWS = (WSP* CRLF WSP+) | (CRLF WSP+) | obs_FWS;
17
18
 
18
19
  obs_ctext = obs_NO_WS_CTL;
19
- ctext = 0x21..0x27 | 0x2a..0x5b | 0x5d..0x7e | obs_ctext;
20
+ rfc5322_ctext = 0x21..0x27 | 0x2a..0x5b | 0x5d..0x7e | obs_ctext;
21
+ ctext = rfc5322_ctext | utf8_non_ascii; # RFC6532 for UTF-8
20
22
 
21
23
  # Recursive comments
22
24
  action comment_begin { fcall comment_tail; }
@@ -27,16 +29,18 @@
27
29
  CFWS = ((FWS? comment)+ FWS?) | FWS;
28
30
 
29
31
  # 3.2.3. Atom
30
- atext = ALPHA | DIGIT | "!" | "#" | "$" | "%" | "&" |
31
- "'" | "*" | "+" | "-" | "/" | "=" | "?" | "^" |
32
- "_" | "`" | "{" | "|" | "}" | "~";
32
+ rfc5322_atext = ALPHA | DIGIT | "!" | "#" | "$" | "%" | "&" |
33
+ "'" | "*" | "+" | "-" | "/" | "=" | "?" | "^" |
34
+ "_" | "`" | "{" | "|" | "}" | "~";
35
+ atext = rfc5322_atext | utf8_non_ascii; # RFC6532 for UTF-8
33
36
  atom = CFWS? atext+ CFWS?;
34
37
  dot_atom_text = atext ("." atext)*;
35
38
  dot_atom = CFWS? dot_atom_text CFWS?;
36
39
 
37
40
  # 3.2.4. Quoted Strings
38
41
  obs_qtext = obs_NO_WS_CTL;
39
- qtext = 0x21 | 0x23..0x5b | 0x5d..0x7e | obs_qtext;
42
+ rfc5322_qtext = 0x21 | 0x23..0x5b | 0x5d..0x7e | obs_qtext;
43
+ qtext = rfc5322_qtext | utf8_non_ascii; # RFC6532 for UTF-8
40
44
 
41
45
  qcontent = qtext | quoted_pair;
42
46
  quoted_string = CFWS?
@@ -21,7 +21,7 @@ module Mail
21
21
 
22
22
  def inline_content_id
23
23
  # TODO: Deprecated in 2.2.2 - Remove in 2.3
24
- $stderr.puts("Part#inline_content_id is deprecated, please call Part#cid instead")
24
+ warn("Part#inline_content_id is deprecated, please call Part#cid instead")
25
25
  cid
26
26
  end
27
27
 
@@ -248,33 +248,62 @@ module Mail
248
248
  (LF.encode(:crlf_newline => true) rescue nil) == CRLF
249
249
  # Using String#encode is better performing than Regexp
250
250
 
251
- def self.to_lf(input)
252
- input.kind_of?(String) ? input.to_str.encode(input.encoding, :universal_newline => true) : ''
251
+ def self.binary_unsafe_to_lf(string) #:nodoc:
252
+ string.encode(string.encoding, :universal_newline => true)
253
253
  end
254
254
 
255
- def self.to_crlf(input)
256
- input.kind_of?(String) ? input.to_str.encode(input.encoding, :universal_newline => true).encode!(input.encoding, :crlf_newline => true) : ''
255
+ def self.binary_unsafe_to_crlf(string) #:nodoc:
256
+ string.encode(string.encoding, :universal_newline => true).encode!(string.encoding, :crlf_newline => true)
257
257
  end
258
258
 
259
+ def self.safe_for_line_ending_conversion?(string) #:nodoc:
260
+ string.ascii_only?
261
+ end
259
262
  else
263
+ def self.binary_unsafe_to_lf(string) #:nodoc:
264
+ string.gsub(/\r\n|\r/, LF)
265
+ end
266
+
267
+ TO_CRLF_REGEX =
268
+ if RUBY_VERSION >= '1.9'
269
+ # This 1.9 only regex can save a reasonable amount of time (~20%)
270
+ # by not matching "\r\n" so the string is returned unchanged in
271
+ # the common case.
272
+ Regexp.new("(?<!\r)\n|\r(?!\n)")
273
+ else
274
+ /\n|\r\n|\r/
275
+ end
260
276
 
261
- def self.to_lf(input)
262
- input.kind_of?(String) ? input.to_str.gsub(/\r\n|\r/, LF) : ''
277
+ def self.binary_unsafe_to_crlf(string) #:nodoc:
278
+ string.gsub(TO_CRLF_REGEX, CRLF)
263
279
  end
264
280
 
265
- if RUBY_VERSION >= '1.9'
266
- # This 1.9 only regex can save a reasonable amount of time (~20%)
267
- # by not matching "\r\n" so the string is returned unchanged in
268
- # the common case.
269
- CRLF_REGEX = Regexp.new("(?<!\r)\n|\r(?!\n)")
270
- else
271
- CRLF_REGEX = /\n|\r\n|\r/
281
+ def self.safe_for_line_ending_conversion?(string) #:nodoc:
282
+ string.ascii_only?
272
283
  end
284
+ end
273
285
 
274
- def self.to_crlf(input)
275
- input.kind_of?(String) ? input.to_str.gsub(CRLF_REGEX, CRLF) : ''
286
+ # Convert line endings to \n unless the string is binary. Used for
287
+ # sendmail delivery and for decoding 8bit Content-Transfer-Encoding.
288
+ def self.to_lf(string)
289
+ string = string.to_s
290
+ if safe_for_line_ending_conversion? string
291
+ binary_unsafe_to_lf string
292
+ else
293
+ string
276
294
  end
295
+ end
277
296
 
297
+ # Convert line endings to \r\n unless the string is binary. Used for
298
+ # encoding 8bit and base64 Content-Transfer-Encoding and for convenience
299
+ # when parsing emails with \n line endings instead of the required \r\n.
300
+ def self.to_crlf(string)
301
+ string = string.to_s
302
+ if safe_for_line_ending_conversion? string
303
+ binary_unsafe_to_crlf string
304
+ else
305
+ string
306
+ end
278
307
  end
279
308
 
280
309
  # Returns true if the object is considered blank.
@@ -5,7 +5,7 @@ module Mail
5
5
  MAJOR = 2
6
6
  MINOR = 7
7
7
  PATCH = 0
8
- BUILD = 'rc1'
8
+ BUILD = 'rc2'
9
9
 
10
10
  STRING = [MAJOR, MINOR, PATCH, BUILD].compact.join('.')
11
11
 
@@ -132,6 +132,10 @@ module Mail
132
132
  "#{encoding}'#{language}'#{URI.escape(str)}"
133
133
  end
134
134
 
135
+ def Ruby18.string_byteslice(str, *args)
136
+ str.slice(*args)
137
+ end
138
+
135
139
  private
136
140
 
137
141
  def Ruby18.normalize_iconv_charset_encoding(encoding)
@@ -145,7 +149,14 @@ module Mail
145
149
  when 'KS_C_5601-1987'
146
150
  'CP949'
147
151
  else
148
- encoding
152
+ # Fall back to ASCII for charsets that Iconv doesn't recognize
153
+ begin
154
+ Iconv.new('UTF-8', encoding)
155
+ rescue Iconv::InvalidEncoding => e
156
+ 'ASCII'
157
+ else
158
+ encoding
159
+ end
149
160
  end
150
161
  end
151
162
  end
@@ -42,7 +42,7 @@ module Mail
42
42
  class << self
43
43
  attr_accessor :charset_encoder
44
44
  end
45
- self.charset_encoder = StrictCharsetEncoder.new
45
+ self.charset_encoder = BestEffortCharsetEncoder.new
46
46
 
47
47
  # Escapes any parenthesis in a string that are unescaped this uses
48
48
  # a Ruby 1.9.1 regexp feature of negative look behind
@@ -88,6 +88,7 @@ module Mail
88
88
  end
89
89
 
90
90
  def Ruby19.transcode_charset(str, from_encoding, to_encoding = Encoding::UTF_8)
91
+ to_encoding = to_encoding.to_s if RUBY_VERSION < '1.9.3'
91
92
  to_encoding = Encoding.find(to_encoding)
92
93
  replacement_char = to_encoding == Encoding::UTF_8 ? '�' : '?'
93
94
  charset_encoder.encode(str.dup, from_encoding).encode(to_encoding, :undef => :replace, :invalid => :replace, :replace => replacement_char)
@@ -242,6 +243,16 @@ module Mail
242
243
  convert_to_encoding(encoding)
243
244
  end
244
245
 
246
+ if "string".respond_to?(:byteslice)
247
+ def Ruby19.string_byteslice(str, *args)
248
+ str.byteslice(*args)
249
+ end
250
+ else
251
+ def Ruby19.string_byteslice(str, *args)
252
+ str.unpack('C*').slice(*args).pack('C*').force_encoding(str.encoding)
253
+ end
254
+ end
255
+
245
256
  class << self
246
257
  private
247
258
 
@@ -249,6 +260,7 @@ module Mail
249
260
  if encoding.is_a?(Encoding)
250
261
  encoding
251
262
  else
263
+ # Fall back to ASCII for charsets that Ruby doesn't recognize
252
264
  begin
253
265
  Encoding.find(encoding)
254
266
  rescue ArgumentError
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mail
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.7.0.rc1
4
+ version: 2.7.0.rc2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mikel Lindsaar
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-05-09 00:00:00.000000000 Z
11
+ date: 2017-10-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mini_mime
@@ -86,18 +86,9 @@ executables: []
86
86
  extensions: []
87
87
  extra_rdoc_files:
88
88
  - README.md
89
- - CONTRIBUTING.md
90
- - CHANGELOG.rdoc
91
- - TODO.rdoc
92
89
  files:
93
- - CHANGELOG.rdoc
94
- - CONTRIBUTING.md
95
- - Dependencies.txt
96
- - Gemfile
97
90
  - MIT-LICENSE
98
91
  - README.md
99
- - Rakefile
100
- - TODO.rdoc
101
92
  - lib/mail.rb
102
93
  - lib/mail/attachments_list.rb
103
94
  - lib/mail/body.rb
@@ -124,6 +115,7 @@ files:
124
115
  - lib/mail/encodings/8bit.rb
125
116
  - lib/mail/encodings/base64.rb
126
117
  - lib/mail/encodings/binary.rb
118
+ - lib/mail/encodings/identity.rb
127
119
  - lib/mail/encodings/quoted_printable.rb
128
120
  - lib/mail/encodings/transfer_encoding.rb
129
121
  - lib/mail/encodings/unix_to_unix.rb
@@ -177,12 +169,12 @@ files:
177
169
  - lib/mail/message.rb
178
170
  - lib/mail/multibyte.rb
179
171
  - lib/mail/multibyte/chars.rb
180
- - lib/mail/multibyte/exceptions.rb
181
172
  - lib/mail/multibyte/unicode.rb
182
173
  - lib/mail/multibyte/utils.rb
183
174
  - lib/mail/network.rb
184
175
  - lib/mail/network/delivery_methods/exim.rb
185
176
  - lib/mail/network/delivery_methods/file_delivery.rb
177
+ - lib/mail/network/delivery_methods/logger_delivery.rb
186
178
  - lib/mail/network/delivery_methods/sendmail.rb
187
179
  - lib/mail/network/delivery_methods/smtp.rb
188
180
  - lib/mail/network/delivery_methods/smtp_connection.rb
@@ -191,6 +183,7 @@ files:
191
183
  - lib/mail/network/retriever_methods/imap.rb
192
184
  - lib/mail/network/retriever_methods/pop3.rb
193
185
  - lib/mail/network/retriever_methods/test_retriever.rb
186
+ - lib/mail/parser_tools.rb
194
187
  - lib/mail/parsers.rb
195
188
  - lib/mail/parsers/address_lists_parser.rb
196
189
  - lib/mail/parsers/address_lists_parser.rl
@@ -218,6 +211,7 @@ files:
218
211
  - lib/mail/parsers/rfc2045_content_type.rl
219
212
  - lib/mail/parsers/rfc2045_mime.rl
220
213
  - lib/mail/parsers/rfc2183_content_disposition.rl
214
+ - lib/mail/parsers/rfc3629_utf8.rl
221
215
  - lib/mail/parsers/rfc5234_abnf_core_rules.rl
222
216
  - lib/mail/parsers/rfc5322.rl
223
217
  - lib/mail/parsers/rfc5322_address.rl
@@ -252,7 +246,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
252
246
  version: 1.3.1
253
247
  requirements: []
254
248
  rubyforge_project:
255
- rubygems_version: 2.6.12
249
+ rubygems_version: 2.6.11
256
250
  signing_key:
257
251
  specification_version: 4
258
252
  summary: Mail provides a nice Ruby DSL for making, sending and reading emails.