The Net::IMAP standard library distributed with Ruby 1.8.6, 1.8.7, and 1.9.1 contains a response parsing bug that can cause an endless hang (in 1.8.x) or raise an exception (in 1.9.1) when switching between mailboxes on a Dovecot 1.2.x server.
The bug has been fixed in Ruby’s SVN trunk and should eventually make it into the 1.9.2 release, but if you’re using Net::IMAP with a current or older Ruby release and need a fix for this, the following monkeypatch (which just replaces the old buggy method with the fixed one from SVN) should do the trick.
Fortunately, this fix is the only difference from the 1.8.6, 1.8.7, and 1.9.1 versions of this method, so the monkeypatch works for all three versions. Just add it to your own code at some point after requiring Net::IMAP.
if RUBY_VERSION <= '1.9.1'
module Net # :nodoc:
class IMAP # :nodoc:
class ResponseParser # :nodoc:
private
# This monkeypatched method is the one included in Ruby SVN trunk as
# of 2010-02-08.
def resp_text_code
@lex_state = EXPR_BEG
match(T_LBRA)
token = match(T_ATOM)
name = token.value.upcase
case name
when /\A(?:ALERT|PARSE|READ-ONLY|READ-WRITE|TRYCREATE|NOMODSEQ)\z/n
result = ResponseCode.new(name, nil)
when /\A(?:PERMANENTFLAGS)\z/n
match(T_SPACE)
result = ResponseCode.new(name, flag_list)
when /\A(?:UIDVALIDITY|UIDNEXT|UNSEEN)\z/n
match(T_SPACE)
result = ResponseCode.new(name, number)
else
token = lookahead
if token.symbol == T_SPACE
shift_token
@lex_state = EXPR_CTEXT
token = match(T_TEXT)
@lex_state = EXPR_BEG
result = ResponseCode.new(name, token.value)
else
result = ResponseCode.new(name, nil)
end
end
match(T_RBRA)
@lex_state = EXPR_RTEXT
return result
end
end
end
end
end
If you’re a Larch user, the latest Larch development gem includes this fix.