1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
|
require "net/imap"
require "test/unit"
class IMAPResponseParserTest < Test::Unit::TestCase
def setup
@do_not_reverse_lookup = Socket.do_not_reverse_lookup
Socket.do_not_reverse_lookup = true
if Net::IMAP.respond_to?(:max_flag_count)
@max_flag_count = Net::IMAP.max_flag_count
Net::IMAP.max_flag_count = 3
end
end
def teardown
Socket.do_not_reverse_lookup = @do_not_reverse_lookup
if Net::IMAP.respond_to?(:max_flag_count)
Net::IMAP.max_flag_count = @max_flag_count
end
end
def test_flag_list_safe
parser = Net::IMAP::ResponseParser.new
response = lambda {
$SAFE = 1
parser.parse(<<EOF.gsub(/\n/, "\r\n").taint)
* LIST (\\HasChildren) "." "INBOX"
EOF
}.call
assert_equal [:Haschildren], response.data.attr
end
def test_flag_list_too_many_flags
parser = Net::IMAP::ResponseParser.new
assert_nothing_raised do
3.times do |i|
parser.parse(<<EOF.gsub(/\n/, "\r\n").taint)
* LIST (\\Foo#{i}) "." "INBOX"
EOF
end
end
assert_raise(Net::IMAP::FlagCountError) do
parser.parse(<<EOF.gsub(/\n/, "\r\n").taint)
* LIST (\\Foo3) "." "INBOX"
EOF
end
end
def test_flag_list_many_same_flags
parser = Net::IMAP::ResponseParser.new
assert_nothing_raised do
100.times do
parser.parse(<<EOF.gsub(/\n/, "\r\n").taint)
* LIST (\\Foo) "." "INBOX"
EOF
end
end
end
def test_flag_xlist_inbox
parser = Net::IMAP::ResponseParser.new
response = parser.parse(<<EOF.gsub(/\n/, "\r\n").taint)
* XLIST (\\Inbox) "." "INBOX"
EOF
assert_equal [:Inbox], response.data.attr
end
def test_resp_text_code
parser = Net::IMAP::ResponseParser.new
response = parser.parse(<<EOF.gsub(/\n/, "\r\n").taint)
* OK [CLOSED] Previous mailbox closed.
EOF
assert_equal "CLOSED", response.data.code.name
end
def test_search_response
parser = Net::IMAP::ResponseParser.new
response = parser.parse(<<EOF.gsub(/\n/, "\r\n").taint)
* SEARCH
EOF
assert_equal [], response.data
response = parser.parse(<<EOF.gsub(/\n/, "\r\n").taint)
* SEARCH 1
EOF
assert_equal [1], response.data
response = parser.parse(<<EOF.gsub(/\n/, "\r\n").taint)
* SEARCH 1 2 3
EOF
assert_equal [1, 2, 3], response.data
end
def test_search_response_of_yahoo
parser = Net::IMAP::ResponseParser.new
response = parser.parse(<<EOF.gsub(/\n/, "\r\n").taint)
* SEARCH 1\s
EOF
assert_equal [1], response.data
response = parser.parse(<<EOF.gsub(/\n/, "\r\n").taint)
* SEARCH 1 2 3\s
EOF
assert_equal [1, 2, 3], response.data
end
def test_msg_att_extra_space
parser = Net::IMAP::ResponseParser.new
response = parser.parse(<<EOF.gsub(/\n/, "\r\n").taint)
* 1 FETCH (UID 92285)
EOF
assert_equal 92285, response.data.attr["UID"]
response = parser.parse(<<EOF.gsub(/\n/, "\r\n").taint)
* 1 FETCH (UID 92285 )
EOF
assert_equal 92285, response.data.attr["UID"]
end
def test_msg_att_parse_error
parser = Net::IMAP::ResponseParser.new
e = assert_raise(Net::IMAP::ResponseParseError) {
parser.parse(<<EOF.gsub(/\n/, "\r\n").taint)
* 123 FETCH (UNKNOWN 92285)
EOF
}
assert_match(/ for \{123\}/, e.message)
end
def test_msg_att_rfc822_text
parser = Net::IMAP::ResponseParser.new
response = parser.parse(<<EOF.gsub(/\n/, "\r\n").taint)
* 123 FETCH (RFC822 {5}
foo
)
EOF
assert_equal("foo\r\n", response.data.attr["RFC822"])
response = parser.parse(<<EOF.gsub(/\n/, "\r\n").taint)
* 123 FETCH (RFC822[] {5}
foo
)
EOF
assert_equal("foo\r\n", response.data.attr["RFC822"])
end
# [Bug #6397] [ruby-core:44849]
def test_body_type_attachment
parser = Net::IMAP::ResponseParser.new
response = parser.parse(<<EOF.gsub(/\n/, "\r\n").taint)
* 980 FETCH (UID 2862 BODYSTRUCTURE ((("TEXT" "PLAIN" ("CHARSET" "iso-8859-1") NIL NIL "7BIT" 416 21 NIL NIL NIL)("TEXT" "HTML" ("CHARSET" "iso-8859-1") NIL NIL "7BIT" 1493 32 NIL NIL NIL) "ALTERNATIVE" ("BOUNDARY" "Boundary_(ID_IaecgfnXwG5bn3x8lIeGIQ)") NIL NIL)("MESSAGE" "RFC822" ("NAME" "Fw_ ____ _____ ____.eml") NIL NIL "7BIT" 1980088 NIL ("ATTACHMENT" ("FILENAME" "Fw_ ____ _____ ____.eml")) NIL) "MIXED" ("BOUNDARY" "Boundary_(ID_eDdLc/j0mBIzIlR191pHjA)") NIL NIL))
EOF
assert_equal("Fw_ ____ _____ ____.eml",
response.data.attr["BODYSTRUCTURE"].parts[1].body.param["FILENAME"])
end
def assert_parseable(s)
parser = Net::IMAP::ResponseParser.new
parser.parse(s.gsub(/\n/, "\r\n").taint)
end
# [Bug #7146]
def test_msg_delivery_status
# This was part of a larger response that caused crashes, but this was the
# minimal test case to demonstrate it
assert_parseable <<EOF
* 4902 FETCH (BODY (("MESSAGE" "DELIVERY-STATUS" NIL NIL NIL "7BIT" 324) "REPORT"))
EOF
end
# [Bug #7147]
def test_msg_with_message_rfc822_attachment
assert_parseable <<EOF
* 5441 FETCH (BODY ((("TEXT" "PLAIN" ("CHARSET" "iso-8859-1") NIL NIL "QUOTED-PRINTABLE" 69 1)("TEXT" "HTML" ("CHARSET" "iso-8859-1") NIL NIL "QUOTED-PRINTABLE" 455 12) "ALTERNATIVE")("MESSAGE" "RFC822" ("NAME" "ATT00026.eml") NIL NIL "7BIT" 4079755) "MIXED"))
EOF
end
# [Bug #7153]
def test_msg_body_mixed
assert_parseable <<EOF
* 1038 FETCH (BODY ("MIXED"))
EOF
end
# [Bug #8167]
def test_msg_delivery_status_with_extra_data
parser = Net::IMAP::ResponseParser.new
response = parser.parse(<<EOF.gsub(/\n/, "\r\n").taint)
* 29021 FETCH (RFC822.SIZE 3162 UID 113622 RFC822.HEADER {1155}
Return-path: <>
Envelope-to: info@xxxxxxxx.si
Delivery-date: Tue, 26 Mar 2013 12:42:58 +0100
Received: from mail by xxxx.xxxxxxxxxxx.net with spam-scanned (Exim 4.76)
id 1UKSHI-000Cwl-AR
for info@xxxxxxxx.si; Tue, 26 Mar 2013 12:42:58 +0100
X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on xxxx.xxxxxxxxxxx.net
X-Spam-Level: **
X-Spam-Status: No, score=2.1 required=7.0 tests=DKIM_ADSP_NXDOMAIN,RDNS_NONE
autolearn=no version=3.3.1
Received: from [xx.xxx.xxx.xx] (port=56890 helo=xxxxxx.localdomain)
by xxxx.xxxxxxxxxxx.net with esmtp (Exim 4.76)
id 1UKSHI-000Cwi-9j
for info@xxxxxxxx.si; Tue, 26 Mar 2013 12:42:56 +0100
Received: by xxxxxx.localdomain (Postfix)
id 72725BEA64A; Tue, 26 Mar 2013 12:42:55 +0100 (CET)
Date: Tue, 26 Mar 2013 12:42:55 +0100 (CET)
From: MAILER-DAEMON@xxxxxx.localdomain (Mail Delivery System)
Subject: Undelivered Mail Returned to Sender
To: info@xxxxxxxx.si
Auto-Submitted: auto-replied
MIME-Version: 1.0
Content-Type: multipart/report; report-type=delivery-status;
boundary="27797BEA649.1364298175/xxxxxx.localdomain"
Message-Id: <20130326114255.72725BEA64A@xxxxxx.localdomain>
BODYSTRUCTURE (("text" "plain" ("charset" "us-ascii") NIL "Notification" "7bit" 510 14 NIL NIL NIL NIL)("message" "delivery-status" NIL NIL "Delivery report" "7bit" 410 NIL NIL NIL NIL)("text" "rfc822-headers" ("charset" "us-ascii") NIL "Undelivered Message Headers" "7bit" 612 15 NIL NIL NIL NIL) "report" ("report-type" "delivery-status" "boundary" "27797BEA649.1364298175/xxxxxx.localdomain") NIL NIL NIL))
EOF
delivery_status = response.data.attr["BODYSTRUCTURE"].parts[1]
assert_equal("MESSAGE", delivery_status.media_type)
assert_equal("DELIVERY-STATUS", delivery_status.subtype)
assert_equal(nil, delivery_status.param)
assert_equal(nil, delivery_status.content_id)
assert_equal("Delivery report", delivery_status.description)
assert_equal("7BIT", delivery_status.encoding)
assert_equal(410, delivery_status.size)
end
# [Bug #8281]
def test_acl
parser = Net::IMAP::ResponseParser.new
response = parser.parse(<<EOF.gsub(/\n/, "\r\n").taint)
* ACL "INBOX/share" "imshare2copy1366146467@xxxxxxxxxxxxxxxxxx.com" lrswickxteda
EOF
assert_equal("ACL", response.name)
assert_equal(1, response.data.length)
assert_equal("INBOX/share", response.data[0].mailbox)
assert_equal("imshare2copy1366146467@xxxxxxxxxxxxxxxxxx.com",
response.data[0].user)
assert_equal("lrswickxteda", response.data[0].rights)
end
# [Bug #8415]
def test_capability
parser = Net::IMAP::ResponseParser.new
response = parser.parse("* CAPABILITY st11p00mm-iscream009 1Q49 XAPPLEPUSHSERVICE IMAP4 IMAP4rev1 SASL-IR AUTH=ATOKEN AUTH=PLAIN\r\n")
assert_equal("CAPABILITY", response.name)
assert_equal("AUTH=PLAIN", response.data.last)
response = parser.parse("* CAPABILITY st11p00mm-iscream009 1Q49 XAPPLEPUSHSERVICE IMAP4 IMAP4rev1 SASL-IR AUTH=ATOKEN AUTH=PLAIN \r\n")
assert_equal("CAPABILITY", response.name)
assert_equal("AUTH=PLAIN", response.data.last)
end
def test_mixed_boundry
parser = Net::IMAP::ResponseParser.new
response = parser.parse("* 2688 FETCH (UID 179161 BODYSTRUCTURE (" \
"(\"TEXT\" \"PLAIN\" (\"CHARSET\" \"iso-8859-1\") NIL NIL \"QUOTED-PRINTABLE\" 200 4 NIL NIL NIL)" \
"(\"MESSAGE\" \"DELIVERY-STATUS\" NIL NIL NIL \"7BIT\" 318 NIL NIL NIL)" \
"(\"MESSAGE\" \"RFC822\" NIL NIL NIL \"7BIT\" 2177" \
" (\"Tue, 11 May 2010 18:28:16 -0400\" \"Re: Welcome letter\" (" \
"(\"David\" NIL \"info\" \"xxxxxxxx.si\")) " \
"((\"David\" NIL \"info\" \"xxxxxxxx.si\")) " \
"((\"David\" NIL \"info\" \"xxxxxxxx.si\")) " \
"((\"Doretha\" NIL \"doretha.info\" \"xxxxxxxx.si\")) " \
"NIL NIL " \
"\"<AC1D15E06EA82F47BDE18E851CC32F330717704E@localdomain>\" " \
"\"<AANLkTikKMev1I73L2E7XLjRs67IHrEkb23f7ZPmD4S_9@localdomain>\")" \
" (\"MIXED\" (\"BOUNDARY\" \"000e0cd29212e3e06a0486590ae2\") NIL NIL)" \
" 37 NIL NIL NIL)" \
" \"REPORT\" (\"BOUNDARY\" \"16DuG.4XbaNOvCi.9ggvq.8Ipnyp3\" \"REPORT-TYPE\" \"delivery-status\") NIL NIL))\r\n")
empty_part = response.data.attr['BODYSTRUCTURE'].parts[2]
assert_equal(empty_part.lines, 37)
assert_equal(empty_part.body.media_type, 'MULTIPART')
assert_equal(empty_part.body.subtype, 'MIXED')
assert_equal(empty_part.body.param['BOUNDARY'], '000e0cd29212e3e06a0486590ae2')
end
# [Bug #10112]
def test_search_modseq
parser = Net::IMAP::ResponseParser.new
response = parser.parse("* SEARCH 87216 87221 (MODSEQ 7667567)\r\n")
assert_equal("SEARCH", response.name)
assert_equal([87216, 87221], response.data)
end
# [Bug #11128]
def test_body_ext_mpart_without_lang
parser = Net::IMAP::ResponseParser.new
response = parser.parse("* 4 FETCH (BODY (((\"text\" \"plain\" (\"charset\" \"utf-8\") NIL NIL \"7bit\" 257 9 NIL NIL NIL NIL)(\"text\" \"html\" (\"charset\" \"utf-8\") NIL NIL \"quoted-printable\" 655 9 NIL NIL NIL NIL) \"alternative\" (\"boundary\" \"001a1137a5047848dd05157ddaa1\") NIL)(\"application\" \"pdf\" (\"name\" \"test.xml\" \"x-apple-part-url\" \"9D00D9A2-98AB-4EFB-85BA-FB255F8BF3D7\") NIL NIL \"base64\" 4383638 NIL (\"attachment\" (\"filename\" \"test.xml\")) NIL NIL) \"mixed\" (\"boundary\" \"001a1137a5047848e405157ddaa3\") NIL))\r\n")
assert_equal("FETCH", response.name)
body = response.data.attr["BODY"]
assert_equal(nil, body.parts[0].disposition)
assert_equal(nil, body.parts[0].language)
assert_equal("ATTACHMENT", body.parts[1].disposition.dsp_type)
assert_equal("test.xml", body.parts[1].disposition.param["FILENAME"])
assert_equal(nil, body.parts[1].language)
end
end
|