sup 0.19.0 → 0.22.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +5 -0
  3. data/.gitmodules +3 -0
  4. data/.travis.yml +3 -2
  5. data/CONTRIBUTORS +19 -13
  6. data/Gemfile +4 -0
  7. data/History.txt +41 -0
  8. data/Rakefile +41 -1
  9. data/ReleaseNotes +17 -0
  10. data/bin/sup +5 -18
  11. data/bin/sup-add +1 -2
  12. data/bin/sup-config +0 -1
  13. data/bin/sup-dump +0 -1
  14. data/bin/sup-import-dump +1 -2
  15. data/bin/sup-sync +0 -1
  16. data/bin/sup-sync-back-maildir +1 -2
  17. data/bin/sup-tweak-labels +1 -2
  18. data/contrib/colorpicker.rb +0 -2
  19. data/contrib/completion/_sup.bash +102 -0
  20. data/devel/profile.rb +0 -1
  21. data/ext/mkrf_conf_xapian.rb +47 -0
  22. data/lib/sup.rb +9 -8
  23. data/lib/sup/buffer.rb +12 -0
  24. data/lib/sup/colormap.rb +5 -2
  25. data/lib/sup/contact.rb +4 -2
  26. data/lib/sup/crypto.rb +41 -8
  27. data/lib/sup/draft.rb +8 -8
  28. data/lib/sup/hook.rb +1 -1
  29. data/lib/sup/index.rb +2 -2
  30. data/lib/sup/label.rb +1 -1
  31. data/lib/sup/maildir.rb +16 -5
  32. data/lib/sup/mbox.rb +13 -5
  33. data/lib/sup/message.rb +17 -3
  34. data/lib/sup/message_chunks.rb +10 -2
  35. data/lib/sup/mode.rb +33 -28
  36. data/lib/sup/modes/edit_message_mode.rb +3 -2
  37. data/lib/sup/modes/forward_mode.rb +22 -3
  38. data/lib/sup/modes/line_cursor_mode.rb +1 -1
  39. data/lib/sup/modes/text_mode.rb +6 -1
  40. data/lib/sup/modes/thread_index_mode.rb +11 -1
  41. data/lib/sup/modes/thread_view_mode.rb +103 -9
  42. data/lib/sup/person.rb +68 -61
  43. data/lib/sup/search.rb +1 -1
  44. data/lib/sup/sent.rb +1 -1
  45. data/lib/sup/util.rb +1 -75
  46. data/lib/sup/util/locale_fiddler.rb +24 -0
  47. data/lib/sup/version.rb +1 -1
  48. data/sup.gemspec +22 -5
  49. data/test/{messages → fixtures}/bad-content-transfer-encoding-1.eml +0 -0
  50. data/test/{messages → fixtures}/binary-content-transfer-encoding-2.eml +0 -0
  51. data/test/fixtures/blank-header-fields.eml +71 -0
  52. data/test/fixtures/contacts.txt +1 -0
  53. data/test/fixtures/malicious-attachment-names.eml +55 -0
  54. data/test/fixtures/missing-from-to.eml +18 -0
  55. data/test/{messages → fixtures}/missing-line.eml +0 -0
  56. data/test/fixtures/multi-part-2.eml +72 -0
  57. data/test/fixtures/multi-part.eml +61 -0
  58. data/test/fixtures/no-body.eml +18 -0
  59. data/test/fixtures/simple-message.eml +29 -0
  60. data/test/gnupg_test_home/gpg.conf +2 -1
  61. data/test/gnupg_test_home/key1.gen +15 -0
  62. data/test/gnupg_test_home/key2.gen +15 -0
  63. data/test/gnupg_test_home/key_ecc.gen +13 -0
  64. data/test/gnupg_test_home/pubring.gpg +0 -0
  65. data/test/gnupg_test_home/receiver_pubring.gpg +0 -0
  66. data/test/gnupg_test_home/receiver_secring.gpg +0 -0
  67. data/test/gnupg_test_home/regen_keys.sh +38 -0
  68. data/test/gnupg_test_home/secring.gpg +0 -0
  69. data/test/gnupg_test_home/sup-test-2@foo.bar.asc +22 -17
  70. data/test/integration/test_maildir.rb +75 -0
  71. data/test/integration/test_mbox.rb +69 -0
  72. data/test/test_crypto.rb +12 -2
  73. data/test/test_header_parsing.rb +1 -1
  74. data/test/test_helper.rb +6 -3
  75. data/test/test_message.rb +42 -342
  76. data/test/test_messages_dir.rb +4 -28
  77. data/test/test_yaml_regressions.rb +1 -1
  78. data/test/unit/test_contact.rb +33 -0
  79. data/test/unit/test_locale_fiddler.rb +15 -0
  80. data/test/unit/test_person.rb +37 -0
  81. metadata +108 -38
  82. data/test/gnupg_test_home/receiver_trustdb.gpg +0 -0
  83. data/test/gnupg_test_home/trustdb.gpg +0 -0
