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.