ruby-changes:66076
From: nicholas <ko1@a...>
Date: Thu, 6 May 2021 15:20:59 +0900 (JST)
Subject: [ruby-changes:66076] 337c0e312b (master): [ruby/net-imap] Move UTF7 & datetime formatting to net/imap/data_encoding
https://git.ruby-lang.org/ruby.git/commit/?id=337c0e312b From 337c0e312bc4e8a13ee90b9d7b102664661cf9a7 Mon Sep 17 00:00:00 2001 From: "nicholas a. evans" <nicholas.evans@g...> Date: Tue, 4 May 2021 14:52:38 -0400 Subject: [ruby/net-imap] Move UTF7 & datetime formatting to net/imap/data_encoding Partially implements #10. https://github.com/ruby/net-imap/commit/0d43c5e856 --- lib/net/imap.rb | 41 +--------------------------- lib/net/imap/data_encoding.rb | 47 ++++++++++++++++++++++++++++++++ test/net/imap/test_imap.rb | 38 -------------------------- test/net/imap/test_imap_data_encoding.rb | 46 +++++++++++++++++++++++++++++++ 4 files changed, 94 insertions(+), 78 deletions(-) create mode 100644 lib/net/imap/data_encoding.rb create mode 100644 test/net/imap/test_imap_data_encoding.rb diff --git a/lib/net/imap.rb b/lib/net/imap.rb index fe56bc0..862b10e 100644 --- a/lib/net/imap.rb +++ b/lib/net/imap.rb @@ -23,6 +23,7 @@ rescue LoadError https://github.com/ruby/ruby/blob/trunk/lib/net/imap.rb#L23 end require_relative "imap/command_data" +require_relative "imap/data_encoding" require_relative "imap/response_data" require_relative "imap/response_parser" @@ -1054,46 +1055,6 @@ module Net https://github.com/ruby/ruby/blob/trunk/lib/net/imap.rb#L1055 end end - # Decode a string from modified UTF-7 format to UTF-8. - # - # UTF-7 is a 7-bit encoding of Unicode [UTF7]. IMAP uses a - # slightly modified version of this to encode mailbox names - # containing non-ASCII characters; see [IMAP] section 5.1.3. - # - # Net::IMAP does _not_ automatically encode and decode - # mailbox names to and from UTF-7. - def self.decode_utf7(s) - return s.gsub(/&([^-]+)?-/n) { - if $1 - ($1.tr(",", "/") + "===").unpack1("m").encode(Encoding::UTF_8, Encoding::UTF_16BE) - else - "&" - end - } - end - - # Encode a string from UTF-8 format to modified UTF-7. - def self.encode_utf7(s) - return s.gsub(/(&)|[^\x20-\x7e]+/) { - if $1 - "&-" - else - base64 = [$&.encode(Encoding::UTF_16BE)].pack("m0") - "&" + base64.delete("=").tr("/", ",") + "-" - end - }.force_encoding("ASCII-8BIT") - end - - # Formats +time+ as an IMAP-style date. - def self.format_date(time) - return time.strftime('%d-%b-%Y') - end - - # Formats +time+ as an IMAP-style date-time. - def self.format_datetime(time) - return time.strftime('%d-%b-%Y %H:%M %z') - end - private CRLF = "\r\n" # :nodoc: diff --git a/lib/net/imap/data_encoding.rb b/lib/net/imap/data_encoding.rb new file mode 100644 index 0000000..d8449f5 --- /dev/null +++ b/lib/net/imap/data_encoding.rb @@ -0,0 +1,47 @@ https://github.com/ruby/ruby/blob/trunk/lib/net/imap/data_encoding.rb#L1 +# frozen_string_literal: true + +module Net + class IMAP < Protocol + + # Decode a string from modified UTF-7 format to UTF-8. + # + # UTF-7 is a 7-bit encoding of Unicode [UTF7]. IMAP uses a + # slightly modified version of this to encode mailbox names + # containing non-ASCII characters; see [IMAP] section 5.1.3. + # + # Net::IMAP does _not_ automatically encode and decode + # mailbox names to and from UTF-7. + def self.decode_utf7(s) + return s.gsub(/&([^-]+)?-/n) { + if $1 + ($1.tr(",", "/") + "===").unpack1("m").encode(Encoding::UTF_8, Encoding::UTF_16BE) + else + "&" + end + } + end + + # Encode a string from UTF-8 format to modified UTF-7. + def self.encode_utf7(s) + return s.gsub(/(&)|[^\x20-\x7e]+/) { + if $1 + "&-" + else + base64 = [$&.encode(Encoding::UTF_16BE)].pack("m0") + "&" + base64.delete("=").tr("/", ",") + "-" + end + }.force_encoding("ASCII-8BIT") + end + + # Formats +time+ as an IMAP-style date. + def self.format_date(time) + return time.strftime('%d-%b-%Y') + end + + # Formats +time+ as an IMAP-style date-time. + def self.format_datetime(time) + return time.strftime('%d-%b-%Y %H:%M %z') + end + + end +end diff --git a/test/net/imap/test_imap.rb b/test/net/imap/test_imap.rb index 49e1467..46008b0 100644 --- a/test/net/imap/test_imap.rb +++ b/test/net/imap/test_imap.rb @@ -22,44 +22,6 @@ class IMAPTest < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/net/imap/test_imap.rb#L22 Socket.do_not_reverse_lookup = @do_not_reverse_lookup end - def test_encode_utf7 - assert_equal("foo", Net::IMAP.encode_utf7("foo")) - assert_equal("&-", Net::IMAP.encode_utf7("&")) - - utf8 = "\357\274\241\357\274\242\357\274\243".dup.force_encoding("UTF-8") - s = Net::IMAP.encode_utf7(utf8) - assert_equal("&,yH,Iv8j-", s) - s = Net::IMAP.encode_utf7("foo&#{utf8}-bar".encode("EUC-JP")) - assert_equal("foo&-&,yH,Iv8j--bar", s) - - utf8 = "\343\201\202&".dup.force_encoding("UTF-8") - s = Net::IMAP.encode_utf7(utf8) - assert_equal("&MEI-&-", s) - s = Net::IMAP.encode_utf7(utf8.encode("EUC-JP")) - assert_equal("&MEI-&-", s) - end - - def test_decode_utf7 - assert_equal("&", Net::IMAP.decode_utf7("&-")) - assert_equal("&-", Net::IMAP.decode_utf7("&--")) - - s = Net::IMAP.decode_utf7("&,yH,Iv8j-") - utf8 = "\357\274\241\357\274\242\357\274\243".dup.force_encoding("UTF-8") - assert_equal(utf8, s) - end - - def test_format_date - time = Time.mktime(2009, 7, 24) - s = Net::IMAP.format_date(time) - assert_equal("24-Jul-2009", s) - end - - def test_format_datetime - time = Time.mktime(2009, 7, 24, 1, 23, 45) - s = Net::IMAP.format_datetime(time) - assert_match(/\A24-Jul-2009 01:23 [+\-]\d{4}\z/, s) - end - if defined?(OpenSSL::SSL::SSLError) def test_imaps_unknown_ca assert_raise(OpenSSL::SSL::SSLError) do diff --git a/test/net/imap/test_imap_data_encoding.rb b/test/net/imap/test_imap_data_encoding.rb new file mode 100644 index 0000000..2ca1c18 --- /dev/null +++ b/test/net/imap/test_imap_data_encoding.rb @@ -0,0 +1,46 @@ https://github.com/ruby/ruby/blob/trunk/test/net/imap/test_imap_data_encoding.rb#L1 +# frozen_string_literal: true + +require "net/imap" +require "test/unit" + +class IMAPDataEncodingTest < Test::Unit::TestCase + + def test_encode_utf7 + assert_equal("foo", Net::IMAP.encode_utf7("foo")) + assert_equal("&-", Net::IMAP.encode_utf7("&")) + + utf8 = "\357\274\241\357\274\242\357\274\243".dup.force_encoding("UTF-8") + s = Net::IMAP.encode_utf7(utf8) + assert_equal("&,yH,Iv8j-", s) + s = Net::IMAP.encode_utf7("foo&#{utf8}-bar".encode("EUC-JP")) + assert_equal("foo&-&,yH,Iv8j--bar", s) + + utf8 = "\343\201\202&".dup.force_encoding("UTF-8") + s = Net::IMAP.encode_utf7(utf8) + assert_equal("&MEI-&-", s) + s = Net::IMAP.encode_utf7(utf8.encode("EUC-JP")) + assert_equal("&MEI-&-", s) + end + + def test_decode_utf7 + assert_equal("&", Net::IMAP.decode_utf7("&-")) + assert_equal("&-", Net::IMAP.decode_utf7("&--")) + + s = Net::IMAP.decode_utf7("&,yH,Iv8j-") + utf8 = "\357\274\241\357\274\242\357\274\243".dup.force_encoding("UTF-8") + assert_equal(utf8, s) + end + + def test_format_date + time = Time.mktime(2009, 7, 24) + s = Net::IMAP.format_date(time) + assert_equal("24-Jul-2009", s) + end + + def test_format_datetime + time = Time.mktime(2009, 7, 24, 1, 23, 45) + s = Net::IMAP.format_datetime(time) + assert_match(/\A24-Jul-2009 01:23 [+\-]\d{4}\z/, s) + end + +end -- cgit v1.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/