Skip to content

Commit b441c9c

Browse files
committed
Merge branch 'master' into dist/3.4/bookworm
2 parents 1da2ede + 5ea8ff1 commit b441c9c

File tree

87 files changed

+1266
-240
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

87 files changed

+1266
-240
lines changed
File renamed without changes.

.bundle/gems/net-imap-0.5.6/lib/net/imap.rb renamed to .bundle/gems/net-imap-0.5.8/lib/net/imap.rb

Lines changed: 218 additions & 47 deletions
Large diffs are not rendered by default.

.bundle/gems/net-imap-0.5.6/lib/net/imap/config.rb renamed to .bundle/gems/net-imap-0.5.8/lib/net/imap/config.rb

Lines changed: 101 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,25 @@ def self.default; @default end
131131
def self.global; @global if defined?(@global) end
132132

133133
# A hash of hard-coded configurations, indexed by version number or name.
134+
# Values can be accessed with any object that responds to +to_sym+ or
135+
# +to_r+/+to_f+ with a non-zero number.
136+
#
137+
# Config::[] gets named or numbered versions from this hash.
138+
#
139+
# For example:
140+
# Net::IMAP::Config.version_defaults[0.5] == Net::IMAP::Config[0.5]
141+
# Net::IMAP::Config[0.5] == Net::IMAP::Config[0.5r] # => true
142+
# Net::IMAP::Config["current"] == Net::IMAP::Config[:current] # => true
143+
# Net::IMAP::Config["0.5.6"] == Net::IMAP::Config[0.5r] # => true
134144
def self.version_defaults; @version_defaults end
135-
@version_defaults = {}
145+
@version_defaults = Hash.new {|h, k|
146+
# NOTE: String responds to both so the order is significant.
147+
# And ignore non-numeric conversion to zero, because: "wat!?".to_r == 0
148+
(h.fetch(k.to_r, nil) || h.fetch(k.to_f, nil) if k.is_a?(Numeric)) ||
149+
(h.fetch(k.to_sym, nil) if k.respond_to?(:to_sym)) ||
150+
(h.fetch(k.to_r, nil) if k.respond_to?(:to_r) && k.to_r != 0r) ||
151+
(h.fetch(k.to_f, nil) if k.respond_to?(:to_f) && k.to_f != 0.0)
152+
}
136153

137154
# :call-seq:
138155
# Net::IMAP::Config[number] -> versioned config
@@ -155,18 +172,17 @@ def self.[](config)
155172
elsif config.nil? && global.nil? then nil
156173
elsif config.respond_to?(:to_hash) then new(global, **config).freeze
157174
else
158-
version_defaults.fetch(config) do
175+
version_defaults[config] or
159176
case config
160177
when Numeric
161178
raise RangeError, "unknown config version: %p" % [config]
162-
when Symbol
179+
when String, Symbol
163180
raise KeyError, "unknown config name: %p" % [config]
164181
else
165182
raise TypeError, "no implicit conversion of %s to %s" % [
166183
config.class, Config
167184
]
168185
end
169-
end
170186
end
171187
end
172188

@@ -193,10 +209,13 @@ def self.[](config)
193209

