net-imap 0.4.19 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of net-imap might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Gemfile +7 -1
- data/lib/net/imap/authenticators.rb +2 -2
- data/lib/net/imap/command_data.rb +11 -0
- data/lib/net/imap/config.rb +36 -79
- data/lib/net/imap/data_encoding.rb +3 -3
- data/lib/net/imap/deprecated_client_options.rb +6 -3
- data/lib/net/imap/errors.rb +6 -0
- data/lib/net/imap/response_data.rb +60 -96
- data/lib/net/imap/response_parser.rb +18 -45
- data/lib/net/imap/sasl/authentication_exchange.rb +52 -20
- data/lib/net/imap/sasl/authenticators.rb +8 -4
- data/lib/net/imap/sasl/client_adapter.rb +77 -26
- data/lib/net/imap/sasl/cram_md5_authenticator.rb +1 -1
- data/lib/net/imap/sasl/digest_md5_authenticator.rb +213 -51
- data/lib/net/imap/sasl/login_authenticator.rb +2 -1
- data/lib/net/imap/sasl/protocol_adapters.rb +60 -4
- data/lib/net/imap/sasl.rb +6 -3
- data/lib/net/imap/sasl_adapter.rb +0 -1
- data/lib/net/imap/sequence_set.rb +70 -213
- data/lib/net/imap.rb +29 -55
- data/net-imap.gemspec +1 -1
- metadata +7 -5
- data/lib/net/imap/uidplus_data.rb +0 -326
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2c89d97e842bce303df112c3fbc0f048f20a2ff1dbf3b85bb2314ea0d2e207c5
|
4
|
+
data.tar.gz: 11d6ec196e1e768f61a17b0ce7f385a11eb03e3e92af8ab327ba9a90699ee940
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ca70e20c3c70f4ca57822f70936546adb3129dd7c0771ef2d054b0356ed4f6a994b7453803cc06bd25ebb37dc0ed10f60b5541bc56749dee38a6126264344599
|
7
|
+
data.tar.gz: 2921a79dbdab7bd0476d883c18db50150388d587c711270faac99ad4505574a23e6532fe61a4fb48f51c8bddea6641d96f81d9dcbe245b4d4f4542fcc7418566
|
data/Gemfile
CHANGED
@@ -13,4 +13,10 @@ gem "rdoc"
|
|
13
13
|
gem "test-unit"
|
14
14
|
gem "test-unit-ruby-core", git: "https://github.com/ruby/test-unit-ruby-core"
|
15
15
|
|
16
|
-
gem "benchmark-driver"
|
16
|
+
gem "benchmark-driver", require: false
|
17
|
+
|
18
|
+
group :test do
|
19
|
+
gem "simplecov", require: false
|
20
|
+
gem "simplecov-html", require: false
|
21
|
+
gem "simplecov-json", require: false
|
22
|
+
end
|
@@ -9,7 +9,7 @@ module Net::IMAP::Authenticators
|
|
9
9
|
"%s.%s is deprecated. Use %s.%s instead." % [
|
10
10
|
Net::IMAP, __method__, Net::IMAP::SASL, __method__
|
11
11
|
],
|
12
|
-
uplevel: 1
|
12
|
+
uplevel: 1, category: :deprecated
|
13
13
|
)
|
14
14
|
Net::IMAP::SASL.add_authenticator(...)
|
15
15
|
end
|
@@ -20,7 +20,7 @@ module Net::IMAP::Authenticators
|
|
20
20
|
"%s.%s is deprecated. Use %s.%s instead." % [
|
21
21
|
Net::IMAP, __method__, Net::IMAP::SASL, __method__
|
22
22
|
],
|
23
|
-
uplevel: 1
|
23
|
+
uplevel: 1, category: :deprecated
|
24
24
|
)
|
25
25
|
Net::IMAP::SASL.authenticator(...)
|
26
26
|
end
|
@@ -179,6 +179,7 @@ module Net
|
|
179
179
|
end
|
180
180
|
end
|
181
181
|
|
182
|
+
# *DEPRECATED*. Replaced by SequenceSet.
|
182
183
|
class MessageSet # :nodoc:
|
183
184
|
def send_data(imap, tag)
|
184
185
|
imap.__send__(:put_string, format_internal(@data))
|
@@ -192,6 +193,16 @@ module Net
|
|
192
193
|
|
193
194
|
def initialize(data)
|
194
195
|
@data = data
|
196
|
+
warn("DEPRECATED: #{MessageSet} should be replaced with #{SequenceSet}.",
|
197
|
+
uplevel: 1, category: :deprecated)
|
198
|
+
begin
|
199
|
+
# to ensure the input works with SequenceSet, too
|
200
|
+
SequenceSet.new(data)
|
201
|
+
rescue
|
202
|
+
warn "MessageSet input is incompatible with SequenceSet: [%s] %s" % [
|
203
|
+
$!.class, $!.message
|
204
|
+
]
|
205
|
+
end
|
195
206
|
end
|
196
207
|
|
197
208
|
def format_internal(data)
|
data/lib/net/imap/config.rb
CHANGED
@@ -223,6 +223,29 @@ module Net
|
|
223
223
|
# Use +SASL-IR+ when it is supported by the server and the mechanism.
|
224
224
|
attr_accessor :sasl_ir, type: :boolean
|
225
225
|
|
226
|
+
# Controls the behavior of Net::IMAP#login when the +LOGINDISABLED+
|
227
|
+
# capability is present. When enforced, Net::IMAP will raise a
|
228
|
+
# LoginDisabledError when that capability is present.
|
229
|
+
#
|
230
|
+
# <em>(Support for +LOGINDISABLED+ was added in +v0.5.0+.)</em>
|
231
|
+
#
|
232
|
+
# ==== Valid options
|
233
|
+
#
|
234
|
+
# [+false+ <em>(original behavior, before support was added)</em>]
|
235
|
+
# Send the +LOGIN+ command without checking for +LOGINDISABLED+.
|
236
|
+
#
|
237
|
+
# [+:when_capabilities_cached+]
|
238
|
+
# Enforce the requirement when Net::IMAP#capabilities_cached? is true,
|
239
|
+
# but do not send a +CAPABILITY+ command to discover the capabilities.
|
240
|
+
#
|
241
|
+
# [+true+ <em>(default since +v0.5+)</em>]
|
242
|
+
# Only send the +LOGIN+ command if the +LOGINDISABLED+ capability is not
|
243
|
+
# present. When capabilities are unknown, Net::IMAP will automatically
|
244
|
+
# send a +CAPABILITY+ command first before sending +LOGIN+.
|
245
|
+
#
|
246
|
+
attr_accessor :enforce_logindisabled, type: [
|
247
|
+
false, :when_capabilities_cached, true
|
248
|
+
]
|
226
249
|
|
227
250
|
# Controls the behavior of Net::IMAP#responses when called without any
|
228
251
|
# arguments (+type+ or +block+).
|
@@ -262,67 +285,6 @@ module Net
|
|
262
285
|
#
|
263
286
|
# Alias for responses_without_block
|
264
287
|
|
265
|
-
# Whether ResponseParser should use the deprecated UIDPlusData or
|
266
|
-
# CopyUIDData for +COPYUID+ response codes, and UIDPlusData or
|
267
|
-
# AppendUIDData for +APPENDUID+ response codes.
|
268
|
-
#
|
269
|
-
# UIDPlusData stores its data in arrays of numbers, which is vulnerable to
|
270
|
-
# a memory exhaustion denial of service attack from an untrusted or
|
271
|
-
# compromised server. Set this option to +false+ to completely block this
|
272
|
-
# vulnerability. Otherwise, parser_max_deprecated_uidplus_data_size
|
273
|
-
# mitigates this vulnerability.
|
274
|
-
#
|
275
|
-
# AppendUIDData and CopyUIDData are _mostly_ backward-compatible with
|
276
|
-
# UIDPlusData. Most applications should be able to upgrade with little
|
277
|
-
# or no changes.
|
278
|
-
#
|
279
|
-
# <em>(Parser support for +UIDPLUS+ added in +v0.3.2+.)</em>
|
280
|
-
#
|
281
|
-
# <em>(Config option added in +v0.4.19+ and +v0.5.6+.)</em>
|
282
|
-
#
|
283
|
-
# <em>UIDPlusData will be removed in +v0.6+ and this config setting will
|
284
|
-
# be ignored.</em>
|
285
|
-
#
|
286
|
-
# ==== Valid options
|
287
|
-
#
|
288
|
-
# [+true+ <em>(original default)</em>]
|
289
|
-
# ResponseParser only uses UIDPlusData.
|
290
|
-
#
|
291
|
-
# [+:up_to_max_size+ <em>(default since +v0.5.6+)</em>]
|
292
|
-
# ResponseParser uses UIDPlusData when the +uid-set+ size is below
|
293
|
-
# parser_max_deprecated_uidplus_data_size. Above that size,
|
294
|
-
# ResponseParser uses AppendUIDData or CopyUIDData.
|
295
|
-
#
|
296
|
-
# [+false+ <em>(planned default for +v0.6+)</em>]
|
297
|
-
# ResponseParser _only_ uses AppendUIDData and CopyUIDData.
|
298
|
-
attr_accessor :parser_use_deprecated_uidplus_data, type: [
|
299
|
-
true, :up_to_max_size, false
|
300
|
-
]
|
301
|
-
|
302
|
-
# The maximum +uid-set+ size that ResponseParser will parse into
|
303
|
-
# deprecated UIDPlusData. This limit only applies when
|
304
|
-
# parser_use_deprecated_uidplus_data is not +false+.
|
305
|
-
#
|
306
|
-
# <em>(Parser support for +UIDPLUS+ added in +v0.3.2+.)</em>
|
307
|
-
#
|
308
|
-
# <em>Support for limiting UIDPlusData to a maximum size was added in
|
309
|
-
# +v0.3.8+, +v0.4.19+, and +v0.5.6+.</em>
|
310
|
-
#
|
311
|
-
# <em>UIDPlusData will be removed in +v0.6+.</em>
|
312
|
-
#
|
313
|
-
# ==== Versioned Defaults
|
314
|
-
#
|
315
|
-
# Because this limit guards against a remote server causing catastrophic
|
316
|
-
# memory exhaustion, the versioned default (used by #load_defaults) also
|
317
|
-
# applies to versions without the feature.
|
318
|
-
#
|
319
|
-
# * +0.3+ and prior: <tt>10,000</tt>
|
320
|
-
# * +0.4+: <tt>1,000</tt>
|
321
|
-
# * +0.5+: <tt>100</tt>
|
322
|
-
# * +0.6+: <tt>0</tt>
|
323
|
-
#
|
324
|
-
attr_accessor :parser_max_deprecated_uidplus_data_size, type: Integer
|
325
|
-
|
326
288
|
# Creates a new config object and initialize its attribute with +attrs+.
|
327
289
|
#
|
328
290
|
# If +parent+ is not given, the global config is used by default.
|
@@ -401,41 +363,36 @@ module Net
|
|
401
363
|
open_timeout: 30,
|
402
364
|
idle_response_timeout: 5,
|
403
365
|
sasl_ir: true,
|
404
|
-
|
405
|
-
|
406
|
-
parser_max_deprecated_uidplus_data_size: 1000,
|
366
|
+
enforce_logindisabled: true,
|
367
|
+
responses_without_block: :warn,
|
407
368
|
).freeze
|
408
369
|
|
409
370
|
@global = default.new
|
410
371
|
|
411
|
-
version_defaults[
|
372
|
+
version_defaults[:default] = Config[default.send(:defaults_hash)]
|
373
|
+
version_defaults[:current] = Config[:default]
|
412
374
|
|
413
|
-
version_defaults[0] = Config[
|
375
|
+
version_defaults[0] = Config[:current].dup.update(
|
414
376
|
sasl_ir: false,
|
415
|
-
|
416
|
-
|
377
|
+
responses_without_block: :silence_deprecation_warning,
|
378
|
+
enforce_logindisabled: false,
|
417
379
|
).freeze
|
418
380
|
version_defaults[0.0] = Config[0]
|
419
381
|
version_defaults[0.1] = Config[0]
|
420
382
|
version_defaults[0.2] = Config[0]
|
421
383
|
version_defaults[0.3] = Config[0]
|
422
384
|
|
423
|
-
version_defaults[0.
|
424
|
-
|
425
|
-
parser_use_deprecated_uidplus_data: :up_to_max_size,
|
426
|
-
parser_max_deprecated_uidplus_data_size: 100,
|
385
|
+
version_defaults[0.4] = Config[0.3].dup.update(
|
386
|
+
sasl_ir: true,
|
427
387
|
).freeze
|
428
388
|
|
429
|
-
version_defaults[
|
430
|
-
version_defaults[:current] = Config[0.4]
|
431
|
-
version_defaults[:next] = Config[0.5]
|
389
|
+
version_defaults[0.5] = Config[:current]
|
432
390
|
|
433
|
-
version_defaults[0.6]
|
391
|
+
version_defaults[0.6] = Config[0.5].dup.update(
|
434
392
|
responses_without_block: :frozen_dup,
|
435
|
-
parser_use_deprecated_uidplus_data: false,
|
436
|
-
parser_max_deprecated_uidplus_data_size: 0,
|
437
393
|
).freeze
|
438
|
-
version_defaults[:
|
394
|
+
version_defaults[:next] = Config[0.6]
|
395
|
+
version_defaults[:future] = Config[:next]
|
439
396
|
|
440
397
|
version_defaults.freeze
|
441
398
|
end
|
@@ -186,7 +186,7 @@ module Net
|
|
186
186
|
|
187
187
|
# Ensure argument is 'number' or raise DataFormatError
|
188
188
|
def ensure_number(num)
|
189
|
-
return if valid_number?(num)
|
189
|
+
return num if valid_number?(num)
|
190
190
|
|
191
191
|
msg = "number must be unsigned 32-bit integer: #{num}"
|
192
192
|
raise DataFormatError, msg
|
@@ -194,7 +194,7 @@ module Net
|
|
194
194
|
|
195
195
|
# Ensure argument is 'nz_number' or raise DataFormatError
|
196
196
|
def ensure_nz_number(num)
|
197
|
-
return if valid_nz_number?(num)
|
197
|
+
return num if valid_nz_number?(num)
|
198
198
|
|
199
199
|
msg = "nz_number must be non-zero unsigned 32-bit integer: #{num}"
|
200
200
|
raise DataFormatError, msg
|
@@ -202,7 +202,7 @@ module Net
|
|
202
202
|
|
203
203
|
# Ensure argument is 'mod_sequence_value' or raise DataFormatError
|
204
204
|
def ensure_mod_sequence_value(num)
|
205
|
-
return if valid_mod_sequence_value?(num)
|
205
|
+
return num if valid_mod_sequence_value?(num)
|
206
206
|
|
207
207
|
msg = "mod_sequence_value must be unsigned 64-bit integer: #{num}"
|
208
208
|
raise DataFormatError, msg
|
@@ -83,10 +83,12 @@ module Net
|
|
83
83
|
elsif deprecated.empty?
|
84
84
|
super host, port: port_or_options
|
85
85
|
elsif deprecated.shift
|
86
|
-
warn
|
86
|
+
warn("DEPRECATED: Call Net::IMAP.new with keyword options",
|
87
|
+
uplevel: 1, category: :deprecated)
|
87
88
|
super host, port: port_or_options, ssl: create_ssl_params(*deprecated)
|
88
89
|
else
|
89
|
-
warn
|
90
|
+
warn("DEPRECATED: Call Net::IMAP.new with keyword options",
|
91
|
+
uplevel: 1, category: :deprecated)
|
90
92
|
super host, port: port_or_options, ssl: false
|
91
93
|
end
|
92
94
|
end
|
@@ -113,7 +115,8 @@ module Net
|
|
113
115
|
elsif deprecated.first.respond_to?(:to_hash)
|
114
116
|
super(**Hash.try_convert(deprecated.first))
|
115
117
|
else
|
116
|
-
warn
|
118
|
+
warn("DEPRECATED: Call Net::IMAP#starttls with keyword options",
|
119
|
+
uplevel: 1, category: :deprecated)
|
117
120
|
super(**create_ssl_params(*deprecated))
|
118
121
|
end
|
119
122
|
end
|
data/lib/net/imap/errors.rb
CHANGED
@@ -7,6 +7,12 @@ module Net
|
|
7
7
|
class Error < StandardError
|
8
8
|
end
|
9
9
|
|
10
|
+
class LoginDisabledError < Error
|
11
|
+
def initialize(msg = "Remote server has disabled the LOGIN command", ...)
|
12
|
+
super
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
10
16
|
# Error raised when data is in the incorrect format.
|
11
17
|
class DataFormatError < Error
|
12
18
|
end
|
@@ -5,9 +5,6 @@ module Net
|
|
5
5
|
autoload :FetchData, "#{__dir__}/fetch_data"
|
6
6
|
autoload :SearchResult, "#{__dir__}/search_result"
|
7
7
|
autoload :SequenceSet, "#{__dir__}/sequence_set"
|
8
|
-
autoload :UIDPlusData, "#{__dir__}/uidplus_data"
|
9
|
-
autoload :AppendUIDData, "#{__dir__}/uidplus_data"
|
10
|
-
autoload :CopyUIDData, "#{__dir__}/uidplus_data"
|
11
8
|
|
12
9
|
# Net::IMAP::ContinuationRequest represents command continuation requests.
|
13
10
|
#
|
@@ -327,6 +324,60 @@ module Net
|
|
327
324
|
# code data can take.
|
328
325
|
end
|
329
326
|
|
327
|
+
# Net::IMAP::UIDPlusData represents the ResponseCode#data that accompanies
|
328
|
+
# the +APPENDUID+ and +COPYUID+ response codes.
|
329
|
+
#
|
330
|
+
# See [[UIDPLUS[https://www.rfc-editor.org/rfc/rfc4315.html]].
|
331
|
+
#
|
332
|
+
# ==== Capability requirement
|
333
|
+
#
|
334
|
+
# The +UIDPLUS+ capability[rdoc-ref:Net::IMAP#capability] must be supported.
|
335
|
+
# A server that supports +UIDPLUS+ should send a UIDPlusData object inside
|
336
|
+
# every TaggedResponse returned by the append[rdoc-ref:Net::IMAP#append],
|
337
|
+
# copy[rdoc-ref:Net::IMAP#copy], move[rdoc-ref:Net::IMAP#move], {uid
|
338
|
+
# copy}[rdoc-ref:Net::IMAP#uid_copy], and {uid
|
339
|
+
# move}[rdoc-ref:Net::IMAP#uid_move] commands---unless the destination
|
340
|
+
# mailbox reports +UIDNOTSTICKY+.
|
341
|
+
#
|
342
|
+
#--
|
343
|
+
# TODO: support MULTIAPPEND
|
344
|
+
#++
|
345
|
+
#
|
346
|
+
class UIDPlusData < Struct.new(:uidvalidity, :source_uids, :assigned_uids)
|
347
|
+
##
|
348
|
+
# method: uidvalidity
|
349
|
+
# :call-seq: uidvalidity -> nonzero uint32
|
350
|
+
#
|
351
|
+
# The UIDVALIDITY of the destination mailbox.
|
352
|
+
|
353
|
+
##
|
354
|
+
# method: source_uids
|
355
|
+
# :call-seq: source_uids -> nil or an array of nonzero uint32
|
356
|
+
#
|
357
|
+
# The UIDs of the copied or moved messages.
|
358
|
+
#
|
359
|
+
# Note:: Returns +nil+ for Net::IMAP#append.
|
360
|
+
|
361
|
+
##
|
362
|
+
# method: assigned_uids
|
363
|
+
# :call-seq: assigned_uids -> an array of nonzero uint32
|
364
|
+
#
|
365
|
+
# The newly assigned UIDs of the copied, moved, or appended messages.
|
366
|
+
#
|
367
|
+
# Note:: This always returns an array, even when it contains only one UID.
|
368
|
+
|
369
|
+
##
|
370
|
+
# :call-seq: uid_mapping -> nil or a hash
|
371
|
+
#
|
372
|
+
# Returns a hash mapping each source UID to the newly assigned destination
|
373
|
+
# UID.
|
374
|
+
#
|
375
|
+
# Note:: Returns +nil+ for Net::IMAP#append.
|
376
|
+
def uid_mapping
|
377
|
+
source_uids&.zip(assigned_uids)&.to_h
|
378
|
+
end
|
379
|
+
end
|
380
|
+
|
330
381
|
# Net::IMAP::MailboxList represents contents of the LIST response,
|
331
382
|
# representing a single mailbox path.
|
332
383
|
#
|
@@ -888,7 +939,8 @@ module Net
|
|
888
939
|
# for something else?
|
889
940
|
#++
|
890
941
|
def media_subtype
|
891
|
-
warn("media_subtype is obsolete, use subtype instead.\n",
|
942
|
+
warn("media_subtype is obsolete, use subtype instead.\n",
|
943
|
+
uplevel: 1, category: :deprecated)
|
892
944
|
return subtype
|
893
945
|
end
|
894
946
|
end
|
@@ -933,7 +985,8 @@ module Net
|
|
933
985
|
# generate a warning message to +stderr+, then return
|
934
986
|
# the value of +subtype+.
|
935
987
|
def media_subtype
|
936
|
-
warn("media_subtype is obsolete, use subtype instead.\n",
|
988
|
+
warn("media_subtype is obsolete, use subtype instead.\n",
|
989
|
+
uplevel: 1, category: :deprecated)
|
937
990
|
return subtype
|
938
991
|
end
|
939
992
|
end
|
@@ -989,77 +1042,6 @@ module Net
|
|
989
1042
|
end
|
990
1043
|
end
|
991
1044
|
|
992
|
-
# BodyTypeAttachment is not used and will be removed in an upcoming release.
|
993
|
-
#
|
994
|
-
# === Bug Analysis
|
995
|
-
#
|
996
|
-
# \IMAP body structures are parenthesized lists and assign their fields
|
997
|
-
# positionally, so missing fields change the interpretation of all
|
998
|
-
# following fields. Additionally, different body types have a different
|
999
|
-
# number of required fields, followed by optional "extension" fields.
|
1000
|
-
#
|
1001
|
-
# BodyTypeAttachment was previously returned when a "message/rfc822" part,
|
1002
|
-
# which should be sent as <tt>body-type-msg</tt> with ten required fields,
|
1003
|
-
# was actually sent as a <tt>body-type-basic</tt> with _seven_ required
|
1004
|
-
# fields.
|
1005
|
-
#
|
1006
|
-
# basic => type, subtype, param, id, desc, enc, octets, md5=nil, dsp=nil, lang=nil, loc=nil, *ext
|
1007
|
-
# msg => type, subtype, param, id, desc, enc, octets, envelope, body, lines, md5=nil, ...
|
1008
|
-
#
|
1009
|
-
# Normally, +envelope+ and +md5+ are incompatible, but Net::IMAP leniently
|
1010
|
-
# allowed buggy servers to send +NIL+ for +envelope+. As a result, when a
|
1011
|
-
# server sent a <tt>message/rfc822</tt> part with +NIL+ for +md5+ and a
|
1012
|
-
# non-<tt>NIL</tt> +dsp+, Net::IMAP misinterpreted the
|
1013
|
-
# <tt>Content-Disposition</tt> as if it were a strange body type. In all
|
1014
|
-
# reported cases, the <tt>Content-Disposition</tt> was "attachment", so
|
1015
|
-
# BodyTypeAttachment was created as the workaround.
|
1016
|
-
#
|
1017
|
-
# === Current behavior
|
1018
|
-
#
|
1019
|
-
# When interpreted strictly, +envelope+ and +md5+ are incompatible. So the
|
1020
|
-
# current parsing algorithm peeks ahead after it has received the seventh
|
1021
|
-
# body field. If the next token is not the start of an +envelope+, we assume
|
1022
|
-
# the server has incorrectly sent us a <tt>body-type-basic</tt> and return
|
1023
|
-
# BodyTypeBasic. As a result, what was previously BodyTypeMessage#body =>
|
1024
|
-
# BodyTypeAttachment is now BodyTypeBasic#disposition => ContentDisposition.
|
1025
|
-
#
|
1026
|
-
class BodyTypeAttachment < Struct.new(:dsp_type, :_unused_, :param)
|
1027
|
-
# *invalid for BodyTypeAttachment*
|
1028
|
-
def media_type
|
1029
|
-
warn(<<~WARN, uplevel: 1)
|
1030
|
-
BodyTypeAttachment#media_type is obsolete. Use dsp_type instead.
|
1031
|
-
WARN
|
1032
|
-
dsp_type
|
1033
|
-
end
|
1034
|
-
|
1035
|
-
# *invalid for BodyTypeAttachment*
|
1036
|
-
def subtype
|
1037
|
-
warn("BodyTypeAttachment#subtype is obsolete.\n", uplevel: 1)
|
1038
|
-
nil
|
1039
|
-
end
|
1040
|
-
|
1041
|
-
##
|
1042
|
-
# method: dsp_type
|
1043
|
-
# :call-seq: dsp_type -> string
|
1044
|
-
#
|
1045
|
-
# Returns the content disposition type, as defined by
|
1046
|
-
# [DISPOSITION[https://tools.ietf.org/html/rfc2183]].
|
1047
|
-
|
1048
|
-
##
|
1049
|
-
# method: param
|
1050
|
-
# :call-seq: param -> hash
|
1051
|
-
#
|
1052
|
-
# Returns a hash representing parameters of the Content-Disposition
|
1053
|
-
# field, as defined by [DISPOSITION[https://tools.ietf.org/html/rfc2183]].
|
1054
|
-
|
1055
|
-
##
|
1056
|
-
def multipart?
|
1057
|
-
return false
|
1058
|
-
end
|
1059
|
-
end
|
1060
|
-
|
1061
|
-
deprecate_constant :BodyTypeAttachment
|
1062
|
-
|
1063
1045
|
# Net::IMAP::BodyTypeMultipart represents body structures of messages and
|
1064
1046
|
# message parts, when <tt>Content-Type</tt> is <tt>multipart/*</tt>.
|
1065
1047
|
class BodyTypeMultipart < Struct.new(:media_type, :subtype,
|
@@ -1131,29 +1113,11 @@ module Net
|
|
1131
1113
|
# generate a warning message to +stderr+, then return
|
1132
1114
|
# the value of +subtype+.
|
1133
1115
|
def media_subtype
|
1134
|
-
warn("media_subtype is obsolete, use subtype instead.\n",
|
1116
|
+
warn("media_subtype is obsolete, use subtype instead.\n",
|
1117
|
+
uplevel: 1, category: :deprecated)
|
1135
1118
|
return subtype
|
1136
1119
|
end
|
1137
1120
|
end
|
1138
1121
|
|
1139
|
-
# === Obsolete
|
1140
|
-
# BodyTypeExtension is not used and will be removed in an upcoming release.
|
1141
|
-
#
|
1142
|
-
# >>>
|
1143
|
-
# BodyTypeExtension was (incorrectly) used for <tt>message/*</tt> parts
|
1144
|
-
# (besides <tt>message/rfc822</tt>, which correctly uses BodyTypeMessage).
|
1145
|
-
#
|
1146
|
-
# Net::IMAP now (correctly) parses all message types (other than
|
1147
|
-
# <tt>message/rfc822</tt> or <tt>message/global</tt>) as BodyTypeBasic.
|
1148
|
-
class BodyTypeExtension < Struct.new(:media_type, :subtype,
|
1149
|
-
:params, :content_id,
|
1150
|
-
:description, :encoding, :size)
|
1151
|
-
def multipart?
|
1152
|
-
return false
|
1153
|
-
end
|
1154
|
-
end
|
1155
|
-
|
1156
|
-
deprecate_constant :BodyTypeExtension
|
1157
|
-
|
1158
1122
|
end
|
1159
1123
|
end
|
@@ -13,17 +13,13 @@ module Net
|
|
13
13
|
|
14
14
|
attr_reader :config
|
15
15
|
|
16
|
-
#
|
17
|
-
#
|
18
|
-
# When +config+ is frozen or global, the parser #config inherits from it.
|
19
|
-
# Otherwise, +config+ will be used directly.
|
16
|
+
# :call-seq: Net::IMAP::ResponseParser.new -> Net::IMAP::ResponseParser
|
20
17
|
def initialize(config: Config.global)
|
21
18
|
@str = nil
|
22
19
|
@pos = nil
|
23
20
|
@lex_state = nil
|
24
21
|
@token = nil
|
25
22
|
@config = Config[config]
|
26
|
-
@config = @config.new if @config == Config.global || @config.frozen?
|
27
23
|
end
|
28
24
|
|
29
25
|
# :call-seq:
|
@@ -1321,31 +1317,19 @@ module Net
|
|
1321
1317
|
# header-fld-name = astring
|
1322
1318
|
#
|
1323
1319
|
# NOTE: Previously, Net::IMAP recreated the raw original source string.
|
1324
|
-
# Now, it
|
1325
|
-
#
|
1326
|
-
#
|
1327
|
-
# standard header field names are valid atoms:
|
1320
|
+
# Now, it returns the decoded astring value. Although this is technically
|
1321
|
+
# incompatible, it should almost never make a difference: all standard
|
1322
|
+
# header field names are valid atoms:
|
1328
1323
|
#
|
1329
1324
|
# https://www.iana.org/assignments/message-headers/message-headers.xhtml
|
1330
1325
|
#
|
1331
|
-
#
|
1332
|
-
# or more of the printable US-ASCII characters, except SP and colon. So
|
1333
|
-
# empty string isn't valid, and literals aren't needed and should not be
|
1334
|
-
# used. This is explicitly unchanged by [I18N-HDRS] (RFC6532).
|
1335
|
-
#
|
1336
|
-
# RFC5233:
|
1326
|
+
# See also RFC5233:
|
1337
1327
|
# optional-field = field-name ":" unstructured CRLF
|
1338
1328
|
# field-name = 1*ftext
|
1339
1329
|
# ftext = %d33-57 / ; Printable US-ASCII
|
1340
1330
|
# %d59-126 ; characters not including
|
1341
1331
|
# ; ":".
|
1342
|
-
|
1343
|
-
assert_no_lookahead
|
1344
|
-
start = @pos
|
1345
|
-
astring
|
1346
|
-
end_pos = @token ? @pos - 1 : @pos
|
1347
|
-
@str[start...end_pos]
|
1348
|
-
end
|
1332
|
+
alias header_fld_name astring
|
1349
1333
|
|
1350
1334
|
# mailbox-data = "FLAGS" SP flag-list / "LIST" SP mailbox-list /
|
1351
1335
|
# "LSUB" SP mailbox-list / "SEARCH" *(SP nz-number) /
|
@@ -1867,10 +1851,11 @@ module Net
|
|
1867
1851
|
#
|
1868
1852
|
# n.b, uniqueid ⊂ uid-set. To avoid inconsistent return types, we always
|
1869
1853
|
# match uid_set even if that returns a single-member array.
|
1854
|
+
#
|
1870
1855
|
def resp_code_apnd__data
|
1871
1856
|
validity = number; SP!
|
1872
1857
|
dst_uids = uid_set # uniqueid ⊂ uid-set
|
1873
|
-
|
1858
|
+
UIDPlusData.new(validity, nil, dst_uids)
|
1874
1859
|
end
|
1875
1860
|
|
1876
1861
|
# already matched: "COPYUID"
|
@@ -1880,25 +1865,7 @@ module Net
|
|
1880
1865
|
validity = number; SP!
|
1881
1866
|
src_uids = uid_set; SP!
|
1882
1867
|
dst_uids = uid_set
|
1883
|
-
|
1884
|
-
end
|
1885
|
-
|
1886
|
-
def AppendUID(...) DeprecatedUIDPlus(...) || AppendUIDData.new(...) end
|
1887
|
-
def CopyUID(...) DeprecatedUIDPlus(...) || CopyUIDData.new(...) end
|
1888
|
-
|
1889
|
-
# TODO: remove this code in the v0.6.0 release
|
1890
|
-
def DeprecatedUIDPlus(validity, src_uids = nil, dst_uids)
|
1891
|
-
return unless config.parser_use_deprecated_uidplus_data
|
1892
|
-
compact_uid_sets = [src_uids, dst_uids].compact
|
1893
|
-
count = compact_uid_sets.map { _1.count_with_duplicates }.max
|
1894
|
-
max = config.parser_max_deprecated_uidplus_data_size
|
1895
|
-
if count <= max
|
1896
|
-
src_uids &&= src_uids.each_ordered_number.to_a
|
1897
|
-
dst_uids = dst_uids.each_ordered_number.to_a
|
1898
|
-
UIDPlusData.new(validity, src_uids, dst_uids)
|
1899
|
-
elsif config.parser_use_deprecated_uidplus_data != :up_to_max_size
|
1900
|
-
parse_error("uid-set is too large: %d > %d", count, max)
|
1901
|
-
end
|
1868
|
+
UIDPlusData.new(validity, src_uids, dst_uids)
|
1902
1869
|
end
|
1903
1870
|
|
1904
1871
|
ADDRESS_REGEXP = /\G
|
@@ -2024,9 +1991,15 @@ module Net
|
|
2024
1991
|
# uniqueid = nz-number
|
2025
1992
|
# ; Strictly ascending
|
2026
1993
|
def uid_set
|
2027
|
-
|
2028
|
-
|
2029
|
-
|
1994
|
+
token = match(T_NUMBER, T_ATOM)
|
1995
|
+
case token.symbol
|
1996
|
+
when T_NUMBER then [Integer(token.value)]
|
1997
|
+
when T_ATOM
|
1998
|
+
token.value.split(",").flat_map {|range|
|
1999
|
+
range = range.split(":").map {|uniqueid| Integer(uniqueid) }
|
2000
|
+
range.size == 1 ? range : Range.new(range.min, range.max).to_a
|
2001
|
+
}
|
2002
|
+
end
|
2030
2003
|
end
|
2031
2004
|
|
2032
2005
|
def nil_atom
|