Skip to content

Commit

Permalink
🥅 Return empty array for missing server response
Browse files Browse the repository at this point in the history
When the server fails to send a response for certain commands, we can
workaround this by simply returning an empty array.  This should work
for `SEARCH`, `SORT`, `THREAD`, and `ENABLED`, each of which expects a
single response.

I did not do the same for `CAPABILITY` for two reasons:
* unless written carefully, it could break the cache.
* the server _must_ at least return `* CAPABILITY IMAP4rev1`, so a
  missing response may indicate a bigger problems.
  • Loading branch information
nevans committed Nov 3, 2023
1 parent 37a1344 commit 4d038fb
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 4 deletions.
8 changes: 4 additions & 4 deletions lib/net/imap.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2188,7 +2188,7 @@ def enable(*capabilities)
.join(' ')
synchronize do
send_command("ENABLE #{capabilities}")
result = clear_responses("ENABLED").last
result = clear_responses("ENABLED").last || []
@utf8_strings ||= result.include? "UTF8=ACCEPT"
@utf8_strings ||= result.include? "IMAP4REV2"
result
Expand Down Expand Up @@ -2642,7 +2642,7 @@ def search_internal(cmd, keys, charset)
else
send_command(cmd, *keys)
end
clear_responses("SEARCH").last
clear_responses("SEARCH").last || []
end
end

Expand Down Expand Up @@ -2691,7 +2691,7 @@ def sort_internal(cmd, sort_keys, search_keys, charset)
normalize_searching_criteria(search_keys)
synchronize do
send_command(cmd, sort_keys, charset, *search_keys)
clear_responses("SORT").last
clear_responses("SORT").last || []
end
end

Expand All @@ -2704,7 +2704,7 @@ def thread_internal(cmd, algorithm, search_keys, charset)
normalize_searching_criteria(search_keys)
synchronize do
send_command(cmd, algorithm, charset, *search_keys)
clear_responses("THREAD").last
clear_responses("THREAD").last || []
end
end

Expand Down
41 changes: 41 additions & 0 deletions test/net/imap/test_imap.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1138,6 +1138,47 @@ def test_unselect
end
end

test("missing server ENABLED response") do
with_fake_server do |server, imap|
server.on "ENABLE", &:done_ok
enabled = imap.enable "foo", "bar", "baz"
assert_equal [], enabled
end
end

test("missing server SEARCH response") do
with_fake_server do |server, imap|
server.on "SEARCH", &:done_ok
server.on "UID SEARCH", &:done_ok
found = imap.search ["subject", "hello"]
assert_equal [], found
found = imap.uid_search ["subject", "hello"]
assert_equal [], found
end
end

test("missing server SORT response") do
with_fake_server do |server, imap|
server.on "SORT", &:done_ok
server.on "UID SORT", &:done_ok
found = imap.sort ["INTERNALDATE"], ["subject", "hello"], "UTF-8"
assert_equal [], found
found = imap.uid_sort ["INTERNALDATE"], ["subject", "hello"], "UTF-8"
assert_equal [], found
end
end

test("missing server THREAD response") do
with_fake_server do |server, imap|
server.on "THREAD", &:done_ok
server.on "UID THREAD", &:done_ok
found = imap.thread "REFERENCES", ["subject", "hello"], "UTF-8"
assert_equal [], found
found = imap.uid_thread "REFERENCES", ["subject", "hello"], "UTF-8"
assert_equal [], found
end
end

private

def imaps_test(timeout: 10)
Expand Down

0 comments on commit 4d038fb

Please sign in to comment.