diff --git a/lib/net/imap.rb b/lib/net/imap.rb index b0fd5e53..c52b2498 100644 --- a/lib/net/imap.rb +++ b/lib/net/imap.rb @@ -1930,70 +1930,248 @@ def uid_expunge(uid_set) end # Sends a {SEARCH command [IMAP4rev1 §6.4.4]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.4.4] - # to search the mailbox for messages that match the given searching - # criteria, and returns message sequence numbers. +keys+ can either be a - # string holding the entire search string, or a single-dimension array of - # search keywords and arguments. - # - # Returns a SearchResult object. SearchResult inherits from Array (for + # to search the mailbox for messages that match the given search +criteria+, + # and returns a SearchResult. SearchResult inherits from Array (for # backward compatibility) but adds SearchResult#modseq when the +CONDSTORE+ # capability has been enabled. # + # +criteria+ is one or more search keys and their arguments, which may be + # provided as an array or a string. + # See {"Search criteria"}[rdoc-ref:#search@Search+criteria], below. + # + # * When +criteria+ is an array, each member is a +SEARCH+ command argument: + # * Any SequenceSet sends SequenceSet#valid_string. + # +Range+, -1, and nested +Array+ elements are converted to + # SequenceSet. + # * Any +String+ is sent verbatim when it is a valid \IMAP atom, + # and encoded as an \IMAP quoted or literal string otherwise. + # * Any other +Integer+ (besides -1) will be sent as +#to_s+. + # * +Date+ objects will be encoded as an \IMAP date (see ::encode_date). + # + # * When +criteria+ is a string, it will be sent directly to the server + # without any validation or encoding. *WARNING:* This is + # vulnerable to injection attacks when external inputs are used. + # + # +charset+ is the name of the {registered character + # set}[https://www.iana.org/assignments/character-sets/character-sets.xhtml] + # used by strings in the search +criteria+. When +charset+ isn't specified, + # either "US-ASCII" or "UTF-8" is assumed, depending on + # the server's capabilities. +charset+ may be sent inside +criteria+ + # instead of as a separate argument. + # # Related: #uid_search # - # ===== Search criteria + # ===== For example: # - # For a full list of search criteria, + # p imap.search(["SUBJECT", "hello", "NOT", "SEEN"]) + # #=> [1, 6, 7, 8] + # + # The following searches send the exact same command to the server: + # + # # criteria array, charset arg + # imap.search(%w[OR UNSEEN FLAGGED SUBJECT foo], "UTF-8") + # # criteria string, charset arg + # imap.search("OR UNSEEN FLAGGED SUBJECT foo", "UTF-8") + # # criteria array contains charset arg + # imap.search(%w[CHARSET UTF-8 OR UNSEEN FLAGGED SUBJECT foo]) + # # criteria string contains charset arg + # imap.search("CHARSET UTF-8 OR UNSEEN FLAGGED SUBJECT foo") + # + # ===== Search keys + # + # For full definitions of the standard search +criteria+, # see [{IMAP4rev1 §6.4.4}[https://www.rfc-editor.org/rfc/rfc3501.html#section-6.4.4]], # or [{IMAP4rev2 §6.4.4}[https://www.rfc-editor.org/rfc/rfc9051.html#section-6.4.4]], # in addition to documentation for - # any [CAPABILITIES[https://www.iana.org/assignments/imap-capabilities/imap-capabilities.xhtml]] - # reported by #capabilities which may define additional search filters, e.g: + # any #capabilities which may define additional search filters, such as # +CONDSTORE+, +WITHIN+, +FILTERS+, SEARCH=FUZZY, +OBJECTID+, or - # +SAVEDATE+. The following are some common search criteria: + # +SAVEDATE+. + # + # With the exception of sequence-set and parenthesized + # list, all search keys are composed of prefix label with zero or more + # arguments. The number and type of arguments is specific to each search + # key. + # + # +ALL+:: + # Matches every message in the mailbox. + # + # (_search-key_ _search-key_...):: + # Combines one or more _search-key_ arguments to match + # messages which match all contained search keys. Useful for +OR+, +NOT+, + # and other search keys with _search-key_ arguments. + # + # _Note:_ this search key has no label. + # + # +OR+ _search-key_ _search-key_:: + # Matches messages which match either _search-key_ argument. + # + # +NOT+ _search-key_:: + # Matches messages which do not match _search-key_. + # + # _sequence-set_:: + # Matches messages with message sequence numbers in _sequence-set_. + # + # _Note:_ this search key has no label. + # + # +UIDONLY+ must *not* be enabled. + # {[RFC9586]}[https://www.rfc-editor.org/rfc/rfc9586.html] + # + # +UID+ _sequence-set_:: + # Matches messages with a UID in _sequence-set_. + # + # +ANSWERED+:: + # +UNANSWERED+:: + # Matches messages with or without the \\Answered flag. + # +DELETED+:: + # +UNDELETED+:: + # Matches messages with or without the \\Deleted flag. + # +DRAFT+:: + # +UNDRAFT+:: + # Matches messages with or without the \\Draft flag. + # +FLAGGED+:: + # +UNFLAGGED+:: + # Matches messages with or without the \\Flagged flag. + # +SEEN+:: + # +UNSEEN+:: + # Matches messages with or without the \\Seen flag. + # + # +KEYWORD+ _keyword_:: + # +UNKEYWORD+ _keyword_:: + # Matches messages with or without the specified _keyword_. + # + # +BCC+ _substring_:: + # Matches when _substring_ is in the envelope's BCC field. + # +CC+ _substring_:: + # Matches when _substring_ is in the envelope's CC field. + # +FROM+ _substring_:: + # Matches when _substring_ is in the envelope's FROM field. + # +SUBJECT+ _substring_:: + # Matches when _substring_ is in the envelope's SUBJECT field. + # +TO+ _substring_:: + # Matches when _substring_ is in the envelope's TO field. + # + # +HEADER+ _field_ _substring_:: + # Matches when _substring_ is in the specified header _field_. + # + # +BODY+ _string_:: + # Matches when _string_ is in the body of the message. + # Does not match on header fields. + # + # The server _may_ use flexible matching, rather than simple substring + # matches. For example, this may use stemming or match only full words. + # + # +TEXT+ _string_:: + # Matches when _string_ is in the header or body of the message. + # + # The server _may_ use flexible matching, rather than simple substring + # matches. For example, this may use stemming or match only full words. + # + # +BEFORE+ _date_:: + # +ON+ _date_:: + # +SINCE+ _date_:: + # Matches when the +INTERNALDATE+ is earlier than, on, or later than + # _date_. + # + # +SENTBEFORE+ _date_:: + # +SENTON+ _date_:: + # +SENTSINCE+ _date_:: + # Matches when the +Date+ header is earlier than, on, or later than _date_. + # + # +SMALLER+ _bytes_:: + # +LARGER+ _bytes_:: + # Matches when +RFC822.SIZE+ is smaller/larger than _bytes_. + # + # ====== Removed from +IMAP4rev2+ + # + # The \\Recent flag has been removed from +IMAP4rev2+. So these + # search keys require the +IMAP4rev1+ capability. + # + # +RECENT+:: + # +UNRECENT+:: + # Matches messages with or without the \\Recent flag. # - # :: a set of message sequence numbers. "," indicates - # an interval, "+:+" indicates a range. For instance, - # "2,10:12,15" means "2,10,11,12,15". + # +NEW+:: + # Equivalent to (RECENT UNSEEN). # - # BEFORE :: messages with an internal date strictly before - # . The date argument has a format similar - # to 8-Aug-2002, and can be formatted using - # Net::IMAP.format_date. + # ====== Extension search keys # - # BODY :: messages that contain within their body. + # The search keys described below are defined by standard \IMAP extensions. # - # CC :: messages containing in their CC field. + # +OLDER+ _interval_:: + # +YOUNGER+ _interval_:: + # Matches when +INTERNALDATE+ is more/less than _interval_ seconds ago. # - # FROM :: messages that contain in their FROM field. + # Requires the +WITHIN+ capability. + # {[RFC5032]}[https://www.rfc-editor.org/rfc/rfc5032.html] # - # NEW:: messages with the \Recent, but not the \Seen, flag set. + # +ANNOTATION+ _entry_ _attr_ _value_:: + # Matches messages that have annotations with entries matching _entry_, + # attributes matching _attr_, and _value_ in the attribute's values. # - # NOT :: negate the following search key. + # Requires the +ANNOTATE-EXPERIMENT-1+ capability. + # {[RFC5257]}[https://www.rfc-editor.org/rfc/rfc5257.html]. # - # OR :: "or" two search keys together. + # +FILTER+ _filter_:: + # References a _filter_ that is stored on the server and matches all + # messages which would be matched by that filter's search criteria. # - # ON :: messages with an internal date exactly equal to , - # which has a format similar to 8-Aug-2002. + # Requires the +FILTERS+ capability. + # {[RFC5466]}[https://www.rfc-editor.org/rfc/rfc5466.html#section-3.1] # - # SINCE :: messages with an internal date on or after . + # +FUZZY+ _search-key_:: + # Uses fuzzy matching for the specified search key. # - # SUBJECT :: messages with in their subject. + # Requires the SEARCH=FUZZY capability. + # {[RFC6203]}[https://www.rfc-editor.org/rfc/rfc6203.html#section-6]. # - # TO :: messages with in their TO field. + # +MODSEQ+ _modseq_:: + # Matches when +MODSEQ+ is greater than or equal to _modseq_. # - # ===== For example: + # Requires the +CONDSTORE+ capability. + # {[RFC7162]}[https://www.rfc-editor.org/rfc/rfc7162.html#section-3.1.5]. # - # p imap.search(["SUBJECT", "hello", "NOT", "NEW"]) - # #=> [1, 6, 7, 8] + # +MODSEQ+ _entry_ _entry-type_ _modseq_:: + # Matches when a specific metadata _entry_ has been updated since + # _modseq_. + # + # For flags, the corresponding _entry_ name is + # "/flags/#{flag_name}", where _flag_name_ includes the + # \\ prefix. _entry-type_ can be one of "shared", + # "priv" (private), or "all". + # + # Requires the +CONDSTORE+ capability. + # {[RFC7162]}[https://www.rfc-editor.org/rfc/rfc7162.html#section-3.1.5]. + # + # +EMAILID+ _objectid_:: + # +THREADID+ _objectid_:: + # Matches when +EMAILID+/+THREADID+ is equal to _objectid_ + # (substring matches are not supported). + # + # Requires the +OBJECTID+ capability. + # {[RFC8474]}[https://www.rfc-editor.org/rfc/rfc8474.html#section-6] + # + # +SAVEDATESUPPORTED+:: + # Matches every message in the mailbox when the mailbox supports the save + # date attribute. Otherwise, it matches no messages. + # + # Requires the +SAVEDATE+ capability. + # {[RFC8514]}[https://www.rfc-editor.org/rfc/rfc8514.html#section-4.3] + # + # +SAVEDBEFORE+ _date_:: + # +SAVEDON+ _date_:: + # +SAVEDSINCE+ _date_:: + # Matches when the save date is earlier than, on, or later than _date_. + # + # Requires the +SAVEDATE+ capability. + # {[RFC8514]}[https://www.rfc-editor.org/rfc/rfc8514.html#section-4.3] # # ===== Capabilities # - # If [CONDSTORE[https://www.rfc-editor.org/rfc/rfc7162.html]] is supported + # If CONDSTORE[https://www.rfc-editor.org/rfc/rfc7162.html] is supported # and enabled for the selected mailbox, a non-empty SearchResult will # include a +MODSEQ+ value. # imap.select("mbox", condstore: true) - # result = imap.search(["SUBJECT", "hi there", "not", "new") + # result = imap.search(["SUBJECT", "hi there", "not", "new"]) # #=> Net::IMAP::SearchResult[1, 6, 7, 8, modseq: 5594] # result.modseq # => 5594 def search(keys, charset = nil) @@ -2008,7 +2186,7 @@ def search(keys, charset = nil) # backward compatibility) but adds SearchResult#modseq when the +CONDSTORE+ # capability has been enabled. # - # See #search for documentation of search criteria. + # See #search for documentation of parameters. def uid_search(keys, charset = nil) return search_internal("UID SEARCH", keys, charset) end