mail 2.2.7 → 2.2.9

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.

data/CHANGELOG.rdoc CHANGED
@@ -1,3 +1,15 @@
1
+ == Tue Oct 26 07:14:36 UTC 2010 Mikel Lindsaar <mikel@rubyx.com>
2
+
3
+ * Version Bump to 2.2.9 and tag
4
+ * Updating Gemfile and gemspec to include i18n and sync dependency versions
5
+ * Added work from Kendall Gifford closing issues #104, #107 and #117
6
+ * Always encode mailbox names with UTF-7 (github: fasta)
7
+
8
+ == Tue Oct 26 06:43:17 UTC 2010 Mikel Lindsaar <mikel@rubyx.com>
9
+
10
+ * Added updates from Donald Ball (github: dball) to improve 1.8.6 support
11
+ * Added patch from Ryan Bigg (github: ryanb) for #mark_for_delete
12
+
1
13
  == Thu Oct 7 15:44:31 UTC 2010 Mikel Lindsaar <mikel@rubyx.com>
2
14
 
3
15
  * Version Bump to 2.2.7
data/lib/VERSION CHANGED
@@ -1,4 +1,4 @@
1
- patch:7
1
+ patch:9
2
2
  major:2
3
3
  build:
4
4
  minor:2
@@ -7,7 +7,7 @@ module Mail
7
7
  def initialize( string )
8
8
  parser = Mail::ContentDispositionParser.new
9
9
  if tree = parser.parse(cleaned(string))
10
- @disposition_type = tree.disposition_type.text_value
10
+ @disposition_type = tree.disposition_type.text_value.downcase
11
11
  @parameters = tree.parameters
12
12
  else
13
13
  raise Mail::Field::ParseError, "ContentDispositionElement can not parse |#{string}|\nReason was: #{parser.failure_reason}\n"
@@ -186,7 +186,7 @@ module Mail
186
186
  address.gsub!(/(".*?[^#{us_ascii}].+?")/) { |s| Encodings.b_value_encode(unquote(s), charset) }
187
187
  # Then loop through all remaining items and encode as needed
188
188
  tokens = address.split(/\s/)
189
- tokens.each_with_index.map do |word, i|
189
+ map_with_index(tokens) do |word, i|
190
190
  if word.ascii_only?
191
191
  word
192
192
  else
@@ -209,7 +209,7 @@ module Mail
209
209
  def Encodings.b_value_encode(str, encoding = nil)
210
210
  return str if str.to_s.ascii_only?
211
211
  string, encoding = RubyVer.b_value_encode(str, encoding)
212
- string.each_line.map do |str|
212
+ map_lines(string) do |str|
213
213
  "=?#{encoding}?B?#{str.chomp}?="
214
214
  end.join(" ")
215
215
  end
@@ -225,7 +225,7 @@ module Mail
225
225
  return str if str.to_s.ascii_only?
226
226
  string, encoding = RubyVer.q_value_encode(str, encoding)
227
227
  string.gsub!("=\r\n", '') # We already have limited the string to the length we want
228
- string.each_line.map do |str|
228
+ map_lines(string) do |str|
229
229
  "=?#{encoding}?Q?#{str.chomp.gsub(/ /, '_')}?="
230
230
  end.join(" ")
231
231
  end
@@ -13,10 +13,20 @@ module Mail
13
13
  include Mail::Utilities
14
14
 
15
15
  def [](key_name)
