net-imap 0.6.3 → 0.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/net/imap.rb CHANGED
@@ -450,8 +450,8 @@ module Net
450
450
  #
451
451
  # Although IMAP4rev2[https://www.rfc-editor.org/rfc/rfc9051] is not supported
452
452
  # yet, Net::IMAP supports several extensions that have been folded into it:
453
- # +ENABLE+, +IDLE+, +MOVE+, +NAMESPACE+, +SASL-IR+, +UIDPLUS+, +UNSELECT+,
454
- # <tt>STATUS=SIZE</tt>, and the fetch side of +BINARY+.
453
+ # +ENABLE+, +IDLE+, +LITERAL-+, +MOVE+, +NAMESPACE+, +SASL-IR+, +UIDPLUS+,
454
+ # +UNSELECT+, <tt>STATUS=SIZE</tt>, and the fetch side of +BINARY+.
455
455
  # Commands for these extensions are listed with the {Core IMAP
456
456
  # commands}[rdoc-ref:Net::IMAP@Core+IMAP+commands], above.
457
457
  #
@@ -459,9 +459,12 @@ module Net
459
459
  # <em>The following are folded into +IMAP4rev2+ but are currently
460
460
  # unsupported or incompletely supported by</em> Net::IMAP<em>: RFC4466
461
461
  # extensions, +SEARCHRES+, +LIST-EXTENDED+, +LIST-STATUS+,
462
- # +LITERAL-+, and +SPECIAL-USE+.</em>
462
+ # and +SPECIAL-USE+.</em>
463
463
  #
464
464
  # ==== RFC2087: +QUOTA+
465
+ # +NOTE:+ Only the +STORAGE+ quota resource type is currently supported.
466
+ # - Obsoleted by <tt>QUOTA=RES-*</tt> [RFC9208[https://www.rfc-editor.org/rfc/rfc9208]],
467
+ # although the commands are backward compatible.
465
468
  # - #getquota: returns the resource usage and limits for a quota root
466
469
  # - #getquotaroot: returns the list of quota roots for a mailbox, as well as
467
470
  # their resource usage and limits.
@@ -486,9 +489,7 @@ module Net
486
489
  # IMAP4rev2[https://www.rfc-editor.org/rfc/rfc9051].
487
490
  # - Updates #fetch and #uid_fetch with the +BINARY+, +BINARY.PEEK+, and
488
491
  # +BINARY.SIZE+ items. See FetchData#binary and FetchData#binary_size.
489
- #
490
- # >>>
491
- # *NOTE:* The binary extension the #append command is _not_ supported yet.
492
+ # - Updates #append to allow binary messages containing +NULL+ bytes.
492
493
  #
493
494
  # ==== RFC3691: +UNSELECT+
494
495
  # Folded into IMAP4rev2[https://www.rfc-editor.org/rfc/rfc9051] and also included
@@ -568,6 +569,15 @@ module Net
568
569
  # - Updates #store and #uid_store with the +unchangedsince+ modifier and adds
569
570
  # the +MODIFIED+ ResponseCode to the tagged response.
570
571
  #
572
+ # ==== RFC7888: <tt>LITERAL+</tt>
573
+ # - Literal strings smaller than Config#max_non_synchronizing_literal bytes
574
+ # are sent without waiting for the server's continuation request.
575
+ #
576
+ # ==== RFC7888: +LITERAL-+
577
+ # - Literal strings smaller than 4096 bytes or
578
+ # Config#max_non_synchronizing_literal (whichever is smaller)
579
+ # are sent without waiting for the server's continuation request.
580
+ #
571
581
  # ==== RFC8438: <tt>STATUS=SIZE</tt>
572
582
  # - Updates #status with the +SIZE+ status attribute.
573
583
  #
@@ -578,6 +588,16 @@ module Net
578
588
  # See FetchData#emailid and FetchData#emailid.
579
589
  # - Updates #status with support for the +MAILBOXID+ status attribute.
580
590
  #
