Skip to content

Commit 340d3e7

Browse files
committed
🔧 ResponseParser config is mutable and non-global
When ResponseParser was initialized without any explicit config, it used Config.global directly. This meant that changes to `parser.config` were also changes to the _global_ config! When ResponseParser is initialized with a config hash, that creates a frozen config object. This meant that changes to `parser.config` were impossible. So, when the given config is global or frozen, we create a new config and inherit from the given config. We want to continue using the given config as-is in other cases, so the client and its parser can share the same exact config.
1 parent adacca9 commit 340d3e7

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

lib/net/imap/response_parser.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,17 @@ class ResponseParser
1313

1414
attr_reader :config
1515

16-
# :call-seq: Net::IMAP::ResponseParser.new -> Net::IMAP::ResponseParser
16+
# Creates a new ResponseParser.
17+
#
18+
# When +config+ is frozen or global, the parser #config inherits from it.
19+
# Otherwise, +config+ will be used directly.
1720
def initialize(config: Config.global)
1821
@str = nil
1922
@pos = nil
2023
@lex_state = nil
2124
@token = nil
2225
@config = Config[config]
26+
@config = @config.new if @config == Config.global || @config.frozen?
2327
end
2428

2529
# :call-seq:

test/net/imap/test_imap_response_parser.rb

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,41 @@ def teardown
118118
# response data, should still use normal tests, below
119119
############################################################################
120120

121+
test "default config inherits from Config.global" do
122+
parser = Net::IMAP::ResponseParser.new
123+
refute parser.config.frozen?
124+
refute_equal Net::IMAP::Config.global, parser.config
125+
assert_same Net::IMAP::Config.global, parser.config.parent
126+
end
127+
128+
test "config can be passed in to #initialize" do
129+
config = Net::IMAP::Config.global.new
130+
parser = Net::IMAP::ResponseParser.new config: config
131+
assert_same config, parser.config
132+
end
133+
134+
test "passing in global config inherits from Config.global" do
135+
parser = Net::IMAP::ResponseParser.new config: Net::IMAP::Config.global
136+
refute parser.config.frozen?
137+
refute_equal Net::IMAP::Config.global, parser.config
138+
assert_same Net::IMAP::Config.global, parser.config.parent
139+
end
140+
141+
test "config will inherits from passed in frozen config" do
142+
parser = Net::IMAP::ResponseParser.new config: {debug: true}
143+
refute_equal Net::IMAP::Config.global, parser.config.parent
144+
refute parser.config.frozen?
145+
146+
assert parser.config.parent.frozen?
147+
assert parser.config.debug?
148+
assert parser.config.inherited?(:debug)
149+
150+
config = Net::IMAP::Config[debug: true]
151+
parser = Net::IMAP::ResponseParser.new(config:)
152+
refute_equal Net::IMAP::Config.global, parser.config.parent
153+
assert_same config, parser.config.parent
154+
end
155+
121156
# Strangly, there are no example responses for BINARY[section] in either
122157
# RFC3516 or RFC9051! The closest I found was RFC5259, and those examples
123158
# aren't FETCH responses.

0 commit comments

Comments
 (0)