Skip to content

Commit b174f22

Browse files
committed
♻️ Rewrite response-cond-* methods to match ABNF
Although the assertion is redundant with the case stmt, these `resp_cond_*` methods now check for a valid label.
1 parent e356713 commit b174f22

File tree

1 file changed

+35
-19
lines changed

1 file changed

+35
-19
lines changed

lib/net/imap/response_parser.rb

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -383,15 +383,20 @@ def label(word)
383383
parse_error("unexpected atom %p, expected %p instead", val, word)
384384
end
385385

386+
# expects "OK" or "PREAUTH" and raises InvalidResponseError on failure
387+
def resp_cond_auth__name
388+
lbl = tagged_ext_label and AUTH_CONDS.include? lbl and return lbl
389+
raise InvalidResponseError, "bad response type %p, expected %s" % [
390+
lbl, AUTH_CONDS.join(" or ")
391+
]
392+
end
393+
386394
# expects "OK" or "NO" or "BAD" and raises InvalidResponseError on failure
387395
def resp_cond_state__name
388-
if RESP_COND_STATES.include?(actual = tagged_ext_label)
389-
actual
390-
else
391-
raise InvalidResponseError, "bad response type %p, expected %s" % [
392-
actual, RESP_COND_STATES.join(" or ")
393-
]
394-
end
396+
lbl = tagged_ext_label and RESP_COND_STATES.include? lbl and return lbl
397+
raise InvalidResponseError, "bad response type %p, expected %s" % [
398+
lbl, RESP_COND_STATES.join(" or ")
399+
]
395400
end
396401

397402
# nstring = string / nil
@@ -487,7 +492,7 @@ def response_data
487492
STAR!; SP!
488493
m = peek_re(RE_RESPONSE_TYPE) or parse_error("unparsable response")
489494
case m["type"].upcase
490-
when "OK" then response_cond # RFC3501, RFC9051
495+
when "OK" then resp_cond_state__untagged # RFC3501, RFC9051
491496
when "FETCH" then message_data__fetch # RFC3501, RFC9051
492497
when "EXPUNGE" then message_data__expunge # RFC3501, RFC9051
493498
when "EXISTS" then mailbox_data__exists # RFC3501, RFC9051
@@ -501,10 +506,10 @@ def response_data
501506
when "STATUS" then mailbox_data__status # RFC3501, RFC9051
502507
when "NAMESPACE" then namespace_response # RFC2342, RFC9051
503508
when "ENABLED" then enable_data # RFC5161, RFC9051
504-
when "BAD" then response_cond # RFC3501, RFC9051
505-
when "NO" then response_cond # RFC3501, RFC9051
506-
when "PREAUTH" then response_cond # RFC3501, RFC9051
507-
when "BYE" then response_cond # RFC3501, RFC9051
509+
when "BAD" then resp_cond_state__untagged # RFC3501, RFC9051
510+
when "NO" then resp_cond_state__untagged # RFC3501, RFC9051
511+
when "PREAUTH" then resp_cond_auth # RFC3501, RFC9051
512+
when "BYE" then resp_cond_bye # RFC3501, RFC9051
508513
when "RECENT" then mailbox_data__recent # RFC3501 (obsolete)
509514
when "SORT" then sort_data # RFC5256, RFC7162
510515
when "THREAD" then thread_data # RFC5256
@@ -562,15 +567,26 @@ def response_data__ignored; response_data__unhandled(IgnoredResponse) end
562567
def response_tagged
563568
tag = tag(); SP!
564569
name = resp_cond_state__name; SP!
565-
data = resp_text
566-
TaggedResponse.new(tag, name, data, @str)
570+
TaggedResponse.new(tag, name, resp_text, @str)
567571
end
568572

569-
def response_cond
570-
token = match(T_ATOM)
571-
name = token.value.upcase
572-
match(T_SPACE)
573-
return UntaggedResponse.new(name, resp_text, @str)
573+
# RFC3501 & RFC9051:
574+
# resp-cond-state = ("OK" / "NO" / "BAD") SP resp-text
575+
def resp_cond_state__untagged
576+
name = resp_cond_state__name; SP!
577+
UntaggedResponse.new(name, resp_text, @str)
578+
end
579+
580+
# resp-cond-auth = ("OK" / "PREAUTH") SP resp-text
581+
def resp_cond_auth
582+
name = resp_cond_auth__name; SP!
583+
UntaggedResponse.new(name, resp_text, @str)
584+
end
585+
586+
# resp-cond-bye = "BYE" SP resp-text
587+
def resp_cond_bye
588+
name = label(BYE); SP!
589+
UntaggedResponse.new(name, resp_text, @str)
574590
end
575591

576592
# message-data = nz-number SP ("EXPUNGE" / ("FETCH" SP msg-att))

0 commit comments

Comments
 (0)