591
+ # ==== RFC9208: <tt>QUOTA=RES-*</tt>
592
+ # +NOTE:+ Only the +STORAGE+ quota resource type is currently supported.
593
+ # - Obsoletes the +QUOTA+ [RFC2087[https://www.rfc-editor.org/rfc/rfc2087]]
594
+ # extension and provides strict semantics for different resource types.
595
+ # - #getquota: returns the resource usage and limits for a quota root
596
+ # - #getquotaroot: returns the list of quota roots for a mailbox, as well as
597
+ # their resource usage and limits.
598
+ # - #setquota: sets the resource limits for a given quota root.
599
+ # - Updates #status with <tt>"DELETED"</tt> and +DELETED-STORAGE+ attributes.
600
+ #
581
601
  # ==== RFC9394: +PARTIAL+
582
602
  # - Updates #search, #uid_search with the +PARTIAL+ return option which adds
583
603
  # ESearchResult#partial return data.
@@ -631,9 +651,9 @@ module Net
631
651
  # RFC 5322, DOI 10.17487/RFC5322, October 2008,
632
652
  # <https://www.rfc-editor.org/info/rfc5322>.
633
653
  #
634
- # <em>Note: obsoletes</em>
635
- # RFC-2822[https://www.rfc-editor.org/rfc/rfc2822]<em> (April 2001) and</em>
636
- # RFC-822[https://www.rfc-editor.org/rfc/rfc822]<em> (August 1982).</em>
654
+ # *NOTE*: obsoletes
655
+ # RFC-2822[https://www.rfc-editor.org/rfc/rfc2822] (April 2001) and
656
+ # RFC-822[https://www.rfc-editor.org/rfc/rfc822] (August 1982).
637
657
  #
638
658
  # [CHARSET[https://www.rfc-editor.org/rfc/rfc2978]]::
639
659
  # Freed, N. and J. Postel, "IANA Charset Registration Procedures", BCP 19,
@@ -698,13 +718,12 @@ module Net
698
718
  #
699
719
  # === \IMAP Extensions
700
720
  #
701
- # [QUOTA[https://www.rfc-editor.org/rfc/rfc9208]]::
702
- # Melnikov, A., "IMAP QUOTA Extension", RFC 9208, DOI 10.17487/RFC9208,
703
- # March 2022, <https://www.rfc-editor.org/info/rfc9208>.
721
+ # [QUOTA[https://www.rfc-editor.org/rfc/rfc2087]]::
722
+ # Myers, J., "IMAP4 QUOTA extension", RFC 2087, DOI 10.17487/RFC2087,
723
+ # January 1997, <https://www.rfc-editor.org/info/rfc2087>.
704
724
  #
705
- # <em>Note: obsoletes</em>
706
- # RFC-2087[https://www.rfc-editor.org/rfc/rfc2087]<em> (January 1997)</em>.
707
- # <em>Net::IMAP does not fully support the RFC9208 updates yet.</em>
725
+ # *NOTE*: _obsoleted_ by RFC9208[https://www.rfc-editor.org/rfc/rfc9208]
726
+ # (March 2022).
708
727
  # [IDLE[https://www.rfc-editor.org/rfc/rfc2177]]::
709
728
  # Leiba, B., "IMAP4 IDLE command", RFC 2177, DOI 10.17487/RFC2177,
710
729
  # June 1997, <https://www.rfc-editor.org/info/rfc2177>.
@@ -741,8 +760,8 @@ module Net
741
760
  # Gulbrandsen, A. and N. Freed, Ed., "Internet Message Access Protocol
742
761
  # (\IMAP) - MOVE Extension", RFC 6851, DOI 10.17487/RFC6851, January 2013,
743
762
  # <https://www.rfc-editor.org/info/rfc6851>.
744
- # [UTF8=ACCEPT[https://www.rfc-editor.org/rfc/rfc6855]]::
745
- # [UTF8=ONLY[https://www.rfc-editor.org/rfc/rfc6855]]::
763
+ # [{UTF8=ACCEPT}[https://www.rfc-editor.org/rfc/rfc6855]]::
764
+ # [{UTF8=ONLY}[https://www.rfc-editor.org/rfc/rfc6855]]::
746
765
  # Resnick, P., Ed., Newman, C., Ed., and S. Shen, Ed.,
747
766
  # "IMAP Support for UTF-8", RFC 6855, DOI 10.17487/RFC6855, March 2013,
748
767
  # <https://www.rfc-editor.org/info/rfc6855>.
@@ -756,6 +775,11 @@ module Net
756
775
  # Gondwana, B., Ed., "IMAP Extension for Object Identifiers",
757
776
  # RFC 8474, DOI 10.17487/RFC8474, September 2018,