16
- pairs = select { |k,v| k =~ /^#{key_name}\*/ }
17
- pairs = pairs.to_a if RUBY_VERSION >= '1.9'
16
+ key_pattern = Regexp.escape(key_name.to_s)
17
+ pairs = []
18
+ exact = nil
19
+ each do |k,v|
20
+ if k =~ /^#{key_pattern}(\*|$)/i
21
+ if $1 == '*'
22
+ pairs << [k, v]
23
+ else
24
+ exact = k
25
+ end
26
+ end
27
+ end
18
28
  if pairs.empty? # Just dealing with a single value pair
19
- super(key_name)
29
+ super(exact || key_name)
20
30
  else # Dealing with a multiple value pair or a single encoded value pair
21
31
  string = pairs.sort { |a,b| a.first <=> b.first }.map { |v| v.last }.join('')
22
32
  if mt = string.match(/([\w\d\-]+)'(\w\w)'(.*)/)
data/lib/mail/header.rb CHANGED
@@ -161,16 +161,18 @@ module Mail
161
161
  end
162
162
 
163
163
  def charset
164
- if self[:content_type] && self[:content_type].parameters
165
- self[:content_type].parameters[:charset]
164
+ params = self[:content_type].parameters rescue nil
165
+ if params
166
+ params[:charset]
166
167
  else
167
168
  @charset
168
169
  end
169
170
  end
170
171
 
171
172
  def charset=(val)
172
- if self[:content_type]
173
- self[:content_type].parameters[:charset] = val
173
+ params = self[:content_type].parameters rescue nil
174
+ if params
175
+ params[:charset] = val
174
176
  end
175
177
  @charset = val
176
178
  end
data/lib/mail/message.rb CHANGED
@@ -1276,11 +1276,13 @@ module Mail
1276
1276
  end
1277
1277
 
1278
1278
  def has_content_type?
1279
- !!header[:content_type]
1279
+ tmp = header[:content_type].main_type rescue nil
1280
+ !!tmp
1280
1281
  end
1281
1282
 
1282
1283
  def has_charset?
1283
- !!(has_content_type? && header[:content_type].parameters['charset'])
1284
+ tmp = header[:content_type].parameters rescue nil
1285
+ !!(has_content_type? && tmp && tmp['charset'])
1284
1286
  end
1285
1287
 
1286
1288
  def has_content_transfer_encoding?
@@ -1369,7 +1371,7 @@ module Mail
1369
1371
 
1370
1372
  # Returns the MIME media type of part we are on, this is taken from the content-type header
1371
1373
  def mime_type
1372
- content_type ? header[:content_type].string : nil
1374
+ content_type ? header[:content_type].string : nil rescue nil
1373
1375
  end
1374
1376
 
1375
1377
  def message_content_type
@@ -1395,12 +1397,12 @@ module Mail
1395
1397
 
1396
1398
  # Returns the main content type
1397
1399
  def main_type
1398
- has_content_type? ? header[:content_type].main_type : nil
1400
+ has_content_type? ? header[:content_type].main_type : nil rescue nil
1399
1401
  end
1400
1402
 
1401
1403
  # Returns the sub content type
1402
1404
  def sub_type
1403
- has_content_type? ? header[:content_type].sub_type : nil
1405
+ has_content_type? ? header[:content_type].sub_type : nil rescue nil
1404
1406
  end
1405
1407
 
1406
1408
  # Returns the content type parameters
@@ -1411,7 +1413,7 @@ module Mail
1411
1413
 
1412
1414
  # Returns the content type parameters
1413
1415
  def content_type_parameters
1414
- has_content_type? ? header[:content_type].parameters : nil
1416
+ has_content_type? ? header[:content_type].parameters : nil rescue nil
1415
1417
  end
1416
1418
 
1417
1419
  # Returns true if the message is multipart
@@ -1904,13 +1906,16 @@ module Mail
1904
1906
 
1905
1907
  # Returns the filename of the attachment (if it exists) or returns nil
1906
1908
  def find_attachment
1909
+ content_type_name = header[:content_type].filename rescue nil
1910
+ content_disp_name = header[:content_disposition].filename rescue nil
1911
+ content_loc_name = header[:content_location].location rescue nil
1907
1912
  case
1908
- when content_type && header[:content_type].filename
1909
- filename = header[:content_type].filename
1910
- when content_disposition && header[:content_disposition].filename
1911
- filename = header[:content_disposition].filename
1912
- when content_location && header[:content_location].location
1913
- filename = header[:content_location].location
1913
+ when content_type && content_type_name
1914
+ filename = content_type_name
1915
+ when content_disposition && content_disp_name
1916
+ filename = content_disp_name
1917
+ when content_location && content_loc_name
1918
+ filename = content_loc_name
1914
1919
  else
1915
1920
  filename = nil
1916
1921
  end
@@ -68,7 +68,9 @@ module Mail
68
68
  :user_name => nil,
69
69
  :password => nil,
70
70
  :authentication => nil,
71
- :enable_starttls_auto => true }.merge!(values)
71
+ :enable_starttls_auto => true,
72
+ :openssl_verify_mode => nil
73
+ }.merge!(values)
72
74
  end
73
75
 
74
76
  attr_accessor :settings
@@ -95,7 +97,19 @@ module Mail
95
97
 
96
98
  smtp = Net::SMTP.new(settings[:address], settings[:port])
