Skip to content

Commit

Permalink
🔀 Merge pull request #114 from arnt/utf8accept
Browse files Browse the repository at this point in the history
Minor bits for UTF8=ACCEPT
  • Loading branch information
nevans authored Feb 22, 2023
2 parents a00e2e3 + e0656f3 commit e5bcb67
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 19 deletions.
24 changes: 11 additions & 13 deletions lib/net/imap.rb
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ module Net
#
# ==== RFC6855: <tt>UTF8=ACCEPT</tt>, <tt>UTF8=ONLY</tt>
#
# - See #enable for information about support foi UTF-8 string encoding.
# - See #enable for information about support for UTF-8 string encoding.
#
#--
# ==== RFC7888: <tt>LITERAL+</tt>, +LITERAL-+
Expand Down Expand Up @@ -1931,20 +1931,14 @@ def uid_thread(algorithm, search_keys, charset)
# UTF-7}[::decode_utf7] for mailbox names, or RFC2047 encoded-words for
# message headers.
#
# *Note:* For now, strings with 8-bit characters are still _sent_ using
# "literal" syntax. A future update will change how commands send UTF-8
# strings when <tt>UTF8=ACCEPT</tt> is enabled. This update should be
# backward-compatible.
#
# *Note:* <em>A future update may set string encodings slightly
# differently</em>, e.g: "US-ASCII" when UTF-8 is not enabled, and "UTF-8"
# when it is. Currently, the encoding of strings sent as "quoted" or
# "text" will _always_ be "UTF-8", even when a 7-bit encoding is used
# (e.g. UTF-7, encoded-words, quoted-printable, base64). And currently,
# string "literals" sent by the server will always have an "ASCII-8BIT"
# (binary) encoding, even if they must contain UTF-8 data---although a
# server _should_ use "quoted" strings once <tt>UTF8=ACCEPT</tt> is
# enabled.
# "text" will _always_ be "UTF-8", even when only ASCII characters are
# used (e.g. "Subject: Agenda") And currently, string "literals" sent
# by the server will always have an "ASCII-8BIT" (binary)
# encoding, even if they generally contain UTF-8 data, if they are
# text at all.
#
# [<tt>"UTF8=ONLY"</tt> [RFC6855[https://tools.ietf.org/html/rfc6855]]]
#
Expand Down Expand Up @@ -1974,7 +1968,10 @@ def enable(*capabilities)
.join(' ')
synchronize do
send_command("ENABLE #{capabilities}")
return @responses.delete("ENABLED")[-1]
result = @responses.delete("ENABLED")[-1]
@utf8_strings ||= result.include? "UTF8=ACCEPT"
@utf8_strings ||= result.include? "IMAP4REV2"
result
end
end

Expand Down Expand Up @@ -2222,6 +2219,7 @@ def initialize(host, port_or_options = {},
@port = options[:port] || (options[:ssl] ? SSL_PORT : PORT)
@tag_prefix = "RUBY"
@tagno = 0
@utf8_strings = false
@open_timeout = options[:open_timeout] || 30
@idle_response_timeout = options[:idle_response_timeout] || 5
@parser = ResponseParser.new
Expand Down
19 changes: 13 additions & 6 deletions lib/net/imap/command_data.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,20 @@ def send_data(data, tag = nil)
end

def send_string_data(str, tag = nil)
case str
when ""
if str.empty?
put_string('""')
when /[\x80-\xff\r\n]/n
# literal
elsif str.match?(/[\r\n]/n)
# literal, because multiline
send_literal(str, tag)
when /[(){ \x00-\x1f\x7f%*"\\]/n
elsif !str.ascii_only?
if @utf8_strings
# quoted string
send_quoted_string(str)
else
# literal, because of non-ASCII bytes
send_literal(str, tag)
end
elsif str.match?(/[(){ \x00-\x1f\x7f%*"\\]/n)
# quoted string
send_quoted_string(str)
else
Expand All @@ -67,7 +74,7 @@ def send_string_data(str, tag = nil)
end

def send_quoted_string(str)
put_string('"' + str.gsub(/["\\]/n, "\\\\\\&") + '"')
put_string('"' + str.gsub(/["\\]/, "\\\\\\&") + '"')
end

def send_literal(str, tag = nil)
Expand Down

0 comments on commit e5bcb67

Please sign in to comment.