758
777
  # <https://www.rfc-editor.org/info/rfc8474>.
778
+ # [{QUOTA=RES-*}[https://www.rfc-editor.org/rfc/rfc9208]]::
779
+ # Melnikov, A., "IMAP QUOTA Extension", RFC 9208, DOI 10.17487/RFC9208,
780
+ # March 2022, <https://www.rfc-editor.org/info/rfc9208>.
781
+ #
782
+ # Obsoletes RFC2087[https://www.rfc-editor.org/rfc/rfc2087].
759
783
  # [PARTIAL[https://www.rfc-editor.org/info/rfc9394]]::
760
784
  # Melnikov, A., Achuthan, A., Nagulakonda, V., and L. Alves,
761
785
  # "IMAP PARTIAL Extension for Paged SEARCH and FETCH", RFC 9394,
@@ -769,6 +793,7 @@ module Net
769
793
  #
770
794
  # === IANA registries
771
795
  # * {IMAP Capabilities}[http://www.iana.org/assignments/imap4-capabilities]
796
+ # * {IMAP Quota Resource Types}[http://www.iana.org/assignments/imap4-capabilities#imap-capabilities-2]
772
797
  # * {IMAP Response Codes}[https://www.iana.org/assignments/imap-response-codes/imap-response-codes.xhtml]
773
798
  # * {IMAP Mailbox Name Attributes}[https://www.iana.org/assignments/imap-mailbox-name-attributes/imap-mailbox-name-attributes.xhtml]
774
799
  # * {IMAP and JMAP Keywords}[https://www.iana.org/assignments/imap-jmap-keywords/imap-jmap-keywords.xhtml]
@@ -779,8 +804,8 @@ module Net
779
804
  # * {GSSAPI/Kerberos/SASL Service Names}[https://www.iana.org/assignments/gssapi-service-names/gssapi-service-names.xhtml]:
780
805
  # +imap+
781
806
  # * {Character sets}[https://www.iana.org/assignments/character-sets/character-sets.xhtml]
807
+ #
782
808
  # ==== For currently unsupported features:
783
- # * {IMAP Quota Resource Types}[http://www.iana.org/assignments/imap4-capabilities#imap-capabilities-2]
784
809
  # * {LIST-EXTENDED options and responses}[https://www.iana.org/assignments/imap-list-extended/imap-list-extended.xhtml]
785
810
  # * {IMAP METADATA Server Entry and Mailbox Entry Registries}[https://www.iana.org/assignments/imap-metadata/imap-metadata.xhtml]
786
811
  # * {IMAP ANNOTATE Extension Entries and Attributes}[https://www.iana.org/assignments/imap-annotate-extension/imap-annotate-extension.xhtml]
@@ -788,7 +813,7 @@ module Net
788
813
  # * {IMAP URLAUTH Authorization Mechanism Registry}[https://www.iana.org/assignments/urlauth-authorization-mechanism-registry/urlauth-authorization-mechanism-registry.xhtml]
789
814
  #
790
815
  class IMAP < Protocol
791
- VERSION = "0.6.3"
816
+ VERSION = "0.6.4"
792
817
 
793
818
  # Aliases for supported capabilities, to be used with the #enable command.