97
99
  if settings[:enable_starttls_auto]
98
- smtp.enable_starttls_auto if smtp.respond_to?(:enable_starttls_auto)
100
+ if smtp.respond_to?(:enable_starttls_auto)
101
+ unless settings[:openssl_verify_mode]
102
+ smtp.enable_starttls_auto
103
+ else
104
+ openssl_verify_mode = settings[:openssl_verify_mode]
105
+ if openssl_verify_mode.kind_of?(String)
106
+ openssl_verify_mode = "OpenSSL::SSL::VERIFY_#{openssl_verify_mode.upcase}".constantize
107
+ end
108
+ context = Net::SMTP.default_ssl_context
109
+ context.verify_mode = openssl_verify_mode
110
+ smtp.enable_starttls_auto(context)
111
+ end
112
+ end
99
113
  end
100
114
 
101
115
  smtp.start(settings[:domain], settings[:user_name], settings[:password], settings[:authentication]) do |smtp|
@@ -107,4 +121,4 @@ module Mail
107
121
 
108
122
 
109
123
  end
110
- end
124
+ end
@@ -118,16 +118,20 @@ module Mail
118
118
  if block_given?
119
119
  message_ids.each do |message_id|
120
120
  fetchdata = imap.uid_fetch(message_id, ['RFC822'])[0]
121
-
122
- yield Mail.new(fetchdata.attr['RFC822'])
121
+ new_message = Mail.new(fetchdata.attr['RFC822'])
122
+ new_message.mark_for_delete = true if options[:delete_after_find]
123
+ yield new_message
124
+ imap.uid_store(message_id, "+FLAGS", [Net::IMAP::DELETED]) if options[:delete_after_find] && new_message.is_marked_for_delete?
123
125
  end
126
+ imap.expunge if options[:delete_after_find]
124
127
  else
125
128
  emails = []
126
129
  message_ids.each do |message_id|
127
130
  fetchdata = imap.uid_fetch(message_id, ['RFC822'])[0]
128
-
129
131
  emails << Mail.new(fetchdata.attr['RFC822'])
132
+ imap.uid_store(message_id, "+FLAGS", [Net::IMAP::DELETED]) if options[:delete_after_find]
130
133
  end
134
+ imap.expunge if options[:delete_after_find]
131
135
  emails.size == 1 && options[:count] == 1 ? emails.first : emails
132
136
  end
133
137
  end
@@ -136,6 +140,7 @@ module Mail
136
140
  # Delete all emails from a IMAP mailbox
137
141
  def delete_all(mailbox='INBOX')
138
142
  mailbox ||= 'INBOX'
143
+ mailbox = Net::IMAP.encode_utf7(mailbox)
139
144
 
140
145
  start do |imap|
141
146
  imap.select(mailbox)
@@ -165,6 +170,9 @@ module Mail
165
170
  options[:order] ||= :asc
166
171
  options[:what] ||= :first
167
172
  options[:keys] ||= 'ALL'
173
+ options[:delete_after_find] ||= false
174
+ options[:mailbox] = Net::IMAP.encode_utf7(options[:mailbox])
175
+
168
176
  options
169
177
  end
170
178
 
@@ -109,7 +109,7 @@ module Mail
109
109
  if block_given?
110
110
  mails.each do |mail|
111
111
  new_message = Mail.new(mail.pop)
112
- new_message.marked_for_delete = true if options[:delete_after_find]
112
+ new_message.mark_for_delete = true if options[:delete_after_find]
113
113
  yield new_message
114
114
  mail.delete if options[:delete_after_find] && new_message.is_marked_for_delete? # Delete if still marked for delete
115
115
  end
@@ -113,6 +113,12 @@ module Mail
113
113
  r0
114
114
  end
115
115
 
116
+ module DispositionType0
117
+ end
118
+
119
+ module DispositionType1
120
+ end
121
+
116
122
  def _nt_disposition_type
117
123
  start_index = index
118
124
  if node_cache[:disposition_type].has_key?(index)
@@ -125,39 +131,181 @@ module Mail
125
131
  end
126
132
 
127
133
  i0 = index
128
- if has_terminal?("inline", false, index)
129
- r1 = instantiate_node(SyntaxNode,input, index...(index + 6))
130
- @index += 6
134
+ i1, s1 = index, []
135
+ if has_terminal?('\G[iI]', true, index)
136
+ r2 = true
137
+ @index += 1
131
138
  else