@@ -0,0 +1,69 @@
1
+ require "test_helper"
2
+
3
+ class TestMbox < MiniTest::Test
4
+
5
+ def setup
6
+ @path = Dir.mktmpdir
7
+
8
+ @test_message_1 = <<EOS
9
+ From sup-talk-bounces@rubyforge.org Mon Apr 27 12:56:18 2009
10
+ From: Bob <bob@bob.com>
11
+ To: Joe <joe@joe.com>
12
+
13
+ Hello there friend. How are you? Blah is blah blah.
14
+ I like mboxes, don't you?
15
+ EOS
16
+
17
+ end
18
+
19
+ def teardown
20
+ ObjectSpace.each_object(Class).select {|a| a < Redwood::Singleton}.each do |klass|
21
+ klass.deinstantiate! unless klass == Redwood::Logger
22
+ end
23
+ FileUtils.rm_r @path
24
+ end
25
+
26
+ def create_a_mbox(extra='')
27
+ mbox = File.join(@path, "test_mbox#{extra}.mbox")
28
+ File.write(mbox, @test_message_1)
29
+ mbox
30
+ end
31
+
32
+ def start_sup_and_add_source(source)
33
+ start
34
+ Index.init @path
35
+ Index.load
36
+ SourceManager.instance.instance_eval '@sources = {}'
37
+ SourceManager.instance.add_source source
38
+ PollManager.poll_from source
39
+ end
40
+
41
+ # and now, let the tests begin!
42
+
43
+ def test_can_index_a_mbox_directory
44
+
45
+ mbox = create_a_mbox
46
+ start_sup_and_add_source MBox.new "mbox:#{mbox}"
47
+
48
+ messages_in_index = []
49
+ Index.instance.each_message {|a| messages_in_index << a}
50
+ refute_empty messages_in_index, 'There are no messages in the index'
51
+ test_message_without_first_line = @test_message_1.sub(/^.*\n/,'')
52
+ assert_equal(messages_in_index.first.raw_message, test_message_without_first_line)
53
+
54
+ end
55
+
56
+ def test_can_index_a_mbox_directory_with_special_characters
57
+
58
+ mbox = create_a_mbox URI_ENCODE_CHARS
59
+ start_sup_and_add_source MBox.new "mbox:#{mbox}"
60
+
61
+ messages_in_index = []
62
+ Index.instance.each_message {|a| messages_in_index << a}
63
+ refute_empty messages_in_index, 'There are no messages in the index'
64
+ test_message_without_first_line = @test_message_1.sub(/^.*\n/,'')
65
+ assert_equal(messages_in_index.first.raw_message, test_message_without_first_line)
66
+
67
+ end
68
+
69
+ end
@@ -25,10 +25,11 @@ require 'tmpdir'
25
25
 
26
26
  module Redwood
27
27
 
28
- class TestCryptoManager < ::Minitest::Unit::TestCase
28
+ class TestCryptoManager < Minitest::Test
29
29
 
30
30
  def setup
31
31
  @from_email = 'sup-test-1@foo.bar'
32
+ @from_email_ecc = 'sup-fake-ecc@fake.fake'
32
33
  @to_email = 'sup-test-2@foo.bar'
33
34
  # Use test gnupg setup
34
35
  @orig_gnupghome = ENV['GNUPGHOME']
@@ -37,7 +38,7 @@ class TestCryptoManager < ::Minitest::Unit::TestCase
37
38
  @path = Dir.mktmpdir
38
39
  Redwood::HookManager.init File.join(@path, 'hooks')
39
40
 
40
- am = {:default=> {:name => "test", :email=> 'sup-test-1@foo.bar'}}
41
+ am = {:default=> {name: "test", email: @from_email, alternates: [@from_email_ecc]}}
41
42
  Redwood::AccountManager.init am
42
43
 
43
44
  Redwood::CryptoManager.init
@@ -104,6 +105,15 @@ class TestCryptoManager < ::Minitest::Unit::TestCase
104
105
  CryptoManager.verify signed.body[0], signed.body[1], true
105
106
  end
106
107
  end
108
+
109
+ def test_verify_unknown_keytype
110
+ if CryptoManager.have_crypto?
111
+ signed = CryptoManager.sign @from_email_ecc, @to_email, "ABCDEFG"
112
+ assert_instance_of RMail::Message, signed
113
+ assert_instance_of String, (signed.body[1].body)
114
+ CryptoManager.verify signed.body[0], signed.body[1], true
115
+ end
116
+ end
107
117
  end
