Skip to content

Commit 337c0e3

Browse files
nevanshsbt
authored andcommitted
[ruby/net-imap] Move UTF7 & datetime formatting to net/imap/data_encoding
Partially implements #10. ruby/net-imap@0d43c5e856
1 parent 4dc7b82 commit 337c0e3

File tree

4 files changed

+94
-78
lines changed

4 files changed

+94
-78
lines changed

lib/net/imap.rb

Lines changed: 1 addition & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
end
2424

2525
require_relative "imap/command_data"
26+
require_relative "imap/data_encoding"
2627
require_relative "imap/response_data"
2728
require_relative "imap/response_parser"
2829

@@ -1054,46 +1055,6 @@ def idle_done
10541055
end
10551056
end
10561057

1057-
# Decode a string from modified UTF-7 format to UTF-8.
1058-
#
1059-
# UTF-7 is a 7-bit encoding of Unicode [UTF7]. IMAP uses a
1060-
# slightly modified version of this to encode mailbox names
1061-
# containing non-ASCII characters; see [IMAP] section 5.1.3.
1062-
#
1063-
# Net::IMAP does _not_ automatically encode and decode
1064-
# mailbox names to and from UTF-7.
1065-
def self.decode_utf7(s)
1066-
return s.gsub(/&([^-]+)?-/n) {
1067-
if $1
1068-
($1.tr(",", "/") + "===").unpack1("m").encode(Encoding::UTF_8, Encoding::UTF_16BE)
1069-
else
1070-
"&"
1071-
end
1072-
}
1073-
end
1074-
1075-
# Encode a string from UTF-8 format to modified UTF-7.
1076-
def self.encode_utf7(s)
1077-
return s.gsub(/(&)|[^\x20-\x7e]+/) {
1078-
if $1
1079-
"&-"
1080-
else
1081-
base64 = [$&.encode(Encoding::UTF_16BE)].pack("m0")
1082-
"&" + base64.delete("=").tr("/", ",") + "-"
1083-
end
1084-
}.force_encoding("ASCII-8BIT")
1085-
end
1086-
1087-
# Formats +time+ as an IMAP-style date.
1088-
def self.format_date(time)
1089-
return time.strftime('%d-%b-%Y')
1090-
end
1091-
1092-
# Formats +time+ as an IMAP-style date-time.
1093-
def self.format_datetime(time)
1094-
return time.strftime('%d-%b-%Y %H:%M %z')
1095-
end
1096-
10971058
private
10981059

10991060
CRLF = "\r\n" # :nodoc:

lib/net/imap/data_encoding.rb

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# frozen_string_literal: true
2+
3+
module Net
4+
class IMAP < Protocol
5+
6+
# Decode a string from modified UTF-7 format to UTF-8.
7+
#
8+
# UTF-7 is a 7-bit encoding of Unicode [UTF7]. IMAP uses a
9+
# slightly modified version of this to encode mailbox names
10+
# containing non-ASCII characters; see [IMAP] section 5.1.3.
11+
#
12+
# Net::IMAP does _not_ automatically encode and decode
13+
# mailbox names to and from UTF-7.
14+
def self.decode_utf7(s)
15+
return s.gsub(/&([^-]+)?-/n) {
16+
if $1
17+
($1.tr(",", "/") + "===").unpack1("m").encode(Encoding::UTF_8, Encoding::UTF_16BE)
18+
else
19+
"&"
20+
end
21+
}
22+
end
23+
24+
# Encode a string from UTF-8 format to modified UTF-7.
25+
def self.encode_utf7(s)
26+
return s.gsub(/(&)|[^\x20-\x7e]+/) {
27+
if $1
28+
"&-"
29+
else
30+
base64 = [$&.encode(Encoding::UTF_16BE)].pack("m0")
31+
"&" + base64.delete("=").tr("/", ",") + "-"
32+
end
33+
}.force_encoding("ASCII-8BIT")
34+
end
35+
36+
# Formats +time+ as an IMAP-style date.
37+
def self.format_date(time)
38+
return time.strftime('%d-%b-%Y')
39+
end
40+
41+
# Formats +time+ as an IMAP-style date-time.
42+
def self.format_datetime(time)
43+
return time.strftime('%d-%b-%Y %H:%M %z')
44+
end
45+
46+
end
47+
end

