mail 2.7.1 → 2.8.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (122) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +59 -28
  3. data/lib/mail/attachments_list.rb +2 -5
  4. data/lib/mail/body.rb +24 -47
  5. data/lib/mail/check_delivery_params.rb +21 -16
  6. data/lib/mail/constants.rb +27 -5
  7. data/lib/mail/elements/address.rb +27 -27
  8. data/lib/mail/elements/address_list.rb +1 -1
  9. data/lib/mail/elements/content_disposition_element.rb +1 -1
  10. data/lib/mail/elements/content_location_element.rb +1 -1
  11. data/lib/mail/elements/content_transfer_encoding_element.rb +1 -1
  12. data/lib/mail/elements/content_type_element.rb +8 -4
  13. data/lib/mail/elements/date_time_element.rb +1 -1
  14. data/lib/mail/elements/envelope_from_element.rb +13 -7
  15. data/lib/mail/elements/message_ids_element.rb +14 -5
  16. data/lib/mail/elements/mime_version_element.rb +1 -1
  17. data/lib/mail/elements/phrase_list.rb +7 -2
  18. data/lib/mail/elements/received_element.rb +20 -6
  19. data/lib/mail/encodings/7bit.rb +5 -0
  20. data/lib/mail/encodings/base64.rb +2 -2
  21. data/lib/mail/encodings/quoted_printable.rb +2 -2
  22. data/lib/mail/encodings.rb +30 -59
  23. data/lib/mail/envelope.rb +11 -14
  24. data/lib/mail/field.rb +37 -53
  25. data/lib/mail/field_list.rb +60 -7
  26. data/lib/mail/fields/bcc_field.rb +34 -52
  27. data/lib/mail/fields/cc_field.rb +28 -49
  28. data/lib/mail/fields/comments_field.rb +27 -37
  29. data/lib/mail/fields/common_address_field.rb +170 -0
  30. data/lib/mail/fields/common_date_field.rb +58 -0
  31. data/lib/mail/fields/common_field.rb +77 -0
  32. data/lib/mail/fields/common_message_id_field.rb +42 -0
  33. data/lib/mail/fields/content_description_field.rb +7 -14
  34. data/lib/mail/fields/content_disposition_field.rb +13 -38
  35. data/lib/mail/fields/content_id_field.rb +24 -51
  36. data/lib/mail/fields/content_location_field.rb +11 -25
  37. data/lib/mail/fields/content_transfer_encoding_field.rb +31 -31
  38. data/lib/mail/fields/content_type_field.rb +46 -71
  39. data/lib/mail/fields/date_field.rb +23 -51
  40. data/lib/mail/fields/from_field.rb +28 -49
  41. data/lib/mail/fields/in_reply_to_field.rb +38 -49
  42. data/lib/mail/fields/keywords_field.rb +18 -31
  43. data/lib/mail/fields/message_id_field.rb +25 -71
  44. data/lib/mail/fields/mime_version_field.rb +19 -30
  45. data/lib/mail/fields/named_structured_field.rb +11 -0
  46. data/lib/mail/fields/named_unstructured_field.rb +11 -0
  47. data/lib/mail/fields/optional_field.rb +5 -6
  48. data/lib/mail/fields/{common/parameter_hash.rb → parameter_hash.rb} +12 -10
  49. data/lib/mail/fields/received_field.rb +43 -57
  50. data/lib/mail/fields/references_field.rb +35 -49
  51. data/lib/mail/fields/reply_to_field.rb +28 -49
  52. data/lib/mail/fields/resent_bcc_field.rb +28 -49
  53. data/lib/mail/fields/resent_cc_field.rb +28 -49
  54. data/lib/mail/fields/resent_date_field.rb +5 -29
  55. data/lib/mail/fields/resent_from_field.rb +28 -49
  56. data/lib/mail/fields/resent_message_id_field.rb +5 -29
  57. data/lib/mail/fields/resent_sender_field.rb +27 -56
  58. data/lib/mail/fields/resent_to_field.rb +28 -49
  59. data/lib/mail/fields/return_path_field.rb +50 -54
  60. data/lib/mail/fields/sender_field.rb +34 -55
  61. data/lib/mail/fields/structured_field.rb +3 -30
  62. data/lib/mail/fields/subject_field.rb +9 -11
  63. data/lib/mail/fields/to_field.rb +28 -49
  64. data/lib/mail/fields/unstructured_field.rb +16 -48
  65. data/lib/mail/header.rb +69 -110
  66. data/lib/mail/matchers/attachment_matchers.rb +15 -0
  67. data/lib/mail/message.rb +52 -66
  68. data/lib/mail/multibyte/chars.rb +8 -166
  69. data/lib/mail/multibyte/utils.rb +26 -43
  70. data/lib/mail/multibyte.rb +1 -11
  71. data/lib/mail/network/delivery_methods/exim.rb +5 -4
  72. data/lib/mail/network/delivery_methods/file_delivery.rb +11 -10
  73. data/lib/mail/network/delivery_methods/logger_delivery.rb +2 -5
  74. data/lib/mail/network/delivery_methods/sendmail.rb +56 -18
  75. data/lib/mail/network/delivery_methods/smtp.rb +25 -9
  76. data/lib/mail/network/delivery_methods/smtp_connection.rb +3 -12
  77. data/lib/mail/network/delivery_methods/test_mailer.rb +4 -2
  78. data/lib/mail/network/retriever_methods/base.rb +8 -8
  79. data/lib/mail/network/retriever_methods/imap.rb +2 -2
  80. data/lib/mail/network/retriever_methods/pop3.rb +2 -2
  81. data/lib/mail/network/retriever_methods/test_retriever.rb +2 -1
  82. data/lib/mail/parsers/address_lists_parser.rb +33070 -33064
  83. data/lib/mail/parsers/address_lists_parser.rl +7 -0
  84. data/lib/mail/parsers/content_disposition_parser.rb +833 -827
  85. data/lib/mail/parsers/content_disposition_parser.rl +7 -0
  86. data/lib/mail/parsers/content_location_parser.rb +770 -764
  87. data/lib/mail/parsers/content_location_parser.rl +7 -0
  88. data/lib/mail/parsers/content_transfer_encoding_parser.rb +474 -468
  89. data/lib/mail/parsers/content_transfer_encoding_parser.rl +7 -0
  90. data/lib/mail/parsers/content_type_parser.rb +971 -965
  91. data/lib/mail/parsers/content_type_parser.rl +7 -0
  92. data/lib/mail/parsers/date_time_parser.rb +838 -832
  93. data/lib/mail/parsers/date_time_parser.rl +7 -0
  94. data/lib/mail/parsers/envelope_from_parser.rb +3623 -3529
  95. data/lib/mail/parsers/envelope_from_parser.rl +7 -0
  96. data/lib/mail/parsers/message_ids_parser.rb +5107 -2800
  97. data/lib/mail/parsers/message_ids_parser.rl +12 -1
  98. data/lib/mail/parsers/mime_version_parser.rb +463 -457
  99. data/lib/mail/parsers/mime_version_parser.rl +7 -0
  100. data/lib/mail/parsers/phrase_lists_parser.rb +836 -830
  101. data/lib/mail/parsers/phrase_lists_parser.rl +8 -1
  102. data/lib/mail/parsers/received_parser.rb +8688 -8682
  103. data/lib/mail/parsers/received_parser.rl +7 -0
  104. data/lib/mail/parsers/rfc5322.rl +28 -13
  105. data/lib/mail/parsers.rb +11 -17
  106. data/lib/mail/part.rb +5 -9
  107. data/lib/mail/parts_list.rb +57 -0
  108. data/lib/mail/smtp_envelope.rb +57 -0
  109. data/lib/mail/utilities.rb +307 -69
  110. data/lib/mail/version.rb +1 -1
  111. data/lib/mail/yaml.rb +30 -0
  112. data/lib/mail.rb +3 -20
  113. metadata +72 -18
  114. data/lib/mail/core_extensions/smtp.rb +0 -28
  115. data/lib/mail/core_extensions/string.rb +0 -17
  116. data/lib/mail/fields/common/address_container.rb +0 -17
  117. data/lib/mail/fields/common/common_address.rb +0 -161
  118. data/lib/mail/fields/common/common_date.rb +0 -36
  119. data/lib/mail/fields/common/common_field.rb +0 -52
  120. data/lib/mail/fields/common/common_message_id.rb +0 -49
  121. data/lib/mail/version_specific/ruby_1_8.rb +0 -163
  122. data/lib/mail/version_specific/ruby_1_9.rb +0 -278
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2e806bc9b7c6c6df8de9c9dc80b4cf3a099bad3153f568d0ee4d9287cd34a014
4
- data.tar.gz: 182ed03957858cce70691eb79543f13d53e4ddf43684bf50bc011e904d3a84ae
3
+ metadata.gz: ea4015fe2858f6c1b123e04d4d407169567b1aeea1155b7b145fe75d9d3781b5
4
+ data.tar.gz: 20cdb386c2f878560b9f61ab63b4f0c264c9f9115af5c835b8c66f49486cb274
5
5
  SHA512:
6
- metadata.gz: 3c42702e6529565ae63c486fef492b89a19eb394fb6fe5aaf004862257ef3d840579a3cabb95dd2075ddbc617e077110684d8f47052e51d0435b94ef4a2373c3
7
- data.tar.gz: 31278e7d48271cfec8541d1094fedd1cc62578a6d9f18e0eafd09ebcac4e5edf3e78a3b902aca3e97d7416d37b0f0c07ba2dde2f5462d6317058552bbc0dbfe7
6
+ metadata.gz: b2eb55bc6f51b2d93e6d6abed5bb74876b3f96fd1eea00105047b3a211007b2b906ac89bcd1bed52603c211c595d439b6642bd897943decbcc9ac541f88e2049
7
+ data.tar.gz: 063dd68ef655b93d96412bdcf66ab6f191eaf0bfbafa10730ecfa99a447eb3d2a4469d6d1de67ae144bbaada65eaec4c7d8dbb5fe04509146dc1434a5c557fff
data/README.md CHANGED
@@ -1,39 +1,35 @@
1
- # Mail [![Build Status](https://travis-ci.org/mikel/mail.png?branch=master)](https://travis-ci.org/mikel/mail)
1
+ # Mail [![Build Status](https://github.com/mikel/mail/actions/workflows/test.yml/badge.svg)](https://github.com/mikel/mail/actions/workflows/test.yml)
2
2
 