108
118
 
109
119
  end
@@ -6,7 +6,7 @@ require 'stringio'
6
6
 
7
7
  include Redwood
8
8
 
9
- class TestMBoxParsing < Minitest::Unit::TestCase
9
+ class TestMBoxParsing < Minitest::Test
10
10
 
11
11
  def setup
12
12
  @path = Dir.mktmpdir
@@ -2,6 +2,9 @@ require "rubygems" rescue nil
2
2
  require 'minitest/autorun'
3
3
  require "rr"
4
4
 
5
- class Minitest::Unit::TestCase
6
- include ::RR::Adapters::MiniTest
7
- end
5
+ def fixture(filename)
6
+ file = ''
7
+ path = File.expand_path("../fixtures/#{filename}", __FILE__)
8
+ File.open(path) { |io| file = io.read }
9
+ file
10
+ end
@@ -6,27 +6,9 @@ require 'stringio'
6
6
 
7
7
  require 'dummy_source'
8
8
 
9
- # override File.exists? to make it work with StringIO for testing.
10
- # FIXME: do aliasing to avoid breaking this when sup moves from
11
- # File.exists? to File.exist?
12
-
13
- class File
14
-
15
- def File.exists? file
16
- # puts "fake File::exists?"
17
-
18
- if file.is_a?(StringIO)
19
- return false
20
- end
21
- # use the different function
22
- File.exist?(file)
23
- end
24
-
25
- end
26
-
27
9
  module Redwood
28
10
 
29
- class TestMessage < ::Minitest::Unit::TestCase
11
+ class TestMessage < Minitest::Test
30
12
 
31
13
  def setup
32
14
  @path = Dir.mktmpdir
@@ -39,38 +21,7 @@ class TestMessage < ::Minitest::Unit::TestCase
39
21
  end
40
22
 
41
23
  def test_simple_message
42
-
43
- message = <<EOS
44
- Return-path: <fake_sender@example.invalid>
45
- Envelope-to: fake_receiver@localhost
46
- Delivery-date: Sun, 09 Dec 2007 21:48:19 +0200
47
- Received: from fake_sender by localhost.localdomain with local (Exim 4.67)
48
- (envelope-from <fake_sender@example.invalid>)
49
- id 1J1S8R-0006lA-MJ
50
- for fake_receiver@localhost; Sun, 09 Dec 2007 21:48:19 +0200
51
- Date: Sun, 9 Dec 2007 21:48:19 +0200
52
- Mailing-List: contact example-help@example.invalid; run by ezmlm
53
- Precedence: bulk
54
- List-Id: <example.list-id.example.invalid>
55
- List-Post: <mailto:example@example.invalid>
56
- List-Help: <mailto:example-help@example.invalid>
57
- List-Unsubscribe: <mailto:example-unsubscribe@example.invalid>
58
- List-Subscribe: <mailto:example-subscribe@example.invalid>
59
- Delivered-To: mailing list example@example.invalid
60
- Delivered-To: moderator for example@example.invalid
61
- From: Fake Sender <fake_sender@example.invalid>
62
- To: Fake Receiver <fake_receiver@localhost>
63
- Subject: Re: Test message subject
64
- Message-ID: <20071209194819.GA25972@example.invalid>
65
- References: <E1J1Rvb-0006k2-CE@localhost.localdomain>
66
- MIME-Version: 1.0
67
- Content-Type: text/plain; charset=us-ascii
68
- Content-Disposition: inline
69
- In-Reply-To: <E1J1Rvb-0006k2-CE@localhost.localdomain>
70
- User-Agent: Sup/0.3
71
-
72
- Test message!
73
- EOS
24
+ message = fixture('simple-message.eml')
74
25
 
75
26
  source = DummySource.new("sup-test://test_simple_message")
76
27
  source.messages = [ message ]
@@ -80,11 +31,9 @@ EOS
80
31
  sup_message.load_from_source!
81
32
 
82
33
  # see how well parsing the header went
83
-
84
34
  to = sup_message.to
85
- # "to" is an Array containing person items
86
-
87
- # there should be only one item
35
+ assert(to.is_a? Array)
36
+ assert(to.first.is_a? Person)
88
37
  assert_equal(1, to.length)
89
38
 
90
39
  # sup doesn't do capitalized letters in email addresses
@@ -92,8 +41,7 @@ EOS
92
41
  assert_equal("Fake Receiver", to[0].name)
93
42
 
94
43
  from = sup_message.from
95
- # "from" is just a simple person item
96
-
44
+ assert(from.is_a? Person)
97
45
  assert_equal("fake_sender@example.invalid", from.email)