132
- terminal_parse_failure("inline")
139
+ r2 = nil
140
+ end
141
+ s1 << r2
142
+ if r2
143
+ if has_terminal?('\G[nN]', true, index)
144
+ r3 = true
145
+ @index += 1
146
+ else
147
+ r3 = nil
148
+ end
149
+ s1 << r3
150
+ if r3
151
+ if has_terminal?('\G[lL]', true, index)
152
+ r4 = true
153
+ @index += 1
154
+ else
155
+ r4 = nil
156
+ end
157
+ s1 << r4
158
+ if r4
159
+ if has_terminal?('\G[iI]', true, index)
160
+ r5 = true
161
+ @index += 1
162
+ else
163
+ r5 = nil
164
+ end
165
+ s1 << r5
166
+ if r5
167
+ if has_terminal?('\G[nN]', true, index)
168
+ r6 = true
169
+ @index += 1
170
+ else
171
+ r6 = nil
172
+ end
173
+ s1 << r6
174
+ if r6
175
+ if has_terminal?('\G[eE]', true, index)
176
+ r7 = true
177
+ @index += 1
178
+ else
179
+ r7 = nil
180
+ end
181
+ s1 << r7
182
+ end
183
+ end
184
+ end
185
+ end
186
+ end
187
+ if s1.last
188
+ r1 = instantiate_node(SyntaxNode,input, i1...index, s1)
189
+ r1.extend(DispositionType0)
190
+ else
191
+ @index = i1
133
192
  r1 = nil
134
193
  end
135
194
  if r1
136
195
  r0 = r1
137
196
  else
138
- if has_terminal?("attachment", false, index)
139
- r2 = instantiate_node(SyntaxNode,input, index...(index + 10))
140
- @index += 10
197
+ i8, s8 = index, []
198
+ if has_terminal?('\G[aA]', true, index)
199
+ r9 = true
200
+ @index += 1
141
201
  else
142
- terminal_parse_failure("attachment")
143
- r2 = nil
202
+ r9 = nil
144
203
  end
145
- if r2
146
- r0 = r2
204
+ s8 << r9
205
+ if r9
206
+ if has_terminal?('\G[tT]', true, index)
207
+ r10 = true
208
+ @index += 1
209
+ else
210
+ r10 = nil
211
+ end
212
+ s8 << r10
213
+ if r10
214
+ if has_terminal?('\G[tT]', true, index)
215
+ r11 = true
216
+ @index += 1
217
+ else
218
+ r11 = nil
219
+ end
220
+ s8 << r11
221
+ if r11
222
+ if has_terminal?('\G[aA]', true, index)
223
+ r12 = true
224
+ @index += 1
225
+ else
226
+ r12 = nil
227
+ end
228
+ s8 << r12
229
+ if r12
230
+ if has_terminal?('\G[cC]', true, index)
231
+ r13 = true
232
+ @index += 1
233
+ else
234
+ r13 = nil
235
+ end
236
+ s8 << r13
237
+ if r13
238
+ if has_terminal?('\G[hH]', true, index)
239
+ r14 = true
240
+ @index += 1
241
+ else
242
+ r14 = nil
243
+ end
244
+ s8 << r14
245
+ if r14
246
+ if has_terminal?('\G[mM]', true, index)
247
+ r15 = true
248
+ @index += 1
249
+ else
250
+ r15 = nil
251
+ end
252
+ s8 << r15
253
+ if r15
254
+ if has_terminal?('\G[eE]', true, index)
255
+ r16 = true
256
+ @index += 1
257
+ else
258
+ r16 = nil
259
+ end
260
+ s8 << r16
261
+ if r16
262
+ if has_terminal?('\G[nN]', true, index)
263
+ r17 = true
264
+ @index += 1
265
+ else
266
+ r17 = nil
267
+ end
268
+ s8 << r17
269
+ if r17
270
+ if has_terminal?('\G[tT]', true, index)
271
+ r18 = true
272
+ @index += 1
273
+ else
274
+ r18 = nil
275
+ end
276
+ s8 << r18
277
+ end
278
+ end
279
+ end
280
+ end
281
+ end
282
+ end
283
+ end
284
+ end
285
+ end
286
+ if s8.last
287
+ r8 = instantiate_node(SyntaxNode,input, i8...index, s8)
288
+ r8.extend(DispositionType1)
147
289
  else
