@@ -941,41 +941,57 @@ def msg_att__label
941
941
# this represents the partial size for BODY or BINARY
942
942
alias gt__number__lt atom
943
943
944
+ # RFC3501 & RFC9051:
945
+ # envelope = "(" env-date SP env-subject SP env-from SP
946
+ # env-sender SP env-reply-to SP env-to SP env-cc SP
947
+ # env-bcc SP env-in-reply-to SP env-message-id ")"
944
948
def envelope
945
949
@lex_state = EXPR_DATA
946
- token = lookahead
947
- if token . symbol == T_NIL
948
- shift_token
949
- result = nil
950
- else
951
- match ( T_LPAR )
952
- date = nstring
953
- match ( T_SPACE )
954
- subject = nstring
955
- match ( T_SPACE )
956
- from = address_list
957
- match ( T_SPACE )
958
- sender = address_list
959
- match ( T_SPACE )
960
- reply_to = address_list
961
- match ( T_SPACE )
962
- to = address_list
963
- match ( T_SPACE )
964
- cc = address_list
965
- match ( T_SPACE )
966
- bcc = address_list
967
- match ( T_SPACE )
968
- in_reply_to = nstring
969
- match ( T_SPACE )
970
- message_id = nstring
971
- match ( T_RPAR )
972
- result = Envelope . new ( date , subject , from , sender , reply_to ,
973
- to , cc , bcc , in_reply_to , message_id )
974
- end
950
+ lpar ; date = env_date
951
+ SP! ; subject = env_subject
952
+ SP! ; from = env_from
953
+ SP! ; sender = env_sender
954
+ SP! ; reply_to = env_reply_to
955
+ SP! ; to = env_to
956
+ SP! ; cc = env_cc
957
+ SP! ; bcc = env_bcc
958
+ SP! ; in_reply_to = env_in_reply_to
959
+ SP! ; message_id = env_message_id
960
+ rpar
961
+ Envelope . new ( date , subject , from , sender , reply_to ,
962
+ to , cc , bcc , in_reply_to , message_id )
963
+ ensure
975
964
@lex_state = EXPR_BEG
976
- return result
977
965
end
978
966
967
+ # env-date = nstring
968
+ # env-subject = nstring
969
+ # env-in-reply-to = nstring
970
+ # env-message-id = nstring
971
+ alias env_date nstring
972
+ alias env_subject nstring
973
+ alias env_in_reply_to nstring
974
+ alias env_message_id nstring
975
+
976
+ # env-from = "(" 1*address ")" / nil
977
+ # env-sender = "(" 1*address ")" / nil
978
+ # env-reply-to = "(" 1*address ")" / nil
979
+ # env-to = "(" 1*address ")" / nil
980
+ # env-cc = "(" 1*address ")" / nil
981
+ # env-bcc = "(" 1*address ")" / nil
982
+ def nlist__address
983
+ return if NIL?
984
+ lpar ; list = [ address ] ; list << address until rpar?
985
+ list
986
+ end
987
+
988
+ alias env_from nlist__address
989
+ alias env_sender nlist__address
990
+ alias env_reply_to nlist__address
991
+ alias env_to nlist__address
992
+ alias env_cc nlist__address
993
+ alias env_bcc nlist__address
994
+
979
995
# date-time = DQUOTE date-day-fixed "-" date-month "-" date-year
980
996
# SP time SP zone DQUOTE
981
997
alias date_time quoted
@@ -1877,61 +1893,40 @@ def resp_code_copy__data
1877
1893
UIDPlusData . new ( validity , src_uids , dst_uids )
1878
1894
end
1879
1895
1880
- def address_list
1881
- token = lookahead
1882
- if token . symbol == T_NIL
1883
- shift_token
1884
- return nil
1885
- else
1886
- result = [ ]
1887
- match ( T_LPAR )
1888
- while true
1889
- token = lookahead
1890
- case token . symbol
1891
- when T_RPAR
1892
- shift_token
1893
- break
1894
- when T_SPACE
1895
- shift_token
1896
- end
1897
- result . push ( address )
1898
- end
1899
- return result
1900
- end
1901
- end
1902
-
1903
- ADDRESS_REGEXP = /\G \
1904
- (?# 1: NAME )(?:NIL|"((?:[^\x80 -\xff \x00 \r \n "\\ ]|\\ ["\\ ])*)") \
1905
- (?# 2: ROUTE )(?:NIL|"((?:[^\x80 -\xff \x00 \r \n "\\ ]|\\ ["\\ ])*)") \
1906
- (?# 3: MAILBOX )(?:NIL|"((?:[^\x80 -\xff \x00 \r \n "\\ ]|\\ ["\\ ])*)") \
1907
- (?# 4: HOST )(?:NIL|"((?:[^\x80 -\xff \x00 \r \n "\\ ]|\\ ["\\ ])*)")\
1908
- \) /ni
1909
-
1896
+ ADDRESS_REGEXP = /\G
1897
+ \( (?: NIL | #{ Patterns ::QUOTED_rev2 } ) # 1: NAME
1898
+ \s (?: NIL | #{ Patterns ::QUOTED_rev2 } ) # 2: ROUTE
1899
+ \s (?: NIL | #{ Patterns ::QUOTED_rev2 } ) # 3: MAILBOX
1900
+ \s (?: NIL | #{ Patterns ::QUOTED_rev2 } ) # 4: HOST
1901
+ \)
1902
+ /nix
1903
+
1904
+ # address = "(" addr-name SP addr-adl SP addr-mailbox SP
1905
+ # addr-host ")"
1906
+ # addr-adl = nstring
1907
+ # addr-host = nstring
1908
+ # addr-mailbox = nstring
1909
+ # addr-name = nstring
1910
1910
def address
1911
- match ( T_LPAR )
1912
- if @str . index ( ADDRESS_REGEXP , @pos )
1913
- # address does not include literal.
1914
- @pos = $~. end ( 0 )
1915
- name = $1
1916
- route = $2
1917
- mailbox = $3
1918
- host = $4
1919
- for s in [ name , route , mailbox , host ]
1920
- Patterns . unescape_quoted! s
1921
- end
1922
- else
1923
- name = nstring
1924
- match ( T_SPACE )
1925
- route = nstring
1926
- match ( T_SPACE )
1927
- mailbox = nstring
1928
- match ( T_SPACE )
1929
- host = nstring
1930
- match ( T_RPAR )
1911
+ if ( match = accept_re ( ADDRESS_REGEXP ) )
1912
+ # note that "NIL" isn't captured by the regexp
1913
+ name , route , mailbox , host = match . captures
1914
+ . map { Patterns . unescape_quoted _1 }
1915
+ else # address may include literals
1916
+ lpar ; name = addr_name
1917
+ SP! ; route = addr_adl
1918
+ SP! ; mailbox = addr_mailbox
1919
+ SP! ; host = addr_host
1920
+ rpar
1931
1921
end
1932
- return Address . new ( name , route , mailbox , host )
1922
+ Address . new ( name , route , mailbox , host )
1933
1923
end
1934
1924
1925
+ alias addr_adl nstring
1926
+ alias addr_host nstring
1927
+ alias addr_mailbox nstring
1928
+ alias addr_name nstring
1929
+
1935
1930
# flag-list = "(" [flag *(SP flag)] ")"
1936
1931
def flag_list
1937
1932
match_re ( Patterns ::FLAG_LIST , "flag-list" ) [ 1 ]
0 commit comments