98
46
  assert_equal("Fake Sender", from.name)
99
47
 
@@ -124,13 +72,8 @@ EOS
124
72
  assert_equal(1, replytos.length)
125
73
  assert_equal("E1J1Rvb-0006k2-CE@localhost.localdomain", replytos[0])
126
74
 
127
- cc = sup_message.cc
128
- # there are no ccs
129
- assert_equal(0, cc.length)
130
-
131
- bcc = sup_message.bcc
132
- # there are no bccs
133
- assert_equal(0, bcc.length)
75
+ assert_empty(sup_message.cc)
76
+ assert_empty(sup_message.bcc)
134
77
 
135
78
  recipient_email = sup_message.recipient_email
136
79
  assert_equal("fake_receiver@localhost", recipient_email)
@@ -142,86 +85,22 @@ EOS
142
85
  assert_equal(message_source_info, source_info)
143
86
 
144
87
  # read the message body chunks
145
-
146
88
  chunks = sup_message.load_from_source!
147
89
 
148
90
  # there should be only one chunk
149
91
  assert_equal(1, chunks.length)
150
92
 
151
- lines = chunks[0].lines
93
+ lines = chunks.first.lines
152
94
 
153
95
  # there should be only one line
154
96
  assert_equal(1, lines.length)
155
97
 
156
- assert_equal("Test message!", lines[0])
157
-
98
+ assert_equal("Test message!", lines.first)
158
99
  end
159
100
 
160
101
  def test_multipart_message
102
+ message = fixture('multi-part.eml')
161
103
 
162
- message = <<EOS
163
- From fake_receiver@localhost Sun Dec 09 22:33:37 +0200 2007
164
- Subject: Re: Test message subject
165
- From: Fake Receiver <fake_receiver@localhost>
166
- To: Fake Sender <fake_sender@example.invalid>
167
- References: <E1J1Rvb-0006k2-CE@localhost.localdomain> <20071209194819.GA25972example.invalid>
168
- In-Reply-To: <20071209194819.GA25972example.invalid>
169
- Date: Sun, 09 Dec 2007 22:33:37 +0200
170
- Message-Id: <1197232243-sup-2663example.invalid>
171
- User-Agent: Sup/0.3
172
- Content-Type: multipart/mixed; boundary="=-1197232418-506707-26079-6122-2-="
173
- MIME-Version: 1.0
174
-
175
-
176
- --=-1197232418-506707-26079-6122-2-=
177
- Content-Type: text/plain; charset=utf-8
178
- Content-Disposition: inline
179
-
180
- Excerpts from Fake Sender's message of Sun Dec 09 21:48:19 +0200 2007:
181
- > Test message!
182
-
183
- Thanks for the message!
184
- --=-1197232418-506707-26079-6122-2-=
185
- Content-Disposition: attachment; filename="HACKING"
186
- Content-Type: application/octet-stream; name="HACKING"
187
- Content-Transfer-Encoding: base64
188
-
189
- UnVubmluZyBTdXAgbG9jYWxseQotLS0tLS0tLS0tLS0tLS0tLS0tCkludm9r
190
- ZSBpdCBsaWtlIHRoaXM6CgpydWJ5IC1JIGxpYiAtdyBiaW4vc3VwCgpZb3Un
191
- bGwgaGF2ZSB0byBpbnN0YWxsIGFsbCBnZW1zIG1lbnRpb25lZCBpbiB0aGUg
192
- UmFrZWZpbGUgKGxvb2sgZm9yIHRoZSBsaW5lCnNldHRpbmcgcC5leHRyYV9k
193
- ZXBzKS4gSWYgeW91J3JlIG9uIGEgRGViaWFuIG9yIERlYmlhbi1iYXNlZCBz
194
- eXN0ZW0gKGUuZy4KVWJ1bnR1KSwgeW91J2xsIGhhdmUgdG8gbWFrZSBzdXJl
195
- IHlvdSBoYXZlIGEgY29tcGxldGUgUnVieSBpbnN0YWxsYXRpb24sCmVzcGVj
196
- aWFsbHkgbGlic3NsLXJ1YnkuCgpDb2Rpbmcgc3RhbmRhcmRzCi0tLS0tLS0t
197
- LS0tLS0tLS0KCi0gRG9uJ3Qgd3JhcCBjb2RlIHVubGVzcyBpdCByZWFsbHkg
198
- YmVuZWZpdHMgZnJvbSBpdC4gVGhlIGRheXMgb2YKICA4MC1jb2x1bW4gZGlz
199
- cGxheXMgYXJlIGxvbmcgb3Zlci4gQnV0IGRvIHdyYXAgY29tbWVudHMgYW5k
200
- IG90aGVyCiAgdGV4dCBhdCB3aGF0ZXZlciBFbWFjcyBtZXRhLVEgZG9lcy4K
201
- LSBJIGxpa2UgcG9ldHJ5IG1vZGUuCi0gVXNlIHt9IGZvciBvbmUtbGluZXIg
202
- YmxvY2tzIGFuZCBkby9lbmQgZm9yIG11bHRpLWxpbmUgYmxvY2tzLgoK
203
-
204
- --=-1197232418-506707-26079-6122-2-=
205
- Content-Disposition: attachment; filename="Manifest.txt"
206
- Content-Type: text/plain; name="Manifest.txt"
207
- Content-Transfer-Encoding: quoted-printable
208
-
209
- HACKING
210
- History.txt
211
- LICENSE
212
- Manifest.txt
213
- README.txt
214
- Rakefile
215
- bin/sup
216
- bin/sup-add
217
- bin/sup-config
218
- bin/sup-dump
219
- bin/sup-recover-sources
220
- bin/sup-sync
221
- bin/sup-sync-back
222
-
223
- --=-1197232418-506707-26079-6122-2-=--
224
- EOS
225
104
  source = DummySource.new("sup-test://test_multipart_message")