148
- r3 = _nt_extension_token
149
- if r3
150
- r0 = r3
290
+ @index = i8
291
+ r8 = nil
292
+ end
293
+ if r8
294
+ r0 = r8
295
+ else
296
+ r19 = _nt_extension_token
297
+ if r19
298
+ r0 = r19
151
299
  else
152
300
  if has_terminal?('', false, index)
153
- r4 = instantiate_node(SyntaxNode,input, index...(index + 0))
301
+ r20 = instantiate_node(SyntaxNode,input, index...(index + 0))
154
302
  @index += 0
155
303
  else
156
304
  terminal_parse_failure('')
157
- r4 = nil
305
+ r20 = nil
158
306
  end
159
- if r4
160
- r0 = r4
307
+ if r20
308
+ r0 = r20
161
309
  else
162
310
  @index = i0
163
311
  r0 = nil
@@ -15,7 +15,7 @@ module Mail
15
15
  end
16
16
 
17
17
  rule disposition_type
18
- "inline" / "attachment" / extension_token / ''
18
+ [iI] [nN] [lL] [iI] [nN] [eE] / [aA] [tT] [tT] [aA] [cC] [hH] [mM] [eE] [nN] [tT] / extension_token / ''
19
19
  end
20
20
 
21
21
  rule extension_token
@@ -176,6 +176,36 @@ module Mail
176
176
  def underscoreize( str )
177
177
  str.to_s.downcase.gsub('-', '_')
178
178
  end
179
-
179
+
180
+ if RUBY_VERSION <= '1.8.6'
181
+
182
+ def map_lines( str, &block )
183
+ results = []
184
+ str.each_line do |line|
185
+ results << yield(line)
186
+ end
187
+ results
188
+ end
189
+
190
+ def map_with_index( enum, &block )
191
+ results = []
192
+ enum.each_with_index do |token, i|
193
+ results[i] = yield(token, i)
194
+ end
195
+ results
196
+ end
197
+
198
+ else
199
+
200
+ def map_lines( str, &block )
201
+ str.each_line.map(&block)
202
+ end
203
+
204
+ def map_with_index( enum, &block )
205
+ enum.each_with_index.map(&block)
206
+ end
207
+
208
+ end
209
+
180
210
  end
181
211
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mail
3
3
  version: !ruby/object:Gem::Version
4
- hash: 9
4
+ hash: 21
5
5
  prerelease: false
6
6
  segments:
7
7
  - 2
8
8
  - 2
9
- - 7
10
- version: 2.2.7
9
+ - 9
10
+ version: 2.2.9
11
11
  platform: ruby
12
12
  authors:
13
13
  - Mikel Lindsaar
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-10-08 00:00:00 +11:00
18
+ date: 2010-10-26 00:00:00 +11:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -40,12 +40,13 @@ dependencies:
40
40
  requirement: &id002 !ruby/object:Gem::Requirement
41
41
  none: false
42
42
  requirements:
43
- - - ">="
43
+ - - ~>
44
44
  - !ruby/object:Gem::Version
45
- hash: 3
45
+ hash: 47
46
46
  segments:
47
- - 0
48
- version: "0"
47
+ - 1
48
+ - 16
49
+ version: "1.16"
49
50
  type: :runtime
50
51
  version_requirements: *id002
51
52
  - !ruby/object:Gem::Dependency
@@ -54,16 +55,32 @@ dependencies:
54
55
  requirement: &id003 !ruby/object:Gem::Requirement
55
56
  none: false
56
57
  requirements:
57
- - - ">="
58
+ - - ~>
58
59
  - !ruby/object:Gem::Version
59
- hash: 13
60
+ hash: 23
60
61
  segments:
61
62
  - 1
62
63
  - 4
63
- - 5
64
- version: 1.4.5
64
+ - 8
65
+ version: 1.4.8
65
66
  type: :runtime
66
67
  version_requirements: *id003
68
+ - !ruby/object:Gem::Dependency
69
+ name: i18n
70
+ prerelease: false
71
+ requirement: &id004 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ~>
75
+ - !ruby/object:Gem::Version
76
+ hash: 13
77
+ segments:
78
+ - 0
79
+ - 4
80
+ - 1
81
+ version: 0.4.1
82
+ type: :runtime
83
+ version_requirements: *id004
67
84
  description: A really Ruby Mail handler.
68
85
  email: raasdnil@gmail.com
69
86
  executables: []