194210
# Seconds to wait until a connection is opened.
195211
#
212+
# Applied separately for establishing TCP connection and starting a TLS
213+
# connection.
214+
#
196215
# If the IMAP object cannot open a connection within this time,
197216
# it raises a Net::OpenTimeout exception.
198217
#
199-
# See Net::IMAP.new.
218+
# See Net::IMAP.new and Net::IMAP#starttls.
200219
#
201220
# The default value is +30+ seconds.
202221
attr_accessor :open_timeout, type: Integer
@@ -245,10 +264,44 @@ def self.[](config)
245264
# present. When capabilities are unknown, Net::IMAP will automatically
246265
# send a +CAPABILITY+ command first before sending +LOGIN+.
247266
#
248-
attr_accessor :enforce_logindisabled, type: [
267+
attr_accessor :enforce_logindisabled, type: Enum[
249268
false, :when_capabilities_cached, true
250269
]
251270

271+
# The maximum allowed server response size. When +nil+, there is no limit
272+
# on response size.
273+
#
274+
# The default value (512 MiB, since +v0.5.7+) is <em>very high</em> and
275+
# unlikely to be reached. A _much_ lower value should be used with
276+
# untrusted servers (for example, when connecting to a user-provided
277+
# hostname). When using a lower limit, message bodies should be fetched
278+
# in chunks rather than all at once.
279+
#
280+
# <em>Please Note:</em> this only limits the size per response. It does
281+
# not prevent a flood of individual responses and it does not limit how
282+
# many unhandled responses may be stored on the responses hash. See
283+
# Net::IMAP@Unbounded+memory+use.
284+
#
285+
# Socket reads are limited to the maximum remaining bytes for the current
286+
# response: max_response_size minus the bytes that have already been read.
287+
# When the limit is reached, or reading a +literal+ _would_ go over the
288+
# limit, ResponseTooLargeError is raised and the connection is closed.
289+
#
290+
# Note that changes will not take effect immediately, because the receiver
291+
# thread may already be waiting for the next response using the previous
292+
# value. Net::IMAP#noop can force a response and enforce the new setting
293+
# immediately.
294+
#
295+
# ==== Versioned Defaults
296+
#
297+
# Net::IMAP#max_response_size <em>was added in +v0.2.5+ and +v0.3.9+ as an
298+
# attr_accessor, and in +v0.4.20+ and +v0.5.7+ as a delegator to this
299+
# config attribute.</em>
300+
#
301+
# * original: +nil+ <em>(no limit)</em>
302+
# * +0.5+: 512 MiB
303+
attr_accessor :max_response_size, type: Integer?
304+
252305
# Controls the behavior of Net::IMAP#responses when called without any
253306
# arguments (+type+ or +block+).
254307
#
@@ -275,7 +328,7 @@ def self.[](config)
275328
# Raise an ArgumentError with the deprecation warning.
276329
#
277330
# Note: #responses_without_args is an alias for #responses_without_block.
278-
attr_accessor :responses_without_block, type: [
331+
attr_accessor :responses_without_block, type: Enum[
279332
:silence_deprecation_warning, :warn, :frozen_dup, :raise,
280333
]
281334

@@ -320,7 +373,7 @@ def self.[](config)
320373
#
321374
# [+false+ <em>(planned default for +v0.6+)</em>]
322375
# ResponseParser _only_ uses AppendUIDData and CopyUIDData.
323-
attr_accessor :parser_use_deprecated_uidplus_data, type: [
376+
attr_accessor :parser_use_deprecated_uidplus_data, type: Enum[
324377
true, :up_to_max_size, false
325378
]
326379

@@ -427,6 +480,7 @@ def defaults_hash
427480
idle_response_timeout: 5,
428481
sasl_ir: true,
429482
enforce_logindisabled: true,
483+
max_response_size: 512 << 20, # 512 MiB
430484
responses_without_block: :warn,
431485
parser_use_deprecated_uidplus_data: :up_to_max_size,
432486
parser_max_deprecated_uidplus_data_size: 100,
@@ -435,36 +489,64 @@ def defaults_hash
435489
@global = default.new
436490

437491
version_defaults[:default] = Config[default.send(:defaults_hash)]
438-
version_defaults[:current] = Config[:default]
439492

440-
version_defaults[0] = Config[:current].dup.update(
493+
version_defaults[0r] = Config[:default].dup.update(
441494
sasl_ir: false,
442495
responses_without_block: :silence_deprecation_warning,
443496
enforce_logindisabled: false,
497+
max_response_size: nil,
444498
parser_use_deprecated_uidplus_data: true,
445499
parser_max_deprecated_uidplus_data_size: 10_000,
446500
).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]
501+
version_defaults[0.0r] = Config[0r]
502+
version_defaults[0.1r] = Config[0r]
503+
version_defaults[0.2r] = Config[0r]
504+
version_defaults[0.3r] = Config[0r]
451505

452-
version_defaults[0.4] = Config[0.3].dup.update(
506+
version_defaults[0.4r] = Config[0.3r].dup.update(
453507
sasl_ir: true,
454508
parser_max_deprecated_uidplus_data_size: 1000,
455509
).freeze
456510

457-
version_defaults[0.5] = Config[:current]
511+
version_defaults[0.5r] = Config[0.4r].dup.update(
512+
enforce_logindisabled: true,
513+
max_response_size: 512 << 20, # 512 MiB
514+
responses_without_block: :warn,
515+
parser_use_deprecated_uidplus_data: :up_to_max_size,
516+
parser_max_deprecated_uidplus_data_size: 100,
517+
).freeze
458518

459-
version_defaults[0.6] = Config[0.5].dup.update(
519+
version_defaults[0.6r] = Config[0.5r].dup.update(
460520
responses_without_block: :frozen_dup,
461521
parser_use_deprecated_uidplus_data: false,
462522
parser_max_deprecated_uidplus_data_size: 0,
463523
).freeze
464-
version_defaults[:next] = Config[0.6]
465-
version_defaults[:future] = Config[:next]
524+
525+
version_defaults[0.7r] = Config[0.6r].dup.update(
526+
).freeze
527+
528+
# Safe conversions one way only:
529+
# 0.6r.to_f == 0.6 # => true
530+
# 0.6 .to_r == 0.6r # => false
531+
version_defaults.to_a.each do |k, v|
532+
next unless k in Rational
533+
version_defaults[k.to_f] = v
534+
end
535+
536+
current = VERSION.to_r
537+
version_defaults[:original] = Config[0]
538+
version_defaults[:current] = Config[current]
539+
version_defaults[:next] = Config[current + 0.1r]
540+
version_defaults[:future] = Config[current + 0.2r]
466541

467542
version_defaults.freeze
543+
544+
if ($VERBOSE || $DEBUG) && self[:current].to_h != self[:default].to_h
545+
warn "Misconfigured Net::IMAP::Config[:current] => %p,\n" \
546+
" not equal to Net::IMAP::Config[:default] => %p" % [
547+
self[:current].to_h, self[:default].to_h
548+
]
549+
end
468550
end
469551
end
470552
end

.bundle/gems/net-imap-0.5.6/lib/net/imap/config/attr_type_coercion.rb renamed to .bundle/gems/net-imap-0.5.8/lib/net/imap/config/attr_type_coercion.rb

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ def attr_accessor(attr, type: nil)
1818
super(attr)
1919
AttrTypeCoercion.attr_accessor(attr, type: type)
2020
end
21+
22+
module_function def Integer? = NilOrInteger
2123
end
2224
private_constant :Macros
2325

@@ -26,34 +28,33 @@ def self.included(mod)
2628
end
2729
private_class_method :included
2830

29-
def self.attr_accessor(attr, type: nil)
30-
return unless type
31-
if :boolean == type then boolean attr
32-
elsif Integer == type then integer attr
33-
elsif Array === type then enum attr, type
34-
else raise ArgumentError, "unknown type coercion %p" % [type]
35-
end
31+
if defined?(Ractor.make_shareable)
32+
def self.safe(...) Ractor.make_shareable nil.instance_eval(...).freeze end
33+
else
34+
def self.safe(...) nil.instance_eval(...).freeze end
3635
end
36+
private_class_method :safe
3737

38-
def self.boolean(attr)
39-
define_method :"#{attr}=" do |val| super !!val end
40-
define_method :"#{attr}?" do send attr end
41-
end
38+
Types = Hash.new do |h, type| type => Proc | nil; safe{type} end
39+
Types[:boolean] = Boolean = safe{-> {!!_1}}
40+
Types[Integer] = safe{->{Integer(_1)}}
4241

43-
def self.integer(attr)
44-
define_method :"#{attr}=" do |val| super Integer val end
42+
def self.attr_accessor(attr, type: nil)
43+
type = Types[type] or return
44+
define_method :"#{attr}=" do |val| super type[val] end
45+
define_method :"#{attr}?" do send attr end if type == Boolean
4546
end
4647

47-
def self.enum(attr, enum)
48-
enum = enum.dup.freeze
48+
NilOrInteger = safe{->val { Integer val unless val.nil? }}
49+
50+
Enum = ->(*enum) {
51+
enum = safe{enum}
4952
expected = -"one of #{enum.map(&:inspect).join(", ")}"
50-
define_method :"#{attr}=" do |val|
51-
unless enum.include?(val)
52-
raise ArgumentError, "expected %s, got %p" % [expected, val]
53-
end
54-
super val
55-
end
56-
end
53+
safe{->val {
54+
return val if enum.include?(val)
55+
raise ArgumentError, "expected %s, got %p" % [expected, val]
56+
}}
57+
}
5758

5859
end
5960
end
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# frozen_string_literal: true
2+
3+
module Net
4+
class IMAP
5+
class ConnectionState < Net::IMAP::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

.bundle/gems/net-imap-0.5.6/lib/net/imap/errors.rb renamed to .bundle/gems/net-imap-0.5.8/lib/net/imap/errors.rb

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,39 @@ def initialize(msg = "Remote server has disabled the LOGIN command", ...)
1717
class DataFormatError < Error
1818
end
1919

20+
# Error raised when the socket cannot be read, due to a Config limit.
21+
class ResponseReadError < Error
22+
end
23+
24+
# Error raised when a response is larger than IMAP#max_response_size.
25+
class ResponseTooLargeError < ResponseReadError
26+
attr_reader :bytes_read, :literal_size
27+
attr_reader :max_response_size
28+
29+
def initialize(msg = nil, *args,
30+
bytes_read: nil,
31+
literal_size: nil,
32+
max_response_size: nil,
33+
**kwargs)
34+
@bytes_read = bytes_read
35+
@literal_size = literal_size
36+
@max_response_size = max_response_size
37+
msg ||= [
38+
"Response size", response_size_msg, "exceeds max_response_size",
39+
max_response_size && "(#{max_response_size}B)",
40+
].compact.join(" ")
41+
super(msg, *args, **kwargs)
42+
end
43+
44+
private
45+
46+
def response_size_msg
47+
if bytes_read && literal_size
48+
"(#{bytes_read}B read + #{literal_size}B literal)"
49+
end
50+
end
51+
end
52+
2053
# Error raised when a response from the server is non-parsable.
2154
class ResponseParseError < Error
2255
end

0 commit comments

Comments
 (0)