226
105
  source.messages = [ message ]
227
106
  source_info = 0
@@ -230,17 +109,16 @@ EOS
230
109
  sup_message.load_from_source!
231
110
 
232
111
  # read the message body chunks
233
-
234
112
  chunks = sup_message.load_from_source!
235
113
 
236
114
  # this time there should be four chunks: first the quoted part of
237
115
  # the message, then the non-quoted part, then the two attachments
238
116
  assert_equal(4, chunks.length)
239
117
 
240
- assert_equal(chunks[0].class, Redwood::Chunk::Quote)
241
- assert_equal(chunks[1].class, Redwood::Chunk::Text)
242
- assert_equal(chunks[2].class, Redwood::Chunk::Attachment)
243
- assert_equal(chunks[3].class, Redwood::Chunk::Attachment)
118
+ assert(chunks[0].is_a? Redwood::Chunk::Quote)
119
+ assert(chunks[1].is_a? Redwood::Chunk::Text)
120
+ assert(chunks[2].is_a? Redwood::Chunk::Attachment)
121
+ assert(chunks[3].is_a? Redwood::Chunk::Attachment)
244
122
 
245
123
  # further testing of chunks will happen in test_message_chunks.rb
246
124
  # (possibly not yet implemented)
@@ -248,29 +126,7 @@ EOS
248
126
  end
249
127
 
250
128
  def test_broken_message_1
251
-
252
- # an example of a broken message, missing "to" and "from" fields
253
-
254
- message = <<EOS
255
- Return-path: <fake_sender@example.invalid>
256
- Envelope-to: fake_receiver@localhost
257
- Delivery-date: Sun, 09 Dec 2007 21:48:19 +0200
258
- Received: from fake_sender by localhost.localdomain with local (Exim 4.67)
259
- (envelope-from <fake_sender@example.invalid>)
260
- id 1J1S8R-0006lA-MJ
261
- for fake_receiver@localhost; Sun, 09 Dec 2007 21:48:19 +0200
262
- Date: Sun, 9 Dec 2007 21:48:19 +0200
263
- Subject: Re: Test message subject
264
- Message-ID: <20071209194819.GA25972@example.invalid>
265
- References: <E1J1Rvb-0006k2-CE@localhost.localdomain>
266
- MIME-Version: 1.0
267
- Content-Type: text/plain; charset=us-ascii
268
- Content-Disposition: inline
269
- In-Reply-To: <E1J1Rvb-0006k2-CE@localhost.localdomain>
270
- User-Agent: Sup/0.3
271
-
272
- Test message!
273
- EOS
129
+ message = fixture('missing-from-to.eml')
274
130
 
275
131
  source = DummySource.new("sup-test://test_broken_message_1")
276
132
  source.messages = [ message ]
@@ -281,9 +137,9 @@ EOS
281
137
 
282
138
  to = sup_message.to
283
139
 
284
- # there should no items, since the message doesn't have any
285
- # recipients -- still not nil
286
- assert_equal(0, to.length)
140
+ # there should no items, since the message doesn't have any recipients -- still not nil
141
+ assert(!to.nil?)
142
+ assert_empty(to)
287
143
 
288
144
  # from will have bogus values
289
145
  from = sup_message.from
@@ -294,29 +150,7 @@ EOS
294
150
  end
295
151
 
296
152
  def test_broken_message_2