3
3
  ## Introduction
4
4
 
5
- Mail is an internet library for Ruby that is designed to handle emails
5
+ Mail is an internet library for Ruby that is designed to handle email
6
6
  generation, parsing and sending in a simple, rubyesque manner.
7
7
 
8
8
  The purpose of this library is to provide a single point of access to handle
9
- all email functions, including sending and receiving emails. All network
9
+ all email functions, including sending and receiving email. All network
10
10
  type actions are done through proxy methods to Net::SMTP, Net::POP3 etc.
11
11
 
12
12
  Built from my experience with TMail, it is designed to be a pure ruby
13
- implementation that makes generating, sending and parsing emails a no
13
+ implementation that makes generating, sending and parsing email a no
14
14
  brainer.
15
15
 
16
16
  It is also designed from the ground up to work with the more modern versions
17
- of Ruby. This is because Ruby > 1.9 handles text encodings much more wonderfully
18
- than Ruby 1.8.x and so these features have been taken full advantage of in this
19
- library allowing Mail to handle a lot more messages more cleanly than TMail.
20
- Mail does run on Ruby 1.8.x... it's just not as fun to code.
17
+ of Ruby. Modern Rubies handle text encodings much more wonderfully than before
18
+ so these features have been taken full advantage of in this library allowing
19
+ Mail to handle a lot more messages more cleanly than TMail.
21
20
 
22
21
  Finally, Mail has been designed with a very simple object oriented system
23
22
  that really opens up the email messages you are parsing, if you know what
24
23
  you are doing, you can fiddle with every last bit of your email directly.
25
24
 
26
- ## Donations
25
+ ## You can contribute to this library
27
26
 
