mail 2.7.0.rc1 → 2.7.0.rc2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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.