297
-
298
- # an example of a broken message, no body at all
299
-
300
- message = <<EOS
301
- Return-path: <fake_sender@example.invalid>
302
- From: Fake Sender <fake_sender@example.invalid>
303
- To: Fake Receiver <fake_receiver@localhost>
304
- Envelope-to: fake_receiver@localhost
305
- Delivery-date: Sun, 09 Dec 2007 21:48:19 +0200
306
- Received: from fake_sender by localhost.localdomain with local (Exim 4.67)
307
- (envelope-from <fake_sender@example.invalid>)
308
- id 1J1S8R-0006lA-MJ
309
- for fake_receiver@localhost; Sun, 09 Dec 2007 21:48:19 +0200
310
- Date: Sun, 9 Dec 2007 21:48:19 +0200
311
- Subject: Re: Test message subject
312
- Message-ID: <20071209194819.GA25972@example.invalid>
313
- References: <E1J1Rvb-0006k2-CE@localhost.localdomain>
314
- MIME-Version: 1.0
315
- Content-Type: text/plain; charset=us-ascii
316
- Content-Disposition: inline
317
- In-Reply-To: <E1J1Rvb-0006k2-CE@localhost.localdomain>
318
- User-Agent: Sup/0.3
319
- EOS
153
+ message = fixture('no-body.eml')
320
154
 
321
155
  source = DummySource.new("sup-test://test_broken_message_1")
322
156
  source.messages = [ message ]
@@ -329,90 +163,12 @@ EOS
329
163
 
330
164
  chunks = sup_message.load_from_source!
331
165
 
332
- # the chunks list should be empty
333
-
334
- assert_equal(0, chunks.length)
335
-
166
+ assert_empty(chunks)
336
167
  end
337
168
 
338
169
  def test_multipart_message_2
170
+ message = fixture('multi-part-2.eml')
339
171
 
340
- message = <<EOS
341
- Return-path: <vim-mac-return-3938-fake_receiver=localhost@vim.org>
342
- Envelope-to: fake_receiver@localhost
343
- Delivery-date: Wed, 14 Jun 2006 19:22:54 +0300
344
- Received: from localhost ([127.0.0.1] helo=localhost.localdomain)
345
- by localhost.localdomain with esmtp (Exim 4.60)
346
- (envelope-from <vim-mac-return-3938-fake_receiver=localhost@vim.org>)
347
- id 1FqXk3-0006jM-48
348
- for fake_receiver@localhost; Wed, 14 Jun 2006 18:57:15 +0300
349
- Received: from pop.gmail.com
350
- by localhost.localdomain with POP3 (fetchmail-6.3.2)
351
- for <fake_receiver@localhost> (single-drop); Wed, 14 Jun 2006 18:57:15 +0300 (EEST)
352
- X-Gmail-Received: 8ee0fe5f895736974c042c8eaf176014b1ba7b88
353
- Delivered-To: fake_receiver@localhost
354
- Received: by 10.49.8.16 with SMTP id l16cs11327nfi;
355
- Sun, 26 Mar 2006 19:31:56 -0800 (PST)
356
- Received: by 10.66.224.8 with SMTP id w8mr2172862ugg;
357
- Sun, 26 Mar 2006 19:31:56 -0800 (PST)
358
- Received: from foobar.math.fu-berlin.de (foobar.math.fu-berlin.de [160.45.45.151])
359
- by mx.gmail.com with SMTP id j3si553645ugd.2006.03.26.19.31.56;
360
- Sun, 26 Mar 2006 19:31:56 -0800 (PST)
361
- Received-SPF: neutral (gmail.com: 160.45.45.151 is neither permitted nor denied by best guess record for domain of vim-mac-return-3938-fake_receiver=localhost@vim.org)
362
- Message-Id: <44275cac.74a494f1.315a.ffff825cSMTPIN_ADDED@mx.gmail.com>
363
- Received: (qmail 24265 invoked by uid 200); 27 Mar 2006 02:32:39 -0000
364
- Mailing-List: contact vim-mac-help@vim.org; run by ezmlm
365
- Precedence: bulk
366
- Delivered-To: mailing list vim-mac@vim.org
367
- Received: (qmail 7913 invoked from network); 26 Mar 2006 23:37:34 -0000
368
- Received: from cpe-138-217-96-243.vic.bigpond.net.au (HELO vim.org) (138.217.96.243)
369
- by foobar.math.fu-berlin.de with SMTP; 26 Mar 2006 23:37:34 -0000
370
- From: fake_sender@example.invalid
371
- To: vim-mac@vim.org
372
- Subject: Mail Delivery (failure vim-mac@vim.org)
373
- Date: Mon, 27 Mar 2006 10:29:39 +1000
374
- MIME-Version: 1.0
375
- Content-Type: multipart/related;
376
- type="multipart/alternative";
377
- boundary="----=_NextPart_000_001B_01C0CA80.6B015D10"
378
- X-Priority: 3
379
- X-MSMail-Priority: Normal
380
-
381
- ------=_NextPart_000_001B_01C0CA80.6B015D10
382
- Content-Type: multipart/alternative;
383
- boundary="----=_NextPart_001_001C_01C0CA80.6B015D10"
384
-
385
- ------=_NextPart_001_001C_01C0CA80.6B015D10
386
- Content-Type: text/plain;
387
- charset="iso-8859-1"
388
- Content-Transfer-Encoding: quoted-printable
389
-
390
- ------=_NextPart_001_001C_01C0CA80.6B015D10
391
- Content-Type: text/html;
392
- charset="iso-8859-1"
393
- Content-Transfer-Encoding: quoted-printable
394
-
395
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
396
- <HTML><HEAD>
397
- <META content=3D"text/html; charset=3Diso-8859-1" =
398
- http-equiv=3DContent-Type>
399
- <META content=3D"MSHTML 5.00.2920.0" name=3DGENERATOR>
400
- <STYLE></STYLE>
401
- </HEAD>
402
- <BODY bgColor=3D#ffffff>If the message will not displayed automatically,<br>
403
- follow the link to read the delivered message.<br><br>
404
- Received message is available at:<br>
405
- <a href=3Dcid:031401Mfdab4$3f3dL780$73387018@57W81fa70Re height=3D0 width=3D0>www.vim.org/inbox/vim-mac/read.php?sessionid-18559</a>
406
- <iframe
407
- src=3Dcid:031401Mfdab4$3f3dL780$73387018@57W81fa70Re height=3D0 width=3D0></iframe>
408
- <DIV>&nbsp;</DIV></BODY></HTML>
409
-
410
- ------=_NextPart_001_001C_01C0CA80.6B015D10--
411
-
412
- ------=_NextPart_000_001B_01C0CA80.6B015D10--
413
-
414
-
415
- EOS
416
172
  source = DummySource.new("sup-test://test_multipart_message_2")
