net-imap 0.5.6 → 0.6.3
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.
- checksums.yaml +4 -4
- data/Gemfile +7 -4
- data/lib/net/imap/command_data.rb +0 -68
- data/lib/net/imap/config/attr_accessors.rb +8 -9
- data/lib/net/imap/config/attr_inheritance.rb +64 -1
- data/lib/net/imap/config/attr_type_coercion.rb +35 -22
- data/lib/net/imap/config/attr_version_defaults.rb +90 -0
- data/lib/net/imap/config.rb +265 -95
- data/lib/net/imap/connection_state.rb +48 -0
- data/lib/net/imap/data_encoding.rb +77 -28
- data/lib/net/imap/errors.rb +185 -0
- data/lib/net/imap/esearch_result.rb +48 -3
- data/lib/net/imap/flags.rb +1 -1
- data/lib/net/imap/response_data.rb +2 -4
- data/lib/net/imap/response_parser/parser_utils.rb +14 -23
- data/lib/net/imap/response_parser.rb +27 -17
- data/lib/net/imap/response_reader.rb +73 -0
- data/lib/net/imap/search_result.rb +8 -3
- data/lib/net/imap/sequence_set.rb +1126 -431
- data/lib/net/imap/uidplus_data.rb +2 -63
- data/lib/net/imap/vanished_data.rb +10 -1
- data/lib/net/imap.rb +292 -82
- data/net-imap.gemspec +1 -1
- data/rakelib/string_prep_tables_generator.rb +4 -2
- metadata +7 -5
- data/lib/net/imap/data_lite.rb +0 -226
data/lib/net/imap/config.rb
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require_relative "config/attr_accessors"
|
|
4
4
|
require_relative "config/attr_inheritance"
|
|
5
5
|
require_relative "config/attr_type_coercion"
|
|
6
|
+
require_relative "config/attr_version_defaults"
|
|
6
7
|
|
|
7
8
|
module Net
|
|
8
9
|
class IMAP
|
|
@@ -131,8 +132,17 @@ module Net
|
|
|
131
132
|
def self.global; @global if defined?(@global) end
|
|
132
133
|
|
|
133
134
|
# A hash of hard-coded configurations, indexed by version number or name.
|
|
134
|
-
|
|
135
|
-
|
|
135
|
+
# Values can be accessed with any object that responds to +to_sym+ or
|
|
136
|
+
# +to_r+/+to_f+ with a non-zero number.
|
|
137
|
+
#
|
|
138
|
+
# Config::[] gets named or numbered versions from this hash.
|
|
139
|
+
#
|
|
140
|
+
# For example:
|
|
141
|
+
# Net::IMAP::Config.version_defaults[0.5] == Net::IMAP::Config[0.5]
|
|
142
|
+
# Net::IMAP::Config[0.5] == Net::IMAP::Config[0.5r] # => true
|
|
143
|
+
# Net::IMAP::Config["current"] == Net::IMAP::Config[:current] # => true
|
|
144
|
+
# Net::IMAP::Config["0.5.6"] == Net::IMAP::Config[0.5r] # => true
|
|
145
|
+
def self.version_defaults; AttrVersionDefaults.version_defaults end
|
|
136
146
|
|
|
137
147
|
# :call-seq:
|
|
138
148
|
# Net::IMAP::Config[number] -> versioned config
|
|
@@ -155,24 +165,24 @@ module Net
|
|
|
155
165
|
elsif config.nil? && global.nil? then nil
|
|
156
166
|
elsif config.respond_to?(:to_hash) then new(global, **config).freeze
|
|
157
167
|
else
|
|
158
|
-
version_defaults
|
|
168
|
+
version_defaults[config] or
|
|
159
169
|
case config
|
|
160
170
|
when Numeric
|
|
161
171
|
raise RangeError, "unknown config version: %p" % [config]
|
|
162
|
-
when Symbol
|
|
172
|
+
when String, Symbol
|
|
163
173
|
raise KeyError, "unknown config name: %p" % [config]
|
|
164
174
|
else
|
|
165
175
|
raise TypeError, "no implicit conversion of %s to %s" % [
|
|
166
176
|
config.class, Config
|
|
167
177
|
]
|
|
168
178
|
end
|
|
169
|
-
end
|
|
170
179
|
end
|
|
171
180
|
end
|
|
172
181
|
|
|
173
182
|
include AttrAccessors
|
|
174
183
|
include AttrInheritance
|
|
175
184
|
include AttrTypeCoercion
|
|
185
|
+
extend AttrVersionDefaults
|
|
176
186
|
|
|
177
187
|
# The debug mode (boolean). The default value is +false+.
|
|
178
188
|
#
|
|
@@ -184,7 +194,7 @@ module Net
|
|
|
184
194
|
#
|
|
185
195
|
# *NOTE:* Versioned default configs inherit #debug from Config.global, and
|
|
186
196
|
# #load_defaults will not override #debug.
|
|
187
|
-
attr_accessor :debug, type: :boolean
|
|
197
|
+
attr_accessor :debug, type: :boolean, default: false
|
|
188
198
|
|
|
189
199
|
# method: debug?
|
|
190
200
|
# :call-seq: debug? -> boolean
|
|
@@ -193,13 +203,16 @@ module Net
|
|
|
193
203
|
|
|
194
204
|
# Seconds to wait until a connection is opened.
|
|
195
205
|
#
|
|
206
|
+
# Applied separately for establishing TCP connection and starting a TLS
|
|
207
|
+
# connection.
|
|
208
|
+
#
|
|
196
209
|
# If the IMAP object cannot open a connection within this time,
|
|
197
210
|
# it raises a Net::OpenTimeout exception.
|
|
198
211
|
#
|
|
199
|
-
# See Net::IMAP.new.
|
|
212
|
+
# See Net::IMAP.new and Net::IMAP#starttls.
|
|
200
213
|
#
|
|
201
214
|
# The default value is +30+ seconds.
|
|
202
|
-
attr_accessor :open_timeout, type: Integer
|
|
215
|
+
attr_accessor :open_timeout, type: Integer, default: 30
|
|
203
216
|
|
|
204
217
|
# Seconds to wait until an IDLE response is received, after
|
|
205
218
|
# the client asks to leave the IDLE state.
|
|
@@ -207,7 +220,7 @@ module Net
|
|
|
207
220
|
# See Net::IMAP#idle and Net::IMAP#idle_done.
|
|
208
221
|
#
|
|
209
222
|
# The default value is +5+ seconds.
|
|
210
|
-
attr_accessor :idle_response_timeout, type: Integer
|
|
223
|
+
attr_accessor :idle_response_timeout, type: Integer, default: 5
|
|
211
224
|
|
|
212
225
|
# Whether to use the +SASL-IR+ extension when the server and \SASL
|
|
213
226
|
# mechanism both support it. Can be overridden by the +sasl_ir+ keyword
|
|
@@ -221,9 +234,25 @@ module Net
|
|
|
221
234
|
# Do not use +SASL-IR+, even when it is supported by the server and the
|
|
222
235
|
# mechanism.
|
|
223
236
|
#
|
|
237
|
+
# [+:when_capabilities_cached+]
|
|
238
|
+
# Use +SASL-IR+ when Net::IMAP#capabilities_cached? is +true+ and it is
|
|
239
|
+
# supported by the server and the mechanism, but do not send a
|
|
240
|
+
# +CAPABILITY+ command to discover the server capabilities.
|
|
241
|
+
#
|
|
242
|
+
# <em>(+:when_capabilities_cached+ option was added by +v0.6.0+)</em>
|
|
243
|
+
#
|
|
224
244
|
# [+true+ <em>(default since +v0.4+)</em>]
|
|
225
245
|
# Use +SASL-IR+ when it is supported by the server and the mechanism.
|
|
226
|
-
attr_accessor :sasl_ir, type:
|
|
246
|
+
attr_accessor :sasl_ir, type: Enum[
|
|
247
|
+
false, :when_capabilities_cached, true
|
|
248
|
+
], defaults: {
|
|
249
|
+
0.0r => false,
|
|
250
|
+
0.4r => true,
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
# :stopdoc:
|
|
254
|
+
alias sasl_ir? sasl_ir
|
|
255
|
+
# :startdoc:
|
|
227
256
|
|
|
228
257
|
# Controls the behavior of Net::IMAP#login when the +LOGINDISABLED+
|
|
229
258
|
# capability is present. When enforced, Net::IMAP will raise a
|
|
@@ -245,9 +274,49 @@ module Net
|
|
|
245
274
|
# present. When capabilities are unknown, Net::IMAP will automatically
|
|
246
275
|
# send a +CAPABILITY+ command first before sending +LOGIN+.
|
|
247
276
|
#
|
|
248
|
-
attr_accessor :enforce_logindisabled, type: [
|
|
277
|
+
attr_accessor :enforce_logindisabled, type: Enum[
|
|
249
278
|
false, :when_capabilities_cached, true
|
|
250
|
-
]
|
|
279
|
+
], defaults: {
|
|
280
|
+
0.0r => false,
|
|
281
|
+
0.5r => true,
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
# The maximum allowed server response size. When +nil+, there is no limit
|
|
285
|
+
# on response size.
|
|
286
|
+
#
|
|
287
|
+
# The default value (512 MiB, since +v0.5.7+) is <em>very high</em> and
|
|
288
|
+
# unlikely to be reached. A _much_ lower value should be used with
|
|
289
|
+
# untrusted servers (for example, when connecting to a user-provided
|
|
290
|
+
# hostname). When using a lower limit, message bodies should be fetched
|
|
291
|
+
# in chunks rather than all at once.
|
|
292
|
+
#
|
|
293
|
+
# <em>Please Note:</em> this only limits the size per response. It does
|
|
294
|
+
# not prevent a flood of individual responses and it does not limit how
|
|
295
|
+
# many unhandled responses may be stored on the responses hash. See
|
|
296
|
+
# Net::IMAP@Unbounded+memory+use.
|
|
297
|
+
#
|
|
298
|
+
# Socket reads are limited to the maximum remaining bytes for the current
|
|
299
|
+
# response: max_response_size minus the bytes that have already been read.
|
|
300
|
+
# When the limit is reached, or reading a +literal+ _would_ go over the
|
|
301
|
+
# limit, ResponseTooLargeError is raised and the connection is closed.
|
|
302
|
+
#
|
|
303
|
+
# Note that changes will not take effect immediately, because the receiver
|
|
304
|
+
# thread may already be waiting for the next response using the previous
|
|
305
|
+
# value. Net::IMAP#noop can force a response and enforce the new setting
|
|
306
|
+
# immediately.
|
|
307
|
+
#
|
|
308
|
+
# ==== Versioned Defaults
|
|
309
|
+
#
|
|
310
|
+
# Net::IMAP#max_response_size <em>was added in +v0.2.5+ and +v0.3.9+ as an
|
|
311
|
+
# attr_accessor, and in +v0.4.20+ and +v0.5.7+ as a delegator to this
|
|
312
|
+
# config attribute.</em>
|
|
313
|
+
#
|
|
314
|
+
# * original: +nil+ <em>(no limit)</em>
|
|
315
|
+
# * +0.5+: 512 MiB
|
|
316
|
+
attr_accessor :max_response_size, type: Integer?, defaults: {
|
|
317
|
+
0.0r => nil,
|
|
318
|
+
0.5r => 512 << 20, # 512 MiB
|
|
319
|
+
}
|
|
251
320
|
|
|
252
321
|
# Controls the behavior of Net::IMAP#responses when called without any
|
|
253
322
|
# arguments (+type+ or +block+).
|
|
@@ -275,9 +344,13 @@ module Net
|
|
|
275
344
|
# Raise an ArgumentError with the deprecation warning.
|
|
276
345
|
#
|
|
277
346
|
# Note: #responses_without_args is an alias for #responses_without_block.
|
|
278
|
-
attr_accessor :responses_without_block, type: [
|
|
347
|
+
attr_accessor :responses_without_block, type: Enum[
|
|
279
348
|
:silence_deprecation_warning, :warn, :frozen_dup, :raise,
|
|
280
|
-
]
|
|
349
|
+
], defaults: {
|
|
350
|
+
0.0r => :silence_deprecation_warning,
|
|
351
|
+
0.5r => :warn,
|
|
352
|
+
0.6r => :frozen_dup,
|
|
353
|
+
}
|
|
281
354
|
|
|
282
355
|
alias responses_without_args responses_without_block # :nodoc:
|
|
283
356
|
alias responses_without_args= responses_without_block= # :nodoc:
|
|
@@ -287,66 +360,69 @@ module Net
|
|
|
287
360
|
#
|
|
288
361
|
# Alias for responses_without_block
|
|
289
362
|
|
|
290
|
-
#
|
|
291
|
-
#
|
|
292
|
-
#
|
|
363
|
+
# **NOTE:** <em>+UIDPlusData+ has been removed since +v0.6.0+, and this
|
|
364
|
+
# config option only affects deprecation warnings.
|
|
365
|
+
# This config option will be **removed** in +v0.7.0+.</em>
|
|
293
366
|
#
|
|
294
|
-
#
|
|
295
|
-
#
|
|
296
|
-
#
|
|
297
|
-
# vulnerability. Otherwise, parser_max_deprecated_uidplus_data_size
|
|
298
|
-
# mitigates this vulnerability.
|
|
367
|
+
# ResponseParser always returns CopyUIDData for +COPYUID+ response codes,
|
|
368
|
+
# and AppendUIDData for +APPENDUID+ response codes. Previously, this
|
|
369
|
+
# option determined when UIDPlusData would be returned instead.
|
|
299
370
|
#
|
|
300
|
-
#
|
|
301
|
-
# UIDPlusData. Most applications should be able to upgrade with little
|
|
302
|
-
# or no changes.
|
|
371
|
+
# Parser support for +UIDPLUS+ added in +v0.3.2+.
|
|
303
372
|
#
|
|
304
|
-
#
|
|
373
|
+
# Config option added in +v0.4.19+ and +v0.5.6+.
|
|
305
374
|
#
|
|
306
|
-
# <em>
|
|
375
|
+
# <em>UIDPlusData removed in +v0.6.0+.</em>
|
|
307
376
|
#
|
|
308
|
-
#
|
|
309
|
-
# be ignored.</em>
|
|
310
|
-
#
|
|
311
|
-
# ==== Valid options
|
|
377
|
+
# ==== Options
|
|
312
378
|
#
|
|
313
379
|
# [+true+ <em>(original default)</em>]
|
|
314
|
-
#
|
|
380
|
+
# <em>Since v0.6.0:</em>
|
|
381
|
+
# Prints a deprecation warning when parsing +COPYUID+ or +APPENDUID+.
|
|
315
382
|
#
|
|
316
383
|
# [+:up_to_max_size+ <em>(default since +v0.5.6+)</em>]
|
|
317
|
-
#
|
|
318
|
-
#
|
|
319
|
-
# ResponseParser uses AppendUIDData or CopyUIDData.
|
|
384
|
+
# <em>Since v0.6.0:</em>
|
|
385
|
+
# Prints a deprecation warning when parsing +COPYUID+ or +APPENDUID+.
|
|
320
386
|
#
|
|
321
|
-
# [+false+ <em>(
|
|
322
|
-
#
|
|
323
|
-
attr_accessor :parser_use_deprecated_uidplus_data, type: [
|
|
387
|
+
# [+false+ <em>(default since +v0.6.0+)</em>]
|
|
388
|
+
# This is the only supported option <em>(since v0.6.0)</em>.
|
|
389
|
+
attr_accessor :parser_use_deprecated_uidplus_data, type: Enum[
|
|
324
390
|
true, :up_to_max_size, false
|
|
325
|
-
]
|
|
391
|
+
], defaults: {
|
|
392
|
+
0.0r => true,
|
|
393
|
+
0.5r => :up_to_max_size,
|
|
394
|
+
0.6r => false,
|
|
395
|
+
}
|
|
326
396
|
|
|
327
|
-
#
|
|
328
|
-
#
|
|
329
|
-
#
|
|
397
|
+
# **NOTE:** <em>+UIDPlusData+ has been removed since +v0.6.0+, and this
|
|
398
|
+
# config option is ignored.
|
|
399
|
+
# This config option will be **removed** in +v0.7.0+.</em>
|
|
330
400
|
#
|
|
331
|
-
#
|
|
401
|
+
# ResponseParser always returns CopyUIDData for +COPYUID+ response codes,
|
|
402
|
+
# and AppendUIDData for +APPENDUID+ response codes. Previously, this
|
|
403
|
+
# option determined when UIDPlusData would be returned instead.
|
|
332
404
|
#
|
|
333
|
-
#
|
|
334
|
-
# +v0.3.8+, +v0.4.19+, and +v0.5.6+.</em>
|
|
405
|
+
# Parser support for +UIDPLUS+ added in +v0.3.2+.
|
|
335
406
|
#
|
|
336
|
-
#
|
|
407
|
+
# Support for limiting UIDPlusData to a maximum size was added in
|
|
408
|
+
# +v0.3.8+, +v0.4.19+, and +v0.5.6+.
|
|
337
409
|
#
|
|
338
|
-
#
|
|
410
|
+
# <em>UIDPlusData was removed in +v0.6.0+.</em>
|
|
339
411
|
#
|
|
340
|
-
#
|
|
341
|
-
# memory exhaustion, the versioned default (used by #load_defaults) also
|
|
342
|
-
# applies to versions without the feature.
|
|
412
|
+
# ==== Versioned Defaults
|
|
343
413
|
#
|
|
344
414
|
# * +0.3+ and prior: <tt>10,000</tt>
|
|
345
415
|
# * +0.4+: <tt>1,000</tt>
|
|
346
416
|
# * +0.5+: <tt>100</tt>
|
|
347
417
|
# * +0.6+: <tt>0</tt>
|
|
348
418
|
#
|
|
349
|
-
attr_accessor :parser_max_deprecated_uidplus_data_size, type: Integer
|
|
419
|
+
attr_accessor :parser_max_deprecated_uidplus_data_size, type: Integer,
|
|
420
|
+
defaults: {
|
|
421
|
+
0.0r => 10_000,
|
|
422
|
+
0.4r => 1_000,
|
|
423
|
+
0.5r => 100,
|
|
424
|
+
0.6r => 0,
|
|
425
|
+
}
|
|
350
426
|
|
|
351
427
|
# Creates a new config object and initialize its attribute with +attrs+.
|
|
352
428
|
#
|
|
@@ -415,56 +491,150 @@ module Net
|
|
|
415
491
|
# Returns all config attributes in a hash.
|
|
416
492
|
def to_h; data.members.to_h { [_1, send(_1)] } end
|
|
417
493
|
|
|
494
|
+
# Returns a string representation of overriden config attributes and the
|
|
495
|
+
# inheritance chain.
|
|
496
|
+
#
|
|
497
|
+
# Attributes overridden by ancestors are also inspected, recursively.
|
|
498
|
+
# Attributes that are inherited from default configs are not shown (see
|
|
499
|
+
# Config@Versioned+defaults and Config@Named+defaults).
|
|
500
|
+
#
|
|
501
|
+
# # (Line breaks have been added to the example output for legibility.)
|
|
502
|
+
#
|
|
503
|
+
# Net::IMAP::Config.new(0.4)
|
|
504
|
+
# .new(open_timeout: 10, enforce_logindisabled: true)
|
|
505
|
+
# .inspect
|
|
506
|
+
# #=> "#<Net::IMAP::Config:0x0000745871125410 open_timeout=10 enforce_logindisabled=true
|
|
507
|
+
# # inherits from Net::IMAP::Config[0.4]
|
|
508
|
+
# # inherits from Net::IMAP::Config.global
|
|
509
|
+
# # inherits from Net::IMAP::Config.default>"
|
|
510
|
+
#
|
|
511
|
+
# Non-default attributes are listed after the ancestor config from which
|
|
512
|
+
# they are inherited.
|
|
513
|
+
#
|
|
514
|
+
# # (Line breaks have been added to the example output for legibility.)
|
|
515
|
+
#
|
|
516
|
+
# config = Net::IMAP::Config.global
|
|
517
|
+
# .new(open_timeout: 10, idle_response_timeout: 2)
|
|
518
|
+
# .new(enforce_logindisabled: :when_capabilities_cached, sasl_ir: false)
|
|
519
|
+
# config.inspect
|
|
520
|
+
# #=> "#<Net::IMAP::Config:0x00007ce2a1e20e40 sasl_ir=false enforce_logindisabled=:when_capabilities_cached
|
|
521
|
+
# # inherits from Net::IMAP::Config:0x00007ce2a1e20f80 open_timeout=10 idle_response_timeout=2
|
|
522
|
+
# # inherits from Net::IMAP::Config.global
|
|
523
|
+
# # inherits from Net::IMAP::Config.default>"
|
|
524
|
+
#
|
|
525
|
+
# Net::IMAP.debug = true
|
|
526
|
+
# config.inspect
|
|
527
|
+
# #=> "#<Net::IMAP::Config:0x00007ce2a1e20e40 sasl_ir=false enforce_logindisabled=:when_capabilities_cached
|
|
528
|
+
# # inherits from Net::IMAP::Config:0x00007ce2a1e20f80 open_timeout=10 idle_response_timeout=2
|
|
529
|
+
# # inherits from Net::IMAP::Config.global debug=true
|
|
530
|
+
# # inherits from Net::IMAP::Config.default>"
|
|
531
|
+
#
|
|
532
|
+
# Use +pp+ (see #pretty_print) to inspect _all_ config attributes,
|
|
533
|
+
# including default values.
|
|
534
|
+
#
|
|
535
|
+
# Use #to_h to inspect all config attributes ignoring inheritance.
|
|
536
|
+
def inspect;
|
|
537
|
+
"#<#{inspect_recursive}>"
|
|
538
|
+
end
|
|
539
|
+
alias to_s inspect
|
|
540
|
+
|
|
541
|
+
# Used by PP[https://docs.ruby-lang.org/en/master/PP.html] to create a
|
|
542
|
+
# string representation of all config attributes and the inheritance
|
|
543
|
+
# chain. Inherited attributes are listed with the ancestor config from
|
|
544
|
+
# which they are inherited.
|
|
545
|
+
#
|
|
546
|
+
# pp Config.new[0.4].new(open_timeout: 10, idle_response_timeout: 10)
|
|
547
|
+
# # #<Net::IMAP::Config:0x0000745871125410
|
|
548
|
+
# # open_timeout=10
|
|
549
|
+
# # idle_response_timeout=10
|
|
550
|
+
# # inherits from Net::IMAP::Config[0.4]
|
|
551
|
+
# # responses_without_block=:silence_deprecation_warning
|
|
552
|
+
# # max_response_size=nil
|
|
553
|
+
# # sasl_ir=true
|
|
554
|
+
# # enforce_logindisabled=false
|
|
555
|
+
# # parser_use_deprecated_uidplus_data=true
|
|
556
|
+
# # parser_max_deprecated_uidplus_data_size=1000
|
|
557
|
+
# # inherits from Net::IMAP::Config.global
|
|
558
|
+
# # inherits from Net::IMAP::Config.default
|
|
559
|
+
# # debug=false>
|
|
560
|
+
#
|
|
561
|
+
# Related: #inspect, #to_h.
|
|
562
|
+
def pretty_print(pp)
|
|
563
|
+
pp.group(2, "#<", ">") do
|
|
564
|
+
pretty_print_recursive(pp)
|
|
565
|
+
end
|
|
566
|
+
end
|
|
567
|
+
|
|
568
|
+
# :stopdoc:
|
|
569
|
+
|
|
418
570
|
protected
|
|
419
571
|
|
|
572
|
+
def named_default?
|
|
573
|
+
equal?(Config.default) ||
|
|
574
|
+
AttrVersionDefaults::VERSIONS.any? { equal? Config[_1] }
|
|
575
|
+
end
|
|
576
|
+
|
|
577
|
+
def name
|
|
578
|
+
if equal? Config.default then "#{Config}.default"
|
|
579
|
+
elsif equal? Config.global then "#{Config}.global"
|
|
580
|
+
elsif equal? Config[0.0r] then "#{Config}[:original]"
|
|
581
|
+
elsif (v = AttrVersionDefaults::VERSIONS.find { equal? Config[_1] })
|
|
582
|
+
"%s[%0.1f]" % [Config, v]
|
|
583
|
+
else
|
|
584
|
+
Kernel.instance_method(:to_s).bind_call(self).delete("<#>")
|
|
585
|
+
end
|
|
586
|
+
end
|
|
587
|
+
|
|
588
|
+
def inspect_recursive(attrs = AttrAccessors.struct.members)
|
|
589
|
+
strings = [name]
|
|
590
|
+
assigned = assigned_attrs_hash(attrs)
|
|
591
|
+
strings.concat assigned.map { "%s=%p" % _1 }
|
|
592
|
+
if parent
|
|
593
|
+
if parent.equal?(Config.default)
|
|
594
|
+
inherited_overrides = []
|
|
595
|
+
elsif parent
|
|
596
|
+
inherited_overrides = attrs - assigned.keys
|
|
597
|
+
inherited_overrides &= DEFAULT_TO_INHERIT if parent.named_default?
|
|
598
|
+
end
|
|
599
|
+
strings << "inherits from #{parent.inspect_recursive(inherited_overrides)}"
|
|
600
|
+
end
|
|
601
|
+
strings.join " "
|
|
602
|
+
end
|
|
603
|
+
|
|
604
|
+
def pretty_print_recursive(pp, attrs = AttrAccessors.struct.members)
|
|
605
|
+
pp.text name
|
|
606
|
+
assigned = assigned_attrs_hash(attrs)
|
|
607
|
+
pp.breakable
|
|
608
|
+
pp.seplist(assigned, ->{pp.breakable}) do |key, val|
|
|
609
|
+
pp.text key.to_s
|
|
610
|
+
pp.text "="
|
|
611
|
+
pp.pp val
|
|
612
|
+
end
|
|
613
|
+
if parent
|
|
614
|
+
pp.breakable if assigned.any?
|
|
615
|
+
pp.nest(2) do
|
|
616
|
+
pp.text "inherits from "
|
|
617
|
+
parent.pretty_print_recursive(pp, attrs - assigned.keys)
|
|
618
|
+
end
|
|
619
|
+
elsif assigned.empty?
|
|
620
|
+
pp.text "(overridden)"
|
|
621
|
+
end
|
|
622
|
+
end
|
|
623
|
+
|
|
624
|
+
def assigned_attrs_hash(attrs)
|
|
625
|
+
own_attrs = attrs.reject { inherited?(_1) }
|
|
626
|
+
own_attrs.to_h { [_1, data[_1]] }
|
|
627
|
+
end
|
|
628
|
+
|
|
420
629
|
def defaults_hash
|
|
421
630
|
to_h.reject {|k,v| DEFAULT_TO_INHERIT.include?(k) }
|
|
422
631
|
end
|
|
423
632
|
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
enforce_logindisabled: true,
|
|
430
|
-
responses_without_block: :warn,
|
|
431
|
-
parser_use_deprecated_uidplus_data: :up_to_max_size,
|
|
432
|
-
parser_max_deprecated_uidplus_data_size: 100,
|
|
433
|
-
).freeze
|
|
434
|
-
|
|
435
|
-
@global = default.new
|
|
436
|
-
|
|
437
|
-
version_defaults[:default] = Config[default.send(:defaults_hash)]
|
|
438
|
-
version_defaults[:current] = Config[:default]
|
|
439
|
-
|
|
440
|
-
version_defaults[0] = Config[:current].dup.update(
|
|
441
|
-
sasl_ir: false,
|
|
442
|
-
responses_without_block: :silence_deprecation_warning,
|
|
443
|
-
enforce_logindisabled: false,
|
|
444
|
-
parser_use_deprecated_uidplus_data: true,
|
|
445
|
-
parser_max_deprecated_uidplus_data_size: 10_000,
|
|
446
|
-
).freeze
|
|
447
|
-
version_defaults[0.0] = Config[0]
|
|
448
|
-
version_defaults[0.1] = Config[0]
|
|
449
|
-
version_defaults[0.2] = Config[0]
|
|
450
|
-
version_defaults[0.3] = Config[0]
|
|
451
|
-
|
|
452
|
-
version_defaults[0.4] = Config[0.3].dup.update(
|
|
453
|
-
sasl_ir: true,
|
|
454
|
-
parser_max_deprecated_uidplus_data_size: 1000,
|
|
455
|
-
).freeze
|
|
456
|
-
|
|
457
|
-
version_defaults[0.5] = Config[:current]
|
|
458
|
-
|
|
459
|
-
version_defaults[0.6] = Config[0.5].dup.update(
|
|
460
|
-
responses_without_block: :frozen_dup,
|
|
461
|
-
parser_use_deprecated_uidplus_data: false,
|
|
462
|
-
parser_max_deprecated_uidplus_data_size: 0,
|
|
463
|
-
).freeze
|
|
464
|
-
version_defaults[:next] = Config[0.6]
|
|
465
|
-
version_defaults[:future] = Config[:next]
|
|
466
|
-
|
|
467
|
-
version_defaults.freeze
|
|
633
|
+
Struct = AttrAccessors.struct
|
|
634
|
+
@default = AttrVersionDefaults.compile_default!
|
|
635
|
+
@global = default.new
|
|
636
|
+
AttrVersionDefaults.compile_version_defaults!
|
|
637
|
+
|
|
468
638
|
end
|
|
469
639
|
end
|
|
470
640
|
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Net
|
|
4
|
+
class IMAP
|
|
5
|
+
class ConnectionState < Data # :nodoc:
|
|
6
|
+
def self.define(symbol, *attrs)
|
|
7
|
+
symbol => Symbol
|
|
8
|
+
state = super(*attrs)
|
|
9
|
+
state.const_set :NAME, symbol
|
|
10
|
+
state
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def symbol; self.class::NAME end
|
|
14
|
+
def name; self.class::NAME.name end
|
|
15
|
+
alias to_sym symbol
|
|
16
|
+
|
|
17
|
+
def deconstruct; [symbol, *super] end
|
|
18
|
+
|
|
19
|
+
def deconstruct_keys(names)
|
|
20
|
+
hash = super
|
|
21
|
+
hash[:symbol] = symbol if names.nil? || names.include?(:symbol)
|
|
22
|
+
hash[:name] = name if names.nil? || names.include?(:name)
|
|
23
|
+
hash
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def to_h(&block)
|
|
27
|
+
hash = deconstruct_keys(nil)
|
|
28
|
+
block ? hash.to_h(&block) : hash
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def not_authenticated?; to_sym == :not_authenticated end
|
|
32
|
+
def authenticated?; to_sym == :authenticated end
|
|
33
|
+
def selected?; to_sym == :selected end
|
|
34
|
+
def logout?; to_sym == :logout end
|
|
35
|
+
|
|
36
|
+
NotAuthenticated = define(:not_authenticated)
|
|
37
|
+
Authenticated = define(:authenticated)
|
|
38
|
+
Selected = define(:selected)
|
|
39
|
+
Logout = define(:logout)
|
|
40
|
+
|
|
41
|
+
class << self
|
|
42
|
+
undef :define
|
|
43
|
+
end
|
|
44
|
+
freeze
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -155,57 +155,106 @@ module Net
|
|
|
155
155
|
|
|
156
156
|
# Common validators of number and nz_number types
|
|
157
157
|
module NumValidator # :nodoc
|
|
158
|
+
NUMBER_RE = /\A(?:0|[1-9]\d*)\z/
|
|
158
159
|
module_function
|
|
159
160
|
|
|
160
|
-
# Check is
|
|
161
|
+
# Check if argument is a valid 'number' according to RFC 3501
|
|
162
|
+
# number = 1*DIGIT
|
|
163
|
+
# ; Unsigned 32-bit integer
|
|
164
|
+
# ; (0 <= n < 4,294,967,296)
|
|
161
165
|
def valid_number?(num)
|
|
162
|
-
|
|
163
|
-
# number = 1*DIGIT
|
|
164
|
-
# ; Unsigned 32-bit integer
|
|
165
|
-
# ; (0 <= n < 4,294,967,296)
|
|
166
|
-
num >= 0 && num < 4294967296
|
|
166
|
+
0 <= num && num <= 0xffff_ffff
|
|
167
167
|
end
|
|
168
168
|
|
|
169
|
-
# Check is
|
|
169
|
+
# Check if argument is a valid 'nz-number' according to RFC 3501
|
|
170
|
+
# nz-number = digit-nz *DIGIT
|
|
171
|
+
# ; Non-zero unsigned 32-bit integer
|
|
172
|
+
# ; (0 < n < 4,294,967,296)
|
|
170
173
|
def valid_nz_number?(num)
|
|
171
|
-
|
|
172
|
-
# nz-number = digit-nz *DIGIT
|
|
173
|
-
# ; Non-zero unsigned 32-bit integer
|
|
174
|
-
# ; (0 < n < 4,294,967,296)
|
|
175
|
-
num != 0 && valid_number?(num)
|
|
174
|
+
0 < num && num <= 0xffff_ffff
|
|
176
175
|
end
|
|
177
176
|
|
|
178
|
-
# Check is
|
|
177
|
+
# Check if argument is a valid 'mod-sequence-value' according to RFC 4551
|
|
178
|
+
# mod-sequence-value = 1*DIGIT
|
|
179
|
+
# ; Positive unsigned 64-bit integer
|
|
180
|
+
# ; (mod-sequence)
|
|
181
|
+
# ; (1 <= n < 18,446,744,073,709,551,615)
|
|
179
182
|
def valid_mod_sequence_value?(num)
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
183
|
+
1 <= num && num < 0xffff_ffff_ffff_ffff
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
# Check if argument is a valid 'mod-sequence-valzer' according to RFC 4551
|
|
187
|
+
# mod-sequence-valzer = "0" / mod-sequence-value
|
|
188
|
+
def valid_mod_sequence_valzer?(num)
|
|
189
|
+
0 <= num && num < 0xffff_ffff_ffff_ffff
|
|
185
190
|
end
|
|
186
191
|
|
|
187
192
|
# Ensure argument is 'number' or raise DataFormatError
|
|
188
193
|
def ensure_number(num)
|
|
189
194
|
return num if valid_number?(num)
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
raise DataFormatError, msg
|
|
195
|
+
raise DataFormatError,
|
|
196
|
+
"number must be unsigned 32-bit integer: #{num}"
|
|
193
197
|
end
|
|
194
198
|
|
|
195
|
-
# Ensure argument is '
|
|
199
|
+
# Ensure argument is 'nz-number' or raise DataFormatError
|
|
196
200
|
def ensure_nz_number(num)
|
|
197
201
|
return num if valid_nz_number?(num)
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
raise DataFormatError, msg
|
|
202
|
+
raise DataFormatError,
|
|
203
|
+
"nz-number must be non-zero unsigned 32-bit integer: #{num}"
|
|
201
204
|
end
|
|
202
205
|
|
|
203
|
-
# Ensure argument is '
|
|
206
|
+
# Ensure argument is 'mod-sequence-value' or raise DataFormatError
|
|
204
207
|
def ensure_mod_sequence_value(num)
|
|
205
208
|
return num if valid_mod_sequence_value?(num)
|
|
209
|
+
raise DataFormatError,
|
|
210
|
+
"mod-sequence-value must be non-zero unsigned 64-bit integer: #{num}"
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
# Ensure argument is 'mod-sequence-valzer' or raise DataFormatError
|
|
214
|
+
def ensure_mod_sequence_valzer(num)
|
|
215
|
+
return num if valid_mod_sequence_valzer?(num)
|
|
216
|
+
raise DataFormatError,
|
|
217
|
+
"mod-sequence-valzer must be unsigned 64-bit integer: #{num}"
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
# Like #ensure_number, but usable with numeric String input.
|
|
221
|
+
def coerce_number(num)
|
|
222
|
+
case num
|
|
223
|
+
when Integer then ensure_number num
|
|
224
|
+
when NUMBER_RE then ensure_number Integer num
|
|
225
|
+
else
|
|
226
|
+
raise DataFormatError, "%p is not a valid number" % [num]
|
|
227
|
+
end
|
|
228
|
+
end
|
|
206
229
|
|
|
207
|
-
|
|
208
|
-
|
|
230
|
+
# Like #ensure_nz_number, but usable with numeric String input.
|
|
231
|
+
def coerce_nz_number(num)
|
|
232
|
+
case num
|
|
233
|
+
when Integer then ensure_nz_number num
|
|
234
|
+
when NUMBER_RE then ensure_nz_number Integer num
|
|
235
|
+
else
|
|
236
|
+
raise DataFormatError, "%p is not a valid nz-number" % [num]
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
# Like #ensure_mod_sequence_value, but usable with numeric String input.
|
|
241
|
+
def coerce_mod_sequence_value(num)
|
|
242
|
+
case num
|
|
243
|
+
when Integer then ensure_mod_sequence_value num
|
|
244
|
+
when NUMBER_RE then ensure_mod_sequence_value Integer num
|
|
245
|
+
else
|
|
246
|
+
raise DataFormatError, "%p is not a valid mod-sequence-value" % [num]
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
# Like #ensure_mod_sequence_valzer, but usable with numeric String input.
|
|
251
|
+
def coerce_mod_sequence_valzer(num)
|
|
252
|
+
case num
|
|
253
|
+
when Integer then ensure_mod_sequence_valzer num
|
|
254
|
+
when NUMBER_RE then ensure_mod_sequence_valzer Integer num
|
|
255
|
+
else
|
|
256
|
+
raise DataFormatError, "%p is not a valid mod-sequence-valzer" % [num]
|
|
257
|
+
end
|
|
209
258
|
end
|
|
210
259
|
|
|
211
260
|
end
|