28
- Mail has been downloaded millions of times, by people around the world, in fact,
29
- it represents more than 1% of *all* gems downloaded.
27
+ Yes, you! Mail is used in countless apps by people around the world. It is,
28
+ like all open source software, a labour of love borne from our free time.
29
+ If you would like to say thanks, please dig in and contribute alongside us!
30
+ Triage and fix [GitHub issues](https://github.com/mikel/mail/issues), improve
31
+ our documentation, add new features—up to you! Thank you for pitching in.
30
32
 
31
- It is (like all open source software) a labour of love and something I am doing
32
- with my own free time. If you would like to say thanks, please feel free to
33
- [make a donation](http://www.pledgie.com/campaigns/8790) and feel free to send
34
- me a nice email :)
35
-
36
- <a href='http://www.pledgie.com/campaigns/8790'><img alt='Click here to lend your support to: mail and make a donation at www.pledgie.com !' src='http://www.pledgie.com/campaigns/8790.png?skin_name=chrome' border='0' /></a>
37
33
 
38
34
  # Contents
39
35
  * [Compatibility](#compatibility)
@@ -46,15 +42,30 @@ me a nice email :)
46
42
  * [Encodings](#encodings)
47
43
  * [Contributing](#contributing)
48
44
  * [Usage](#usage)
49
- * [Core Extensions](#core-extensions)
50
45
  * [Excerpts from TREC Span Corpus 2005](#excerpts-from-trec-span-corpus-2005)
51
46
  * [License](#license)
52
47
 
53
48
  ## Compatibility
54
49
 
55
- Mail supports Ruby 1.8.7+, including JRuby and Rubinius.
50
+ Mail is tested against:
51
+
52
+ * Ruby: 2.5
53
+ * Ruby: 2.6
54
+ * Ruby: 2.7
55
+ * Ruby: 3.0
56
+ * Ruby: 3.1
57
+ * Ruby: 3.2
58
+ * JRuby: 9.2
59
+ * JRuby: 9.3
60
+ * JRuby: 9.4
61
+ * JRuby: stable
62
+ * JRuby: head
63
+ * Truffleruby: stable
64
+ * Truffleruby: head
56
65
 
57
- Every Mail commit is tested by Travis on [all supported Ruby versions](https://github.com/mikel/mail/blob/master/.travis.yml).
66
+ As new versions of Ruby are released, Mail will be compatible with support for the "preview" and all "normal maintenance", "security maintenance" and the two most recent "end of life" versions listed at the [Ruby Maintenance Branches](https://www.ruby-lang.org/en/downloads/branches/) page. Pull requests to assist in adding support for new preview releases are more than welcome.
67
+
68
+ Every Mail commit is tested by GitHub Actions on [all supported Ruby versions](https://github.com/mikel/mail/blob/master/.github/workflows/test.yml).
58
69
 
59
70
  ## Discussion
60
71
 
@@ -65,14 +76,14 @@ the [Google Group](http://groups.google.com/group/mail-ruby).
65
76
 
66
77
  * RFC5322 Support, Reading and Writing
67
78
  * RFC6532 Support, reading UTF-8 headers
68
- * RFC2045-2049 Support for multipart emails
69
- * Support for creating multipart alternate emails
70
- * Support for reading multipart/report emails &amp; getting details from such
79
+ * RFC2045-2049 Support for multipart email
80
+ * Support for creating multipart alternate email
81
+ * Support for reading multipart/report email &amp; getting details from such
71
82
  * Wrappers for File, Net/POP3, Net/SMTP
72
83
  * Auto-encoding of non-US-ASCII bodies and header fields
73
84
 
74
85
  Mail is RFC5322 and RFC6532 compliant now, that is, it can parse US-ASCII and UTF-8
75
- emails and generate US-ASCII emails. There are a few obsoleted syntax emails that
86
+ email and generate US-ASCII email. There are a few obsoleted email syntax that
76
87
  it will have problems with, but it also is quite robust, meaning, if it finds something
77
88
  it doesn't understand it will not crash, instead, it will skip the problem and keep
78
89
  parsing. In the case of a header it doesn't understand, it will initialise the header
@@ -101,7 +112,9 @@ the gem gets released.
101
112
 
102
113
  It also means you can be sure Mail will behave correctly.
103
114
 
104
- Note: If you care about core extensions (aka "monkey-patching"), please read the Core Extensions section near the end of this README.
115
+ You can run tests locally by running `bundle exec rspec`.
116
+
117
+ You can run tests on all supported Ruby versions by using [act](https://github.com/nektos/act).
105
118
 
106
119
  ## API Policy
107
120
 
@@ -150,13 +163,15 @@ I have tried to simplify it some:
150
163
 
151
164
  ## Contributing
152
165
 
153
- Please do! Contributing is easy in Mail. Please read the CONTRIBUTING.md document for more info
166
+ Please do! Contributing is easy in Mail. Please read the [CONTRIBUTING.md](CONTRIBUTING.md) document for more info.
154
167
 
155
168
  ## Usage
156
169
 
157
170
  All major mail functions should be able to happen from the Mail module.
158
171
  So, you should be able to just <code>require 'mail'</code> to get started.
159
172
 
173
+ `mail` is pretty well documented in its Ruby code. You can look it up e.g. at [rubydoc.info](https://www.rubydoc.info/gems/mail).
174
+
160
175
  ### Making an email
161
176
 
162
177
  ```ruby
@@ -290,12 +305,13 @@ mail.delivery_method :logger
290
305
  mail.delivery_method :logger, logger: other_logger, severity: :debug
291
306
  ```
292
307
 
293
- ### Getting Emails from a POP Server:
308
+ ### Getting Emails from a POP or IMAP Server:
294
309
 
295
310
  You can configure Mail to receive email using <code>retriever_method</code>
296
311
  within <code>Mail.defaults</code>:
297
312
 
298
313
  ```ruby
314
+ # e.g. POP3
299
315
  Mail.defaults do
300
316
  retriever_method :pop3, :address => "pop.gmail.com",
301
317
  :port => 995,
@@ -303,6 +319,15 @@ Mail.defaults do
303
319
  :password => '<password>',
304
320
  :enable_ssl => true
305
321
  end
322
+
323
+ # IMAP
324
+ Mail.defaults do
325
+ retriever_method :imap, :address => "imap.mailbox.org",
326
+ :port => 993,
327
+ :user_name => '<username>',
328
+ :password => '<password>',
329
+ :enable_ssl => true
330
+ end
306
331
  ```
307
332
 
308
333
  You can access incoming email in a number of ways.
@@ -445,7 +470,7 @@ Content-Transfer-Encoding: 7bit
445
470
  ```
446
471
 
447
472
  Mail inserts the content transfer encoding, the mime version,
448
- the content-id's and handles the content-type and boundary.
473
+ the content-IDs and handles the content-type and boundary.
449
474
 
450
475
  Mail assumes that if your text in the body is only us-ascii, that your
451
476
  transfer encoding is 7bit and it is text/plain. You can override this
@@ -639,6 +664,12 @@ describe "sending an email" do
639
664
  # ... or any attachment
640
665
  it { is_expected.to have_sent_email.with_attachments(any_attachment) }
641
666
 
667
+ # ... or attachment with filename
668
+ it { is_expected.to have_sent_email.with_attachments(an_attachment_with_filename('file.txt')) }
669
+
670
+ # ... or attachment with mime_type
671
+ it { is_expected.to have_sent_email.with_attachments(an_attachment_with_mime_type('application/pdf')) }
672
+
642
673
  # ... by array of attachments
643
674
  it { is_expected.to have_sent_email.with_attachments([my_attachment1, my_attachment2]) } #note that order is important
644
675
 
@@ -74,7 +74,7 @@ module Mail
74
74
  end
75
75
 
76
76
  if hash[:body].respond_to? :force_encoding and hash[:body].respond_to? :valid_encoding?
77
- if not hash[:body].valid_encoding? and default_values[:content_transfer_encoding].downcase == "binary"
77
+ if not hash[:body].valid_encoding? and default_values[:content_transfer_encoding].casecmp('binary').zero?
78
78
  hash[:body] = hash[:body].dup if hash[:body].frozen?
79
79
  hash[:body].force_encoding("BINARY")
80
80
  end
@@ -97,10 +97,7 @@ module Mail
97
97
  end
98
98
 
99
99
  def set_mime_type(filename)
100
- # Have to do this because MIME::Types is not Ruby 1.9 safe yet
101
- if RUBY_VERSION >= '1.9'
102
- filename = filename.encode(Encoding::UTF_8) if filename.respond_to?(:encode)
103
- end
100
+ filename = filename.encode(Encoding::UTF_8) if filename.respond_to?(:encode)
104
101
 
105
102
  @mime_type = MiniMime.lookup_by_filename(filename)
106
103
  @mime_type && @mime_type.content_type
data/lib/mail/body.rb CHANGED
@@ -50,6 +50,11 @@ module Mail
50
50
  set_charset
51
51
  end
52
52
 
53
+ def init_with(coder)
54
+ coder.map.each { |k, v| instance_variable_set(:"@#{k}", v) }
55
+ @parts = Mail::PartsList.new(coder['parts'])
56
+ end
57
+
53
58
  # Matches this body with another body. Also matches the decoded value of this
54
59
  # body with a string.
55
60
  #
@@ -133,12 +138,6 @@ module Mail
133
138
  @parts.sort!(@part_sort_order)
134
139
  end
135
140
 
136
- # Returns the raw source that the body was initialized with, without
137
- # any tampering
138
- def raw_source
139
- @raw_source
140
- end
141
-
142
141
  def negotiate_best_encoding(message_encoding, allowed_encodings = nil)
143
142
  Mail::Encodings::TransferEncoding.negotiate(message_encoding, encoding, raw_source, allowed_encodings)
144
143
  end
@@ -188,14 +187,6 @@ module Mail
188
187
  def to_s
189
188
  decoded
190
189
  end
191
-
192
- def charset
193
- @charset
194
- end
195
-
196
- def charset=( val )
197
- @charset = val
198
- end
199
190
 
200
191
  def encoding(val = nil)
201
192
  if val
@@ -214,45 +205,31 @@ module Mail
214
205
  end
215
206
  end
216
207
 
217
- # Returns the preamble (any text that is before the first MIME boundary)
218
- def preamble
219
- @preamble
220
- end
208
+ # Returns the raw source that the body was initialized with, without
209
+ # any tampering
210
+ attr_reader :raw_source
211
+
212
+ # Returns parts of the body
213
+ attr_reader :parts
214
+
215
+ # Returns and sets the original character encoding
216
+ attr_accessor :charset
217
+
218
+ # Returns and sets the preamble as a string (any text that is before the first MIME boundary)
219
+ attr_accessor :preamble
220
+
221
+ # Returns and sets the epilogue as a string (any text that is after the last MIME boundary)
222
+ attr_accessor :epilogue
223
+
224
+ # Returns and sets the boundary used by the body
225
+ # Allows you to change the boundary of this Body object
226
+ attr_accessor :boundary
221
227
 
222
- # Sets the preamble to a string (adds text before the first MIME boundary)
223
- def preamble=( val )
224
- @preamble = val
225
- end
226
-
227
- # Returns the epilogue (any text that is after the last MIME boundary)
228
- def epilogue
229
- @epilogue
230
- end
231
-
232
- # Sets the epilogue to a string (adds text after the last MIME boundary)
233
- def epilogue=( val )
234
- @epilogue = val
235
- end
236
-
237
228
  # Returns true if there are parts defined in the body
238
229
  def multipart?
239
230
  true unless parts.empty?
240
231
  end
241
-
242
- # Returns the boundary used by the body
243
- def boundary
244
- @boundary
245
- end
246
-
247
- # Allows you to change the boundary of this Body object
248
- def boundary=( val )
249
- @boundary = val
250
- end
251
232
 
252
- def parts
253
- @parts
254
- end
255
-
256
233
  def <<( val )
257
234
  if @parts
258
235
  @parts << val
@@ -1,36 +1,39 @@
1
1
  # frozen_string_literal: true
2
+ #
3
+ # This whole class and associated specs is deprecated and will go away in the version 3 release of mail.
2
4
  module Mail
3
5
  module CheckDeliveryParams #:nodoc:
4
6
  class << self
7
+
8
+ extend Gem::Deprecate
9
+
5
10
  def check(mail)
6
- [ check_from(mail.smtp_envelope_from),
7
- check_to(mail.smtp_envelope_to),
8
- check_message(mail) ]
11
+ envelope = Mail::SmtpEnvelope.new(mail)
12
+ [ envelope.from,
13
+ envelope.to,
14
+ envelope.message ]
9
15
  end
16
+ deprecate :check, 'Mail::SmtpEnvelope.new created in commit c106bebea066782a72e4f24dd37b532d95773df7', 2023, 6
10
17
 
11
18
  def check_from(addr)
12
- if Utilities.blank?(addr)
13
- raise ArgumentError, "SMTP From address may not be blank: #{addr.inspect}"
14
- end
15
-
16
- check_addr 'From', addr
19
+ mail = Mail.new(from: 'deprecated@example.com', to: 'deprecated@example.com')
20
+ Mail::SmtpEnvelope.new(mail).send(:validate_addr, 'From', addr)
17
21
  end
22
+ deprecate :check_from, :none, 2023, 6
18
23
 
19
24
  def check_to(addrs)
20
- if Utilities.blank?(addrs)
21
- raise ArgumentError, "SMTP To address may not be blank: #{addrs.inspect}"
22
- end
23
-
25
+ mail = Mail.new(from: 'deprecated@example.com', to: 'deprecated@example.com')
24
26
  Array(addrs).map do |addr|
25
- check_addr 'To', addr
27
+ Mail::SmtpEnvelope.new(mail).send(:validate_addr, 'To', addr)
26
28
  end
27
29
  end
30
+ deprecate :check_to, :none, 2023, 6
28
31
 
29
32
  def check_addr(addr_name, addr)
30
- validate_smtp_addr addr do |error_message|
31
- raise ArgumentError, "SMTP #{addr_name} address #{error_message}: #{addr.inspect}"
32
- end
33
+ mail = Mail.new(from: 'deprecated@example.com', to: 'deprecated@example.com')
34
+ Mail::SmtpEnvelope.new(mail).send(:validate_addr, addr_name, addr)
33
35
  end
36
+ deprecate :check_addr, :none, 2023, 6
34
37
 
35
38
  def validate_smtp_addr(addr)
36
39
  if addr
@@ -45,6 +48,7 @@ module Mail
45
48
 
46
49
  addr
47
50
  end
51
+ deprecate :validate_smtp_addr, :none, 2023, 6
48
52
 
49
53
  def check_message(message)
50
54
  message = message.encoded if message.respond_to?(:encoded)
@@ -55,6 +59,7 @@ module Mail
55
59
 
56
60
  message
57
61
  end
62
+ deprecate :check_message, :none, 2023, 6
58
63
  end
59
64
  end
60
65
  end
@@ -16,9 +16,10 @@ module Mail
16
16
  control = control.dup.force_encoding(Encoding::BINARY)
17
17
  end
18
18
 
19
- CRLF = /\r?\n/
19
+ LAX_CRLF = /\r?\n/
20
20
  WSP = /[#{white_space}]/
21
- FWS = /#{CRLF}#{WSP}*/
21
+ FWS = /#{LAX_CRLF}#{WSP}*/
22
+ UNFOLD_WS = /#{LAX_CRLF}(#{WSP})/m
22
23
  TEXT = /[#{text}]/ # + obs-text
23
24
  FIELD_NAME = /[#{field_name}]+/
24
25
  FIELD_PREFIX = /\A(#{FIELD_NAME})/
@@ -26,7 +27,7 @@ module Mail
26
27
  FIELD_LINE = /^[#{field_name}]+:\s*.+$/
27
28
  FIELD_SPLIT = /^(#{FIELD_NAME})\s*:\s*(#{FIELD_BODY})?$/
28
29
  HEADER_LINE = /^([#{field_name}]+:\s*.+)$/
29
- HEADER_SPLIT = /#{CRLF}(?!#{WSP})/
30
+ HEADER_SPLIT = /#{LAX_CRLF}(?!#{WSP})/
30
31
 
31
32
  QP_UNSAFE = /[^#{qp_safe}]/
32
33
  QP_SAFE = /[#{qp_safe}]/
@@ -34,8 +35,28 @@ module Mail
34
35
  ATOM_UNSAFE = /[#{Regexp.quote aspecial}#{control}#{sp}]/n
35
36
  PHRASE_UNSAFE = /[#{Regexp.quote aspecial}#{control}]/n
36
37
  TOKEN_UNSAFE = /[#{Regexp.quote tspecial}#{control}#{sp}]/n
37
- ENCODED_VALUE = /\=\?([^?]+)\?([QB])\?[^?]*?\?\=/mi
38
- FULL_ENCODED_VALUE = /(\=\?[^?]+\?[QB]\?[^?]*?\?\=)/mi
38
+
39
+ ENCODED_VALUE = %r{
40
+ \=\? # literal =?
41
+ ([^?]+) #
42
+ \? # literal ?
43
+ ([QB]) # either a "Q" or a "B"
44
+ \? # literal ?
45
+ .*? # lazily match all characters
46
+ \?\= # literal ?=
47
+ }mix # m is multi-line, i is case-insensitive, x is free-spacing
48
+
49
+ FULL_ENCODED_VALUE = %r{ # Identical to ENCODED_VALUE but captures the whole rather than components of
50
+ (
51
+ \=\? # literal =?
52
+ [^?]+ #
53
+ \? # literal ?
54
+ [QB] # either a "Q" or a "B"
55
+ \? # literal ?
56
+ .*? # lazily match all characters
57
+ \?\= # literal ?=
58
+ )
59
+ }mix # m is multi-line, i is case-insensitive, x is free-spacing
39
60
 
40
61
  EMPTY = ''
41
62
  SPACE = ' '
@@ -43,6 +64,7 @@ module Mail
43
64
  HYPHEN = '-'
44
65
  COLON = ':'
45
66
  ASTERISK = '*'
67
+ CRLF = "\r\n"
46
68
  CR = "\r"
47
69
  LF = "\n"
48
70
  CR_ENCODED = "=0D"
@@ -1,27 +1,27 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
3
  require 'mail/parsers/address_lists_parser'
4
+ require 'mail/constants'
5
+ require 'mail/utilities'
4
6
 
5
7
  module Mail
8
+ # Mail::Address handles all email addresses in Mail. It takes an email address string
9
+ # and parses it, breaking it down into its component parts and allowing you to get the
10
+ # address, comments, display name, name, local part, domain part and fully formatted
11
+ # address.
12
+ #
13
+ # Mail::Address requires a correctly formatted email address per RFC2822 or RFC822. It
14
+ # handles all obsolete versions including obsolete domain routing on the local part.
15
+ #
16
+ # a = Address.new('Mikel Lindsaar (My email address) <mikel@test.lindsaar.net>')
17
+ # a.format #=> 'Mikel Lindsaar <mikel@test.lindsaar.net> (My email address)'
18
+ # a.address #=> 'mikel@test.lindsaar.net'
19
+ # a.display_name #=> 'Mikel Lindsaar'
20
+ # a.local #=> 'mikel'
21
+ # a.domain #=> 'test.lindsaar.net'
22
+ # a.comments #=> ['My email address']
23
+ # a.to_s #=> 'Mikel Lindsaar <mikel@test.lindsaar.net> (My email address)'
6
24
  class Address
7
- include Mail::Utilities
8
-
9
- # Mail::Address handles all email addresses in Mail. It takes an email address string
10
- # and parses it, breaking it down into its component parts and allowing you to get the
11
- # address, comments, display name, name, local part, domain part and fully formatted
12
- # address.
13
- #
14
- # Mail::Address requires a correctly formatted email address per RFC2822 or RFC822. It
15
- # handles all obsolete versions including obsolete domain routing on the local part.
16
- #
17
- # a = Address.new('Mikel Lindsaar (My email address) <mikel@test.lindsaar.net>')
18
- # a.format #=> 'Mikel Lindsaar <mikel@test.lindsaar.net> (My email address)'
19
- # a.address #=> 'mikel@test.lindsaar.net'
20
- # a.display_name #=> 'Mikel Lindsaar'
21
- # a.local #=> 'mikel'
22
- # a.domain #=> 'test.lindsaar.net'
23
- # a.comments #=> ['My email address']
24
- # a.to_s #=> 'Mikel Lindsaar <mikel@test.lindsaar.net> (My email address)'
25
25
  def initialize(value = nil)
26
26
  if value.nil?
27
27
  @parsed = false
@@ -47,11 +47,11 @@ module Mail
47
47
  def format(output_type = :decode)
48
48
  parse unless @parsed
49
49
  if @data.nil?
50
- EMPTY
50
+ Constants::EMPTY
51
51
  elsif name = display_name(output_type)
52
- [quote_phrase(name), "<#{address(output_type)}>", format_comments].compact.join(SPACE)
52
+ [Utilities.quote_phrase(name), "<#{address(output_type)}>", format_comments].compact.join(Constants::SPACE)
53
53
  elsif a = address(output_type)
54
- [a, format_comments].compact.join(SPACE)
54
+ [a, format_comments].compact.join(Constants::SPACE)
55
55
  else
56
56
  raw
57
57
  end
@@ -135,7 +135,7 @@ module Mail
135
135
  if comments.nil? || comments.none?
136
136
  nil
137
137
  else
138
- comments.map { |c| c.squeeze(SPACE) }
138
+ comments.map { |c| c.squeeze(Constants::SPACE) }
139
139
  end
140
140
  end
141
141
 
@@ -198,7 +198,7 @@ module Mail
198
198
  def strip_all_comments(string)
199
199
  unless Utilities.blank?(comments)
200
200
  comments.each do |comment|
201
- string = string.gsub("(#{comment})", EMPTY)
201
+ string = string.gsub("(#{comment})", Constants::EMPTY)
202
202
  end
203
203
  end
204
204
  string.strip
@@ -208,7 +208,7 @@ module Mail
208
208
  unless Utilities.blank?(comments)
209
209
  comments.each do |comment|
210
210
  if @data.domain && @data.domain.include?("(#{comment})")
211
- value = value.gsub("(#{comment})", EMPTY)
211
+ value = value.gsub("(#{comment})", Constants::EMPTY)
212
212
  end
213
213
  end
214
214
  end
@@ -228,15 +228,15 @@ module Mail
228
228
  if display_name
229
229
  str = display_name
230
230
  elsif comments
231
- str = "(#{comments.join(SPACE).squeeze(SPACE)})"
231
+ str = "(#{comments.join(Constants::SPACE).squeeze(Constants::SPACE)})"
232
232
  end
233
233
 
234
- unparen(str) unless Utilities.blank?(str)
234
+ Utilities.unparen(str) unless Utilities.blank?(str)
235
235
  end
236
236
 
237
237
  def format_comments
238
238
  if comments
239
- comment_text = comments.map {|c| escape_paren(c) }.join(SPACE).squeeze(SPACE)
239
+ comment_text = comments.map {|c| Utilities.escape_paren(c) }.join(Constants::SPACE).squeeze(Constants::SPACE)
240
240
  @format_comments ||= "(#{comment_text})"
241
241
  else
242
242
  nil
@@ -3,7 +3,7 @@
3
3
  require 'mail/parsers/address_lists_parser'
4
4
 
5
5
  module Mail
6
- class AddressList # :nodoc:
6
+ class AddressList #:nodoc:
7
7
  attr_reader :addresses, :group_names
8
8
 
9
9
  # Mail::AddressList is the class that parses To, From and other address fields from
@@ -3,7 +3,7 @@
3
3
  require 'mail/parsers/content_disposition_parser'
4
4
 
5
5
  module Mail
6
- class ContentDispositionElement # :nodoc:
6
+ class ContentDispositionElement #:nodoc:
7
7
  attr_reader :disposition_type, :parameters
8
8
 
9
9
  def initialize(string)
@@ -3,7 +3,7 @@
3
3
  require 'mail/parsers/content_location_parser'
4
4
 
5
5
  module Mail
6
- class ContentLocationElement # :nodoc:
6
+ class ContentLocationElement #:nodoc:
7
7
  attr_reader :location
8
8
 
9
9
  def initialize(string)
@@ -3,7 +3,7 @@
3
3
  require 'mail/parsers/content_transfer_encoding_parser'
4
4
 
5
5
  module Mail
6
- class ContentTransferEncodingElement
6
+ class ContentTransferEncodingElement #:nodoc:
7
7
  attr_reader :encoding
8
8
 
9
9
  def initialize(string)
@@ -3,7 +3,7 @@
3
3
  require 'mail/parsers/content_type_parser'
4
4
 
5
5
  module Mail
6
- class ContentTypeElement # :nodoc:
6
+ class ContentTypeElement #:nodoc:
7
7
  attr_reader :main_type, :sub_type, :parameters
8
8
 
9
9
  def initialize(string)
@@ -14,8 +14,12 @@ module Mail
14
14
  end
15
15
 
16
16
  private
17
- def cleaned(string)
18
- string =~ /(.+);\s*$/ ? $1 : string
19
- end
17
+ def cleaned(string)
18
+ if string =~ /;\s*$/
19
+ $`
20
+ else
21
+ string
22
+ end
23
+ end
20
24
  end
21
25
  end
@@ -3,7 +3,7 @@
3
3
  require 'mail/parsers/date_time_parser'
4
4
 
5
5
  module Mail
6
- class DateTimeElement # :nodoc:
6
+ class DateTimeElement #:nodoc:
7
7
  attr_reader :date_string, :time_string
8
8
 
9
9
  def initialize(string)