Releases: ruby/net-imap
v0.5.6
What's Changed
🔒 Security Fix
Fixes CVE-2025-25186 (GHSA-7fc5-f82f-cx69): A malicious server can exhaust client memory by sending APPENDUID
or COPYUID
responses with very large uid-set
ranges. Net::IMAP::UIDPlusData
expands these ranges into arrays of integers.
Fix with minor API changes
Set config.parser_use_deprecated_uidplus_data
to false
to replace UIDPlusData
with AppendUIDData
and CopyUIDData
. These classes store their UIDs as Net::IMAP::SequenceSet
objects (not expanded into arrays of integers). Code that does not handle APPENDUID
or COPYUID
responses should not see any difference. Code that does handle these responses may need to be updated.
For v0.3.8, this option is not available
For v0.4.19, the default value is true
.
For v0.5.6, the default value is :up_to_max_size
.
For v0.6.0, the only allowed value will be false
(UIDPlusData
will be removed from v0.6).
Mitigate with backward compatible API
Adjust config.parser_max_deprecated_uidplus_data_size
to limit the maximum UIDPlusData
UID set size.
When config.parser_use_deprecated_uidplus_data == true
, larger sets will crash.
When config.parser_use_deprecated_uidplus_data == :up_to_max_size
, larger sets will use AppendUIDData
or CopyUIDData
.
For v0.3,8, this limit is hard-coded to 10,000.
For v0.4.19, this limit defaults to 1000.
For v0.5.6, this limit defaults to 100.
For v0.6.0, the only allowed value will be 0
(UIDPlusData
will be removed from v0.6).
Please Note: unhandled responses
If the client does not add response handlers to prune unhandled responses, a malicious server can still eventually exhaust all client memory, by repeatedly sending malicious responses. However, net-imap
has always retained unhandled responses, and it has always been necessary for long-lived connections to prune these responses. This is not significantly different from connecting to a trusted server with a long-lived connection. To limit the maximum number of retained responses, a simple handler might look something like the following:
limit = 1000
imap.add_response_handler do |resp|
next unless resp.respond_to?(:name) && resp.respond_to?(:data)
name = resp.name
code = resp.data.code&.name if resp.data.is_a?(Net::IMAP::ResponseText)
imap.responses(name) { _1.slice!(0...-limit) }
imap.responses(code) { _1.slice!(0...-limit) }
end
Added
- 🔧 Ensure ResponseParser config is mutable and non-global by @nevans in #381
- ✨ Add SequenceSet methods for querying about duplicates by @nevans in #384
- ✨ Add
SequenceSet#each_ordered_number
by @nevans in #386 - ✨ Add
SequenceSet#find_ordered_index
by @nevans in #396 - ✨ Add
SequenceSet#ordered_at
by @nevans in #397 - ✨ Add AppendUIDData and CopyUIDData classes by @nevans in #400
- 🔧 Add parser config for
APPENDUID
/COPYUID
, 🗑️ Deprecate UIDPlusData by @nevans in #401
Fixed
- 🐛 Fix
SequenceSet#append
when its@string
is nil by @nevans in #376 - 🐛 Fix SequenceSet merging in another SequenceSet by @nevans in #377
- 🐛 Fix SequenceSet count dups with multiple "*" by @nevans in #387
- 🥅 Re-raise
#starttls
error from receiver thread by @nevans in #395
Documentation
- 📚 Fix
SequenceSet#cover?
documentation by @nevans in #379 - 📚 Document COPYUID in tagged vs untagged responses by @nevans in #398
Other Changes
- 🚚 Move UIDPlusData to its own file by @nevans in #391
- ♻️ Parse
uid-set
assequence-set
without*
by @nevans in #393
Miscellaneous
- ⬆️ Bump step-security/harden-runner from 2.10.2 to 2.10.3 by @dependabot in #375
- ⬆️ Bump step-security/harden-runner from 2.10.3 to 2.10.4 by @dependabot in #380
- ✅ Improve test coverage for SequenceSet enums by @nevans in #383
- ♻️✅ Refactor SequenceSet enumerator tests by @nevans in #385
- ➕ Add "irb" to Gemfile to silence warning by @nevans in #388
- Omit flaky test with macOS platform by @hsbt in #389
- ✅ Improve UIDPlusData test coverage by @nevans in #392
- 🚚 Rename UIDPLUS test file for consistency by @nevans in #399
Full Changelog: v0.5.5...v0.5.6
v0.4.19
What's Changed
🔒 Security Fix
Fixes CVE-2025-25186 (GHSA-7fc5-f82f-cx69): A malicious server can exhaust client memory by sending APPENDUID
or COPYUID
responses with very large uid-set
ranges. Net::IMAP::UIDPlusData
expands these ranges into arrays of integers.
Fix with minor API changes
Set config.parser_use_deprecated_uidplus_data
to false
to replace UIDPlusData
with AppendUIDData
and CopyUIDData
. These classes store their UIDs as Net::IMAP::SequenceSet
objects (not expanded into arrays of integers). Code that does not handle APPENDUID
or COPYUID
responses should not see any difference. Code that does handle these responses may need to be updated.
For v0.3.8, this option is not available
For v0.4.19, the default value is true
.
For v0.5.6, the default value is :up_to_max_size
.
For v0.6.0, the only allowed value will be false
(UIDPlusData
will be removed from v0.6).
Mitigate with backward compatible API
Adjust config.parser_max_deprecated_uidplus_data_size
to limit the maximum UIDPlusData
UID set size.
When config.parser_use_deprecated_uidplus_data == true
, larger sets will crash.
When config.parser_use_deprecated_uidplus_data == :up_to_max_size
, larger sets will use AppendUIDData
or CopyUIDData
.
For v0.3,8, this limit is hard-coded to 10,000.
For v0.4.19, this limit defaults to 1000.
For v0.5.6, this limit defaults to 100.
For v0.6.0, the only allowed value will be 0
(UIDPlusData
will be removed from v0.6).
Please Note: unhandled responses
If the client does not add response handlers to prune unhandled responses, a malicious server can still eventually exhaust all client memory, by repeatedly sending malicious responses. However, net-imap
has always retained unhandled responses, and it has always been necessary for long-lived connections to prune these responses. This is not significantly different from connecting to a trusted server with a long-lived connection. To limit the maximum number of retained responses, a simple handler might look something like the following:
limit = 1000
imap.add_response_handler do |resp|
next unless resp.respond_to?(:name) && resp.respond_to?(:data)
name = resp.name
code = resp.data.code&.name if resp.data.in?(Net::IMAP::ResponseText)
imap.responses(name) { _1.slice!(0...-limit) }
imap.responses(code) { _1.slice!(0...-limit) }
end
Added
- 🔧 ResponseParser config is mutable and non-global (backports #381) by @nevans in #382
- ✨ SequenceSet ordered entries methods (backports to v0.4-stable) by @nevans in #402
Backports the following: - ✨ Backport UIDPlusData, AppendUIDData, CopyUIDData to v0.4 by @nevans in #404
Backports the following:
Fixed
- 🐛 Backport SequenceSet bugfixes (#376, #377) to v0.4 by @nevans in #378
Backports the following: - 🥅 Re-raise
#starttls
error from receiver thread (backport #395 to v0.4) by @nevans in #403
Other Changes
Full Changelog: v0.4.18...v0.4.19
v0.3.8
What's Changed
🔒 Security Fix
Mitigates CVE-2025-25186 (GHSA-7fc5-f82f-cx69): A malicious server can exhaust client memory by sending APPENDUID
or COPYUID
responses with very large uid-set
ranges. Net::IMAP::UIDPlusData
expands these ranges into arrays of integers.
Fix with minor API changes
For v0.3.8, this option is not available. Upgrade to v0.4.19, v0.5.6, or higher to replace UIDPlusData
with AppendUIDData
and CopyUIDData
. These classes store their UIDs as Net::IMAP::SequenceSet
objects (not expanded into arrays of integers).
Mitigate with backward compatible API
This release mitigates the attack by crashing if a server tries to send a uid-set
that represents more than 10,000 numbers. This should be larger than almost all legitimate COPYUID
or APPENDUID
responses and would limit the array to only 80KB (on a 64 bit system).
For v0.3.8, this option is not configurable. Upgrade to v0.4.19, v0.5.6, or higher to configure this limit.
Please Note: unhandled responses
If the client does not add response handlers to prune unhandled responses, a malicious server can still eventually exhaust all client memory, by repeatedly sending malicious responses. However, net-imap
has always retained unhandled responses, and it has always been necessary for long-lived connections to prune these responses. This is not significantly different from connecting to a trusted server with a long-lived connection. To limit the maximum number of retained responses, a simple handler might look something like the following:
limit = 1000
imap.add_response_handler do |resp|
name = resp.name
code = resp.data.code&.name if resp.data.in?(Net::IMAP::ResponseText)
# before 0.4.0:
imap.responses[name].slice!(0...-limit)
imap.responses[code].slice!(0...-limit)
# since 0.4.0:
imap.responses(name) { _1.slice!(0...-limit) }
imap.responses(code) { _1.slice!(0...-limit) }
end
Miscellaneous
Full Changelog: v0.3.7...v0.3.8
v0.5.5
What's Changed
Breaking Changes
- 🐛💥 Remove accidental
Data#attributes
method by @nevans in #371
For ruby 3.2 and above, this PR is not a breaking change, and it fixes a YAML serialization bug.
Net::IMAP::Data#attributes
was only available in ruby 3.1, withnet-imap
v0.5.2
-v0.5.4
. It can be replaced by#to_h
.
Added
Documentation
- 📚 Fix rdoc issues by @nevans in #372
- 📚 Use standard www.rfc-editor.org links for RFCs by @nevans in #374
- 📚 Documentation updates by @nevans in #373
New Contributors
Full Changelog: v0.5.4...v0.5.5
v0.5.4
v0.5.3
v0.5.2
What's Changed
Added
- 🥅 Raise ArgumentError on multiple search charset args by @nevans in #363
- ✨ Add keyword argument for search
charset
by @nevans in #364 - ✨ Add basic
ESEARCH
support (RFC4466, RFC4731) by @nevans in #333
Fixed
Documentation
- 📚 Fix README example by @nevans in #354
- 📦📚 Add release.yml for better release note generation by @nevans in #355
- 📚💄 Fix rdoc 6.8 CSS styles by @nevans in #356
- 📚 Update IMAP#search docs (again) by @nevans in #360
- 📚 Consistent heading levels inside method rdoc by @nevans in #361
Other Changes
- ✨ Add Data polyfill for ruby 3.1 by @nevans in #352
- ♻️ Refactor internal command data classes by @nevans in #358
Miscellaneous
- 🔥 Drop YAML.unsafe_load_file refinement (tests only) by @nevans in #353
- ⬆️ Bump step-security/harden-runner from 2.10.1 to 2.10.2 by @dependabot in #357
- Enabled windows-latest on GHA by @hsbt in #359
Full Changelog: v0.5.1...v0.5.2
v0.5.1
What's Changed
Added
- ✨ Add
SequenceSet#deconstruct
by @nevans in #343 - ✨ Coerce
Set
,:*
,#to_sequence_set
search args into sequence-set by @nevans in #351 - ✨ Enable parenthesized lists in search criteria by @nevans in #345
Fixed
- 🐛 Ensure
set
is loaded in ruby 3.1 by @nevans in #342 - 🐛 Fix
SequenceSet.try_convert
by @nevans in #349
Documentation
Other Changes
Miscellaneous
- Make simplecov-json as optional dependency by @hsbt in #344
- Removed needless workaround by @hsbt in #346
Full Changelog: v0.5.0...v0.5.1
v0.4.18
What's Changed
Full Changelog: v0.4.17...v0.4.18
v0.5.0
What's Changed
Breaking Changes
- 💥 Drop ruby 2.7 and 3.0 support, and require ruby 3.1 by @nevans in #276
- 💥⚡ Simplify
header-fld-name
parser (backward incompatible) by @nevans in #216
For example,HEADER.FIELDS (Content-Type)
andHEADER.FIELDS ("Content-Type")
are semantically identical, and a server may choose to return the quoted version.- Before this change, the FetchData attr header name would be quoted if the server sent the field name quoted.
- After this change, the header field names will always be unquoted by the parser, so the result will always available via
fetch_data.header_fields("Content-Type")
orfetch_data.attr_upcase["HEADER.FIELDS (CONTENT-TYPE)"]
.
- 💥 Replace MessageSet with SequenceSet by @nevans in #282
Most of the changes are bugfixes or allow something new to work that didn't work before. See the PR for more details.
This affects#search
,#uid_search
,#sort
,#uid_sort
,#fetch
,#uid_fetch
,#store
,#uid_store
,#copy
,#uid_copy
,#move
,#uid_move
, and#uid_expunge
. - 💥 SequenceSet input validation for Set, Array, and enumerables by @nevans in #319
- Array inputs can still be deeply nested. This is unchanged.
- Set inputs can only contain integers and
"*"
or:*
, to be consistent withSequenceSet#to_set
. - Other
Enumerables
will only be converted if they implement#to_sequence_set
.
- 🔥 Remove deprecated
#client_thread
attr_reader by @nevans in #321
#client_thread
was deprecated byv0.4.0
. - 🔥 Drop deprecated BodyType structs by @nevans in #323
These structs were deprecated byv0.4.0
.
Added
- ✨ Add
#extract_responses
method by @nevans in #330 Also backported tov0.4.17
. - ✨ New config option to return frozen dup from
#responses
by @nevans in #334 Also backported tov0.4.17
. - 🥅 Improve SequenceSet frozen errors by @nevans in #331 Also backported to
v0.4.17
. - 📚 SequenceSet API is considered stable now by @nevans in #318
- 🔒 Enforce
LOGINDISABLED
requirement by @nevans in #307
To workaround buggy servers,config.enforce_logindisabled
can be set to:when_capabilities_cached
orfalse
. - 🔒 SASL DIGEST-MD5: realm, host, service_name, etc by @nevans in #284
Please note that theDIGEST-MD5
SASL mechanism is insecure and deprecated.
Deprecations
- 🔊 Warn about deprecated
#responses
usage by @nevans in #97
To silence these warnings:- pass a block to
#responses
(supported sincev0.4.0
), - pass a response type to
#responses
for a frozen copied array (sincev0.4.17
), - set
config.responses_without_block
to:silence_deprecation_warning
(sincev0.4.13
), - set
config.responses_without_block
to:frozen_dup
for a frozen copy (sincev0.4.17
), - use
#clear_responses
instead (sincev0.4.0
), - use
#extract_responses
instead (sincev0.4.17
).
- pass a block to
- 🗑️ Deprecate
MessageSet
by @nevans in #282
MessageSet
was only intended for internal use, and all internal usage has been replaced.
Fixed
- 🐛 Fix #send_data to send DateTime as time by @taku0 in #313
Also backported tov0.4.15
. - 🐛 Fix #header_fld_name to handle quoted strings correctly by @taku0 in #315
Also backported tov0.4.16
. - 🐛 Fix SequenceSet[input] when input is a SequenceSet by @nevans in #326
Also backported tov0.4.17
. - 🐛 Fix Set inputs for SequenceSet by @nevans in #332
This bug was introduced by #319, which had not been previously released.
Other Changes
- 🔧 Update default config for v0.5 by @nevans in #305
- ♻️ Use Integer.try_convert (new in ruby 3.1+) by @nevans in #316
- 🗑️ Add
category: :deprecated
to calls towarn
by @nevans in #322 - ♻️ Extract SASL::Authenticators#normalize_name by @nevans in #309
- 🔒 📚 Improvements and docs for SASL::ClientAdapter by @nevans in #320
- ♻️ Use SASL::ClientAdapter by @nevans in #194
Documentation
- 📚 Update Config rdoc for v0.5 by @nevans in #306
- 📚 Update SASL documentation by @nevans in #308
- 📚 SequenceSet API is considered stable now by @nevans in #318
- 🔒 📚 Improvements and docs for SASL::ClientAdapter by @nevans in #320
Miscellaneous
- ✅ Add a Mutex to FakeServer (for tests only) by @nevans in #317
Also backported tov0.4.17
. - ⬆️ Bump step-security/harden-runner from 2.8.1 to 2.9.0 by @dependabot in #311
- ⬆️ Bump step-security/harden-runner from 2.9.0 to 2.9.1 by @dependabot in #312
- Bump step-security/harden-runner from 2.9.1 to 2.10.1 by @dependabot in #325
- 🔨📚 Fix rdoc => ghpages workflow by @nevans in #335
- ✅ Fix GH action for rubygems Trusted Publishing by @nevans in #340
Also backported tov0.4.17
. - ✅ Setup simplecov by @nevans in #328
New Contributors
Full Changelog: v0.4.14...v0.5.0
(Note that v0.4.x
releases since v0.4.14
have used the v0.4-stable
branch.)