Skip to content

Commit 389223d

Browse files
committed
🐛 Fix #responses() freezing internal arrays
Now that `:frozen_dup` is the default behavior for `#responses` when it's called without any arguments, a critical bug has become apparent: it was not freezing the internal responses arrays directly, rather than copies of them. Freezing these arrays will, of course, lead to further issues. Ideally, code should be updated to use one of the other forms of `#responses`, since this form is less efficient and also (intentionally) incompatibile with old code that expects it to return mutable arrays. But this is still a major bug. Fixes #581, reported by @yurikoval.
1 parent 931c094 commit 389223d

File tree

2 files changed

+6
-2
lines changed

2 files changed

+6
-2
lines changed

lib/net/imap.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3233,7 +3233,7 @@ def responses(type = nil)
32333233
warn(RESPONSES_DEPRECATION_MSG, uplevel: 1, category: :deprecated)
32343234
when :frozen_dup
32353235
synchronize {
3236-
responses = @responses.transform_values(&:freeze)
3236+
responses = @responses.transform_values { _1.dup.freeze }
32373237
responses.default_proc = nil
32383238
responses.default = [].freeze
32393239
return responses.freeze

test/net/imap/test_imap_responses.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,13 +151,17 @@ def assert_responses_warn
151151
assert_equal [], imap.responses["FAKE"]
152152
end
153153
assert_empty stderr
154-
# opt-in to future behavior
154+
# default behavior since 0.6.0
155155
imap.config.responses_without_block = :frozen_dup
156156
stderr = EnvUtil.verbose_warning do
157157
assert imap.responses.frozen?
158158
assert imap.responses["CAPABILITY"].frozen?
159159
assert_equal(%w[IMAP4REV1 NAMESPACE MOVE IDLE UTF8=ACCEPT],
160160
imap.responses["CAPABILITY"].last)
161+
imap.responses do |r|
162+
refute r.frozen?
163+
refute r.values.any?(&:frozen?)
164+
end
161165
end
162166
assert_empty stderr
163167
end

0 commit comments

Comments
 (0)