sup 0.19.0 → 0.22.1

Sign up to get free protection for your applications and to get access to all the features.
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