794
819
  ENABLE_ALIASES = {
@@ -1120,6 +1145,31 @@ module Net
1120
1145
  start_imap_connection
1121
1146
  end
1122
1147
 
1148
+ # Returns a string representation of +self+, showing basic client state
1149
+ # information.
1150
+ #
1151
+ # imap = Net::IMAP.new(hostname, ssl: true)
1152
+ # imap.inspect #=> "#<Net::IMAP imap.example.net:993 TLS not_authenticated>"
1153
+ #
1154
+ # imap.authenticate(:oauthbearer, "user", token)
1155
+ # imap.inspect #=> "#<Net::IMAP imap.example.net:993 TLS authenticated>"
1156
+ #
1157
+ # imap.select("INBOX")
1158
+ # imap.inspect #=> "#<Net::IMAP imap.example.net:993 TLS selected>"
1159
+ #
1160
+ # imap.logout
1161
+ # imap.inspect #=> "#<Net::IMAP imap.example.net:993 TLS logout>"
1162
+ #
1163
+ def inspect
1164
+ tls_state = tls_verified? ? "TLS" :
1165
+ ssl_ctx ? "TLS (NOT VERIFIED)" :
1166
+ "PLAINTEXT"
1167
+ conn_state = disconnected? ? "disconnected" : connection_state.to_sym
1168
+ "#<%s:0x%08x %s:%s %s %s>" % [
1169
+ self.class.name, __id__, host, port, tls_state, conn_state
1170
+ ]
1171
+ end
1172
+
1123
1173
  # Returns true after the TLS negotiation has completed and the remote
1124
1174
  # hostname has been verified. Returns false when TLS has been established
1125
1175
  # but peer verification was disabled.
@@ -1390,9 +1440,11 @@ module Net
1390
1440
  #
1391
1441
  def starttls(**options)
1392
1442
  @ssl_ctx_params, @ssl_ctx = build_ssl_ctx(options)
1443
+ handled = false
1393
1444
  error = nil
1394
1445
  ok = send_command("STARTTLS") do |resp|
1395
1446
  if resp.kind_of?(TaggedResponse) && resp.name == "OK"
1447
+ handled = true
1396
1448
  clear_cached_capabilities
1397
1449
  clear_responses
1398
1450
  start_tls_session
@@ -1404,6 +1456,13 @@ module Net
1404
1456
  disconnect
1405
1457
  raise error
1406
1458
  end
1459
+ unless handled
1460
+ disconnect
1461
+ raise InvalidResponseError,
1462
+ "STARTTLS handler was bypassed, although server responded %p" % [
1463
+ ok.raw_data.chomp
1464
+ ]
1465
+ end
1407
1466
  ok
1408
1467
  end
1409
1468
 
@@ -1825,12 +1884,18 @@ module Net
1825
1884
  # to both admin and user. If this mailbox exists, it returns an array
1826
1885
  # containing objects of type MailboxQuotaRoot and MailboxQuota.
1827
1886
  #
1887
+ # *NOTE:* Currently, Net::IMAP only supports +QUOTA+ responses with a single
1888
+ # resource type. This is usually +STORAGE+, but you may need to verify this
1889
+ # with UntaggedResponse#raw_data.
1890
+ #
1828
1891
  # Related: #getquota, #setquota, MailboxQuotaRoot, MailboxQuota
1829
1892
  #
1830
1893
  # ==== Capabilities
1831
1894
  #
1832
- # The server's capabilities must include +QUOTA+
1833
- # [RFC2087[https://www.rfc-editor.org/rfc/rfc2087]].
1895
+ # Requires +QUOTA+ [RFC2087[https://www.rfc-editor.org/rfc/rfc2087]]
1896
+ # capability, or a capability prefixed with <tt>QUOTA=RES-*</tt>
1897
+ # {[RFC9208]}[https://www.rfc-editor.org/rfc/rfc9208] for each supported
1898
+ # resource type.
1834
1899
  def getquotaroot(mailbox)
1835
1900
  synchronize do
1836
1901
  send_command("GETQUOTAROOT", mailbox)
@@ -1842,41 +1907,59 @@ module Net
1842
1907
  end
1843
1908
 
1844
1909
  # Sends a {GETQUOTA command [RFC2087 §4.2]}[https://www.rfc-editor.org/rfc/rfc2087#section-4.2]
1845
- # along with specified +mailbox+. If this mailbox exists, then an array
1846
- # containing a MailboxQuota object is returned. This command is generally
1847
- # only available to server admin.
1910
+ # for the +quota_root+. If this quota root exists, then an array
1911
+ # containing a MailboxQuota object is returned.
1912
+ #
1913
+ # The names of quota roots that are applicable to a particular mailbox can
1914
+ # be discovered with #getquotaroot.
1915
+ #
1916
+ # *NOTE:* Currently, Net::IMAP only supports +QUOTA+ responses with a single
1917
+ # resource type. This is usually +STORAGE+, but you may need to verify this
1918
+ # with UntaggedResponse#raw_data.
1848
1919
  #
1849
1920
  # Related: #getquotaroot, #setquota, MailboxQuota
1850
1921
  #
1851
1922
  # ==== Capabilities
1852
1923
  #
1853
- # The server's capabilities must include +QUOTA+
1854
- # [RFC2087[https://www.rfc-editor.org/rfc/rfc2087]].
1855
- def getquota(mailbox)
1924
+ # Requires +QUOTA+ [RFC2087[https://www.rfc-editor.org/rfc/rfc2087]]
1925
+ # capability, or a capability prefixed with <tt>QUOTA=RES-*</tt>
1926
+ # {[RFC9208]}[https://www.rfc-editor.org/rfc/rfc9208] for each supported
1927
+ # resource type.
1928
+ def getquota(quota_root)
1856
1929
  synchronize do
1857
- send_command("GETQUOTA", mailbox)
1930
+ send_command("GETQUOTA", quota_root)
1858
1931
  clear_responses("QUOTA")
1859
1932
  end
1860
1933
  end
1861
1934
 
1862
1935
  # Sends a {SETQUOTA command [RFC2087 §4.1]}[https://www.rfc-editor.org/rfc/rfc2087#section-4.1]
1863
- # along with the specified +mailbox+ and +quota+. If +quota+ is nil, then
1864
- # +quota+ will be unset for that mailbox. Typically one needs to be logged
1865
- # in as a server admin for this to work.
1936
+ # along with the specified +quota_root+ and +storage_limit+. If
1937
+ # +storage_limit+ is +nil+, resource limits are unset for that quota root.
1938
+ # If +storage_limit+ is a number, it sets the +STORAGE+ resource limit.
1939
+ #
1940
+ # imap.setquota "#user/alice", 100
1941
+ # imap.getquota "#user/alice"
1942
+ # # => [#<struct Net::IMAP::MailboxQuota mailbox="#user/alice" usage=54 quota=100>]
1943
+ #
1944
+ # Typically one needs to be logged in as a server admin for this to work.
1945
+ #
1946
+ # *NOTE:* Currently, Net::IMAP only supports setting +STORAGE+ quota limits.
1866
1947
  #
1867
1948
  # Related: #getquota, #getquotaroot
1868
1949
  #
1869
1950
  # ==== Capabilities
1870
1951
  #
1871
- # The server's capabilities must include +QUOTA+
1872
- # [RFC2087[https://www.rfc-editor.org/rfc/rfc2087]].
1873
- def setquota(mailbox, quota)
1874
- if quota.nil?
1875
- data = '()'
1952
+ # Requires +QUOTA+ [RFC2087[https://www.rfc-editor.org/rfc/rfc2087]]
1953
+ # capability, or a capability prefixed with <tt>QUOTA=RES-*</tt>
1954
+ # {[RFC9208]}[https://www.rfc-editor.org/rfc/rfc9208] for each supported
1955
+ # resource type.
1956
+ def setquota(quota_root, storage_limit)
1957
+ if storage_limit.nil?
1958
+ list = []
1876
1959
  else
1877
- data = '(STORAGE ' + quota.to_s + ')'
1960
+ list = ["STORAGE", NumValidator.coerce_number64(storage_limit)]
1878
1961
  end
1879
- send_command("SETQUOTA", mailbox, RawData.new(data))
1962
+ send_command("SETQUOTA", quota_root, list)
1880
1963
  end
1881
1964
 
1882
1965
  # Sends a {SETACL command [RFC4314 §3.1]}[https://www.rfc-editor.org/rfc/rfc4314#section-3.1]
@@ -1983,7 +2066,10 @@ module Net
1983
2066
  # <tt>STATUS=SIZE</tt>
1984
2067
  # {[RFC8483]}[https://www.rfc-editor.org/rfc/rfc8483.html].
1985
2068
  #
1986
- # +DELETED+ requires the server's capabilities to include +IMAP4rev2+.
2069
+ # +DELETED+ must be supported when the server's capabilities includes
2070
+ # +IMAP4rev2+.
2071
+ # or <tt>QUOTA=RES-MESSAGES</tt>
2072
+ # {[RFC9208]}[https://www.rfc-editor.org/rfc/rfc9208.html].
1987
2073
  #
1988
2074
  # +HIGHESTMODSEQ+ requires the server's capabilities to include +CONDSTORE+
1989
2075
  # {[RFC7162]}[https://www.rfc-editor.org/rfc/rfc7162.html].
@@ -2019,6 +2105,11 @@ module Net
2019
2105
  #
2020
2106
  # ==== Capabilities
2021
2107
  #
2108
+ # If +BINARY+ [RFC3516[https://www.rfc-editor.org/rfc/rfc3516.html]] is
2109
+ # supported by the server, +message+ may contain +NULL+ characters and
2110
+ # be sent as a binary literal. Otherwise, binary message parts must be
2111
+ # encoded appropriately (for example, +base64+).
2112
+ #
2022
2113
  # If +UIDPLUS+ [RFC4315[https://www.rfc-editor.org/rfc/rfc4315.html]] is
2023
2114
  # supported and the destination supports persistent UIDs, the server's
2024
2115
  # response should include an +APPENDUID+ response code with AppendUIDData.
@@ -2029,12 +2120,11 @@ module Net
2029
2120
  # TODO: add MULTIAPPEND support
2030
2121
  #++
2031
2122
  def append(mailbox, message, flags = nil, date_time = nil)
2123
+ message = StringFormatter.literal_or_literal8(message, name: "message")
2032
2124
  args = []
2033
- if flags
2034
- args.push(flags)
2035
- end
2125
+ args.push(flags) if flags
2036
2126
  args.push(date_time) if date_time
2037
- args.push(Literal.new(message))
2127
+ args.push(message)
2038
2128
  send_command("APPEND", mailbox, *args)
2039
2129
  end
2040
2130
 
@@ -2264,11 +2354,11 @@ module Net
2264
2354
  # Encoded as an \IMAP date (see ::encode_date).
2265
2355
  #
2266
2356
  # [When +criteria+ is a String]
2267
- # +criteria+ will be sent directly to the server <em>without any
2268
- # validation or encoding</em>.
2357
+ # +criteria+ will be sent to the server <em>with minimal validation and no
2358
+ # encoding or formatting</em>.
2269
2359
  #
2270
- # <em>*WARNING:* This is vulnerable to injection attacks when external
2271
- # inputs are used.</em>
2360
+ # <em>*WARNING:* Although CRLF is prohibited, this is vulnerable to other
2361
+ # types of attribute injection attack if unvetted user input is used.</em>
2272
2362
  #
2273
2363
  # ==== Supported return options
2274
2364
  #
@@ -2589,6 +2679,13 @@ module Net
2589
2679
  #
2590
2680
  # +attr+ is a list of attributes to fetch; see FetchStruct documentation for
2591
2681
  # a list of supported attributes.
2682
+ # >>>
2683
+ # When +attr+ is a String, it will be sent <em>with minimal validation and
2684
+ # no encoding or formatting</em>. When +attr+ is an Array, each String in
2685
+ # +attr+ will be sent this way.
2686
+ #
2687
+ # <em>*WARNING:* Although CRLF is prohibited, this is vulnerable to other
2688
+ # types of attribute injection attack if unvetted user input is used.</em>
2592
2689
  #
2593
2690
  # +changedsince+ is an optional integer mod-sequence. It limits results to
2594
2691
  # messages with a mod-sequence greater than +changedsince+.
@@ -3077,6 +3174,7 @@ module Net
3077
3174
 
3078
3175
  synchronize do
3079
3176
  tag = Thread.current[:net_imap_tag] = generate_tag
3177
+ guard_against_tagged_response_skipping_handler!(tag, "IDLE")
3080
3178
  put_string("#{tag} IDLE#{CRLF}")
3081
3179
 
3082
3180
  begin
@@ -3481,7 +3579,7 @@ module Net
3481
3579
  raise BadResponseError, resp
3482
3580
  else
3483
3581
  disconnect
3484
- raise InvalidResponseError, "invalid tagged resp: %p" % [resp.raw.chomp]
3582
+ raise InvalidResponseError, "invalid tagged resp: %p" % [resp.raw_data.chomp]
3485
3583
  end
3486
3584
  end
3487
3585
 
@@ -3541,21 +3639,29 @@ module Net
3541
3639
  put_string(" ")
3542
3640
  send_data(i, tag)
3543
3641
  end
3544
- put_string(CRLF)
3545
- if cmd == "LOGOUT"
3546
- @logout_command_tag = tag
3547
- end
3548
- if block
3549
- add_response_handler(&block)
3550
- end
3642
+ @logout_command_tag = tag if cmd == "LOGOUT"
3643
+ guard_against_tagged_response_skipping_handler!(tag, cmd)
3644
+ add_response_handler(&block) if block
3551
3645
  begin
3552
- return get_tagged_response(tag, cmd)
3646
+ put_string(CRLF)
3647
+ get_tagged_response(tag, cmd)
3553
3648
  ensure
3554
- if block
3555
- remove_response_handler(block)
3556
- end
3649
+ remove_response_handler(block) if block
3557
3650
  end
3558
3651
  end
3652
+ rescue InvalidResponseError
3653
+ disconnect
3654
+ raise
3655
+ end
3656
+
3657
+ def guard_against_tagged_response_skipping_handler!(tag, cmd)
3658
+ return unless (resp = @tagged_responses[tag])&.name&.upcase == "OK"
3659
+ raise InvalidResponseError, format(
3660
+ "Received tagged 'OK' to incomplete %s command (tag=%s). " \
3661
+ "This could indicate a malicious server, a man-in-the-middle, or " \
3662
+ "client-side command injection. Disconnecting.",
3663
+ cmd, tag
3664
+ )
3559
3665
  end
3560
3666
 
3561
3667
  def generate_tag
@@ -3709,7 +3815,7 @@ module Net
3709
3815
  end
3710
3816
 
3711
3817
  def store_internal(cmd, set, attr, flags, unchangedsince: nil)
3712
- attr = RawData.new(attr) if attr.instance_of?(String)
3818
+ attr = Atom.new(attr) if attr.instance_of?(String)
3713
3819
  args = [SequenceSet.new(set)]
3714
3820
  args << ["UNCHANGEDSINCE", Integer(unchangedsince)] if unchangedsince
3715
3821
  args << attr << flags
@@ -3781,7 +3887,7 @@ module Net
3781
3887
  params = (Hash.try_convert(ssl) || {}).freeze
3782
3888
  context = OpenSSL::SSL::SSLContext.new
3783
3889
  context.set_params(params)
3784
- context.freeze
3890
+ context.setup
3785
3891
  [params, context]
3786
3892
  else
3787
3893
  false
data/rakelib/rdoc.rake CHANGED
@@ -12,17 +12,6 @@ module RDoc::Generator
12
12
  end
13
13
  end
14
14
 
15
- # See https://github.com/ruby/rdoc/pull/936
16
- module FixSectionComments
17
- def markup(text)
18
- @store ||= @parent&.store
19
- super
20
- end
21
- def description; markup comment end
22
- def comment; super || @comments&.first end
23
- def parse(_comment_location = nil) super() end
24
- end
25
-
26
15
  # render "[label] data" lists as tables. adapted from "hanna-nouveau" gem.
27
16
  module LabelListTable
28
17
  def list_item_start(list_item, list_type)
@@ -51,20 +40,14 @@ class RDoc::AnyMethod
51
40
  prepend RDoc::Generator::NetIMAP::RemoveRedundantParens
52
41
  end
53
42
 
54
- class RDoc::Context::Section
55
- prepend RDoc::Generator::NetIMAP::FixSectionComments
56
- end
57
-
58
43
  class RDoc::Markup::ToHtml
59
44
  LIST_TYPE_TO_HTML[:NOTE] = ['<table class="rdoc-list note-list"><tbody>', '</tbody></table>']
60
45
  prepend RDoc::Generator::NetIMAP::LabelListTable
61
46
  end
62
47
 
63
48
  RDoc::Task.new do |doc|
64
- doc.main = "README.md"
65
49
  doc.title = "net-imap #{Net::IMAP::VERSION}"
66
50
  doc.rdoc_dir = "doc"
67
- doc.rdoc_files = FileList.new %w[lib/**/*.rb *.rdoc *.md]
68
51
  doc.options << "--template-stylesheets" << "docs/styles.css"
69
- # doc.generator = "hanna"
52
+ doc.generator = "darkfish" # TODO: fix issues with aliki
70
53
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: net-imap
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.3
4
+ version: 0.6.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shugo Maeda
@@ -46,6 +46,8 @@ executables: []
46
46
  extensions: []
47
47
  extra_rdoc_files: []
48
48
  files:
49
+ - ".document"
50
+ - ".rdoc_options"
49
51
  - BSDL
50
52
  - COPYING
51
53
  - Gemfile
@@ -129,7 +131,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
129
131
  - !ruby/object:Gem::Version
130
132
  version: '0'
131
133
  requirements: []
132
- rubygems_version: 4.0.6
134
+ rubygems_version: 4.0.10
133
135
  specification_version: 4
134
136
  summary: Ruby client api for Internet Message Access Protocol
135
137
  test_files: []