417
173
  source.messages = [ message ]
418
174
  source_info = 0
@@ -420,86 +176,13 @@ EOS
420
176
  sup_message = Message.build_from_source(source, source_info)
421
177
  sup_message.load_from_source!
422
178
 
423
- # read the message body chunks
179
+ chunks = sup_message.load_from_source! # read the message body chunks
424
180
 
425
- sup_message.load_from_source!
181
+ # TODO: Add more asserts
426
182
  end
427
183
 
428
184
  def test_blank_header_lines
429
-
430
- message = <<EOS
431
- Return-Path: <monitor-list-bounces@widget.com>
432
- X-Original-To: nobody@localhost
433
- Delivered-To: nobody@localhost.eng.widget.com
434
- Received: from localhost (localhost.localdomain [127.0.0.1])
435
- by soquel.eng.widget.com (Postfix) with ESMTP id 609BC13C0DB1
436
- for <nobody@localhost>; Thu, 19 Mar 2009 13:43:21 -0700 (PDT)
437
- MIME-Version: 1.0
438
- Received: from pa-excas-vip.widget.com [10.16.67.200]
439
- by localhost with IMAP (fetchmail-6.2.5)
440
- for nobody@localhost (single-drop); Thu, 19 Mar 2009 13:43:21 -0700 (PDT)
441
- Received: from pa-exht01.widget.com (10.113.81.167) by pa-excaht11.widget.com
442
- (10.113.81.197) with Microsoft SMTP Server (TLS) id 8.1.311.2; Thu, 19 Mar
443
- 2009 13:42:30 -0700
444
- Received: from mailman2.widget.com (10.16.64.159) by pa-exht01.widget.com
445
- (10.113.81.167) with Microsoft SMTP Server id 8.1.336.0; Thu, 19 Mar 2009
446
- 13:42:30 -0700
447
- Received: by mailman2.widget.com (Postfix) id 47095AE30856; Thu, 19 Mar 2009
448
- 13:42:29 -0700 (PDT)
449
- Received: from countchocula.widget.com (localhost.localdomain [127.0.0.1]) by
450
- mailman2.widget.com (Postfix) with ESMTP id 5F782ABC5948; Thu, 19 Mar 2009
451
- 13:42:28 -0700 (PDT)
452
- Received: from mailhost4.widget.com (mailhost4.widget.com [10.16.67.124]) by
453
- mailman2.widget.com (Postfix) with ESMTP id 6CDCCABC5948 for
454
- <monitor-list@mailman2.widget.com>; Thu, 19 Mar 2009 13:42:26 -0700 (PDT)
455
- Received: by mailhost4.widget.com (Postfix) id 2364AC9AC4; Thu, 19 Mar 2009
456
- 13:42:26 -0700 (PDT)
457
- Received: from pa-exht01.widget.com (pa-exht01.widget.com [10.113.81.167]) by
458
- mailhost4.widget.com (Postfix) with ESMTP id 17A68C9AC3 for
459
- <monitor-list@widget.com>; Thu, 19 Mar 2009 13:42:26 -0700 (PDT)
460
- Received: from PA-EXMBX04.widget.com ([10.113.81.142]) by pa-exht01.widget.com
461
- ([10.113.81.167]) with mapi; Thu, 19 Mar 2009 13:42:26 -0700
462
- From: Some User <someuser@widget.com>
463
- To: "monitor-list@widget.com" <monitor-list@widget.com>
464
- Sender: "monitor-list-bounces@widget.com" <monitor-list-bounces@widget.com>
465
- Date: Thu, 19 Mar 2009 13:42:25 -0700
466
- Subject: Looking for a mac
467
- Thread-Topic: Looking for a mac
468
- Thread-Index: AQHJqNM1xIqqjNRWuUCUBaxzPFK5eQ==
469
- Message-ID:
470
- <D3C12B2AD838B44DA9D6B2CA334246D011E72A73A4@PA-EXMBX04.widget.com>
471
- List-Help: <mailto:monitor-list-request@widget.com?subject=help>
472
- List-Subscribe: <http://mailman2.widget.com/mailman/listinfo/monitor-list>,
473
- <mailto:monitor-list-request@widget.com?subject=subscribe>
474
- List-Unsubscribe:
475
- <http://mailman2.widget.com/mailman/listinfo/monitor-list>,
476
- <mailto:monitor-list-request@widget.com?subject=unsubscribe>
477
- Accept-Language: en-US
478
- Content-Language: en-US
479
- X-MS-Exchange-Organization-AuthAs: Anonymous
480
- X-MS-Exchange-Organization-AuthSource: pa-exht01.widget.com
481
- X-MS-Has-Attach:
482
- X-Auto-Response-Suppress: All
483
- X-MS-TNEF-Correlator:
484
- acceptlanguage: en-US
485
- delivered-to: monitor-list@widget.com
486
- errors-to: monitor-list-bounces@widget.com
487
- list-id: engineering monitor related <monitor-list.widget.com>
488
- x-mailman-version: 2.1.8
489
- x-beenthere: monitor-list@widget.com
490
- x-original-to: monitor-list@mailman2.widget.com
491
- list-post: <mailto:monitor-list@widget.com>
492
- list-archive: <http://mailman2.widget.com/pipermail/monitor-list>
493
- Content-Type: text/plain; charset="us-ascii"
494
- Content-Transfer-Encoding: quoted-printable
495
-
496
- Hi all,
497
-
498
- Just wondering if anybody can lend me a mac to reproduce PR 384931 ?
499
- Thanks.
500
-
501
- Michael=
502
- EOS
185
+ message = fixture('blank-header-fields.eml')
503
186
 
