net-imap 0.4.19 → 0.5.0
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.
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
|