PageRenderTime 52ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/test/net/imap/test_imap_response_parser.rb

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