504
187
  source = DummySource.new("sup-test://test_blank_header_lines")
505
188
  source.messages = [ message ]
@@ -514,12 +197,29 @@ EOS
514
197
 
515
198
  # Look at another header field whose first line was blank.
516
199
  list_unsubscribe = sup_message.list_unsubscribe
517
- assert_equal("<http://mailman2.widget.com/mailman/listinfo/monitor-list>,\n \t" +
200
+ assert_equal("<http://mailman2.widget.com/mailman/listinfo/monitor-list>,\n\t" +
518
201
  "<mailto:monitor-list-request@widget.com?subject=unsubscribe>",
519
202
  list_unsubscribe)
520
203
 
521
204
  end
522
205
 
206
+ def test_malicious_attachment_names
207
+ message = fixture('malicious-attachment-names.eml')
208
+
209
+ source = DummySource.new("sup-test://test_blank_header_lines")
210
+ source.messages = [ message ]
211
+ source_info = 0
212
+
213
+ sup_message = Message.build_from_source(source, source_info)
214
+ chunks = sup_message.load_from_source!
215
+
216
+ # See if attachment filenames can be safely used for saving.
217
+ # We do that by verifying that any folder-related character (/ or \)
218
+ # are not interpreted: the filename must not be interpreted into a
219
+ # path.
220
+ fn = chunks[3].safe_filename
221
+ assert_equal(fn, File.basename(fn))
222
+ end
523
223
  # TODO: test different error cases, malformed messages etc.
524
224
 
525
225
  # TODO: test different quoting styles, see that they are all divided