test/net/imap/test_imap.rb

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -22,44 +22,6 @@ def teardown
2222
Socket.do_not_reverse_lookup = @do_not_reverse_lookup
2323
end
2424

25-
def test_encode_utf7
26-
assert_equal("foo", Net::IMAP.encode_utf7("foo"))
27-
assert_equal("&-", Net::IMAP.encode_utf7("&"))
28-
29-
utf8 = "\357\274\241\357\274\242\357\274\243".dup.force_encoding("UTF-8")
30-
s = Net::IMAP.encode_utf7(utf8)
31-
assert_equal("&,yH,Iv8j-", s)
32-
s = Net::IMAP.encode_utf7("foo&#{utf8}-bar".encode("EUC-JP"))
33-
assert_equal("foo&-&,yH,Iv8j--bar", s)
34-
35-
utf8 = "\343\201\202&".dup.force_encoding("UTF-8")
36-
s = Net::IMAP.encode_utf7(utf8)
37-
assert_equal("&MEI-&-", s)
38-
s = Net::IMAP.encode_utf7(utf8.encode("EUC-JP"))
39-
assert_equal("&MEI-&-", s)
40-
end
41-
42-
def test_decode_utf7
43-
assert_equal("&", Net::IMAP.decode_utf7("&-"))
44-
assert_equal("&-", Net::IMAP.decode_utf7("&--"))
45-
46-
s = Net::IMAP.decode_utf7("&,yH,Iv8j-")
47-
utf8 = "\357\274\241\357\274\242\357\274\243".dup.force_encoding("UTF-8")
48-
assert_equal(utf8, s)
49-
end
50-
51-
def test_format_date
52-
time = Time.mktime(2009, 7, 24)
53-
s = Net::IMAP.format_date(time)
54-
assert_equal("24-Jul-2009", s)
55-
end
56-
57-
def test_format_datetime
58-
time = Time.mktime(2009, 7, 24, 1, 23, 45)
59-
s = Net::IMAP.format_datetime(time)
60-
assert_match(/\A24-Jul-2009 01:23 [+\-]\d{4}\z/, s)
61-
end
62-
6325
if defined?(OpenSSL::SSL::SSLError)
6426
def test_imaps_unknown_ca
6527
assert_raise(OpenSSL::SSL::SSLError) do
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# frozen_string_literal: true
2+
3+
require "net/imap"
4+
require "test/unit"
5+
6+
class IMAPDataEncodingTest < Test::Unit::TestCase
7+
8+
def test_encode_utf7
9+
assert_equal("foo", Net::IMAP.encode_utf7("foo"))
10+
assert_equal("&-", Net::IMAP.encode_utf7("&"))
11+
12+
utf8 = "\357\274\241\357\274\242\357\274\243".dup.force_encoding("UTF-8")
13+
s = Net::IMAP.encode_utf7(utf8)
14+
assert_equal("&,yH,Iv8j-", s)
15+
s = Net::IMAP.encode_utf7("foo&#{utf8}-bar".encode("EUC-JP"))
16+
assert_equal("foo&-&,yH,Iv8j--bar", s)
17+
18+
utf8 = "\343\201\202&".dup.force_encoding("UTF-8")
19+
s = Net::IMAP.encode_utf7(utf8)
20+
assert_equal("&MEI-&-", s)
21+
s = Net::IMAP.encode_utf7(utf8.encode("EUC-JP"))
22+
assert_equal("&MEI-&-", s)
23+
end
24+
25+
def test_decode_utf7
26+
assert_equal("&", Net::IMAP.decode_utf7("&-"))
27+
assert_equal("&-", Net::IMAP.decode_utf7("&--"))
28+
29+
s = Net::IMAP.decode_utf7("&,yH,Iv8j-")
30+
utf8 = "\357\274\241\357\274\242\357\274\243".dup.force_encoding("UTF-8")
31+
assert_equal(utf8, s)
32+
end
33+
34+
def test_format_date
35+
time = Time.mktime(2009, 7, 24)
36+
s = Net::IMAP.format_date(time)
37+
assert_equal("24-Jul-2009", s)
38+
end
39+
40+
def test_format_datetime
41+
time = Time.mktime(2009, 7, 24, 1, 23, 45)
42+
s = Net::IMAP.format_datetime(time)
43+
assert_match(/\A24-Jul-2009 01:23 [+\-]\d{4}\z/, s)
44+
end
45+
46+
end

0 commit comments

Comments
 (0)