Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 45 additions & 5 deletions lib/net/imap.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1949,12 +1949,15 @@ def ensure_mod_sequence_value(num)

# Net::IMAP::ResponseCode represents response codes.
#
# resp_text_code ::= "ALERT" / "PARSE" /
# "PERMANENTFLAGS" SPACE "(" #(flag / "\*") ")" /
# resp_text_code ::= "ALERT" /
# "BADCHARSET" [SP "(" astring *(SP astring) ")" ] /
# capability_data / "PARSE" /
# "PERMANENTFLAGS" SP "("
# [flag_perm *(SP flag_perm)] ")" /
# "READ-ONLY" / "READ-WRITE" / "TRYCREATE" /
# "UIDVALIDITY" SPACE nz_number /
# "UNSEEN" SPACE nz_number /
# atom [SPACE 1*<any TEXT_CHAR except "]">]
# "UIDNEXT" SP nz_number / "UIDVALIDITY" SP nz_number /
# "UNSEEN" SP nz_number /
# atom [SP 1*<any TEXT-CHAR except "]">]
#
# ==== Fields:
#
Expand Down Expand Up @@ -3450,12 +3453,25 @@ def resp_text
end
end

# See https://www.rfc-editor.org/errata/rfc3501
#
# resp-text-code = "ALERT" /
# "BADCHARSET" [SP "(" charset *(SP charset) ")" ] /
# capability-data / "PARSE" /
# "PERMANENTFLAGS" SP "("
# [flag-perm *(SP flag-perm)] ")" /
# "READ-ONLY" / "READ-WRITE" / "TRYCREATE" /
# "UIDNEXT" SP nz-number / "UIDVALIDITY" SP nz-number /
# "UNSEEN" SP nz-number /
# atom [SP 1*<any TEXT-CHAR except "]">]
def resp_text_code
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(?:BADCHARSET)\z/n
result = ResponseCode.new(name, charset_list)
when /\A(?:CAPABILITY)\z/ni
result = ResponseCode.new(name, capability_data)
when /\A(?:PERMANENTFLAGS)\z/n
Expand All @@ -3477,6 +3493,19 @@ def resp_text_code
return result
end

def charset_list
result = []
if accept(T_SPACE)
match(T_LPAR)
result << charset
while accept(T_SPACE)
result << charset
end
match(T_RPAR)
end
result
end

def address_list
token = lookahead
if token.symbol == T_NIL
Expand Down Expand Up @@ -3637,6 +3666,17 @@ def combine_adjacent(*tokens)
result
end

# See https://www.rfc-editor.org/errata/rfc3501
#
# charset = atom / quoted
def charset
if token = accept(T_QUOTED)
token.value
else
atom
end
end

def number
token = lookahead
if token.symbol == T_NIL
Expand Down
8 changes: 8 additions & 0 deletions test/net/imap/test_imap_response_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,14 @@ def test_msg_rfc3501_response_text_with_T_LBRA
assert_equal("[Gmail]/Sent Mail selected. (Success)", response.data.text)
end

def test_msg_rfc3501_response_text_with_BADCHARSET_astrings
parser = Net::IMAP::ResponseParser.new
response = parser.parse("t BAD [BADCHARSET (US-ASCII \"[astring with brackets]\")] unsupported charset foo.\r\n")
assert_equal("t", response.tag)
assert_equal("unsupported charset foo.", response.data.text)
assert_equal("BADCHARSET", response.data.code.name)
end

def test_continuation_request_without_response_text
parser = Net::IMAP::ResponseParser.new
response = parser.parse("+\r\n")
Expand Down