sup 0.20.0 → 1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +2 -1
- data/.travis.yml +11 -6
- data/CONTRIBUTORS +27 -15
- data/Gemfile +2 -1
- data/History.txt +84 -0
- data/README.md +26 -5
- data/Rakefile +0 -1
- data/ReleaseNotes +7 -0
- data/bin/sup +17 -30
- data/bin/sup-add +15 -16
- data/bin/sup-config +30 -45
- data/bin/sup-dump +2 -3
- data/bin/sup-import-dump +5 -6
- data/bin/sup-sync +3 -4
- data/bin/sup-sync-back-maildir +3 -4
- data/bin/sup-tweak-labels +6 -7
- data/contrib/colorpicker.rb +0 -2
- data/contrib/completion/_sup.bash +102 -0
- data/devel/profile.rb +0 -1
- data/ext/mkrf_conf_xapian.rb +1 -1
- data/lib/sup.rb +8 -8
- data/lib/sup/colormap.rb +5 -2
- data/lib/sup/contact.rb +4 -2
- data/lib/sup/crypto.rb +58 -16
- data/lib/sup/draft.rb +8 -8
- data/lib/sup/hook.rb +9 -9
- data/lib/sup/index.rb +20 -7
- data/lib/sup/label.rb +1 -1
- data/lib/sup/logger.rb +1 -1
- data/lib/sup/maildir.rb +2 -2
- data/lib/sup/mbox.rb +2 -2
- data/lib/sup/message.rb +26 -10
- data/lib/sup/message_chunks.rb +7 -4
- data/lib/sup/mode.rb +34 -28
- data/lib/sup/modes/contact_list_mode.rb +1 -0
- data/lib/sup/modes/edit_message_mode.rb +1 -1
- data/lib/sup/modes/forward_mode.rb +22 -3
- data/lib/sup/modes/line_cursor_mode.rb +1 -1
- data/lib/sup/modes/reply_mode.rb +3 -1
- data/lib/sup/modes/text_mode.rb +6 -1
- data/lib/sup/modes/thread_index_mode.rb +6 -2
- data/lib/sup/modes/thread_view_mode.rb +63 -18
- data/lib/sup/person.rb +68 -61
- data/lib/sup/search.rb +1 -1
- data/lib/sup/sent.rb +1 -1
- data/lib/sup/source.rb +1 -1
- data/lib/sup/util.rb +15 -94
- data/lib/sup/util/axe.rb +17 -0
- data/lib/sup/util/locale_fiddler.rb +24 -0
- data/lib/sup/util/ncurses.rb +3 -3
- data/lib/sup/version.rb +10 -1
- data/sup.gemspec +12 -10
- data/test/{messages → fixtures}/bad-content-transfer-encoding-1.eml +0 -0
- data/test/{messages → fixtures}/binary-content-transfer-encoding-2.eml +0 -0
- data/test/fixtures/blank-header-fields.eml +71 -0
- data/test/fixtures/contacts.txt +1 -0
- data/test/fixtures/mailing-list-header.eml +80 -0
- data/test/fixtures/malicious-attachment-names.eml +55 -0
- data/test/fixtures/missing-from-to.eml +18 -0
- data/test/{messages → fixtures}/missing-line.eml +0 -0
- data/test/fixtures/multi-part-2.eml +72 -0
- data/test/fixtures/multi-part.eml +61 -0
- data/test/fixtures/no-body.eml +18 -0
- data/test/fixtures/simple-message.eml +29 -0
- data/test/fixtures/text-attachments-with-charset.eml +46 -0
- data/test/fixtures/zimbra-quote-with-bottom-post.eml +27 -0
- data/test/gnupg_test_home/gpg.conf +2 -1
- data/test/gnupg_test_home/private-keys-v1.d/306D2EE90FF0014B5B9FD07E265C751791674140.key +0 -0
- data/test/gnupg_test_home/pubring.gpg +0 -0
- data/test/gnupg_test_home/receiver_pubring.gpg +0 -0
- data/test/gnupg_test_home/receiver_secring.gpg +0 -0
- data/test/gnupg_test_home/regen_keys.sh +70 -16
- data/test/gnupg_test_home/secring.gpg +0 -0
- data/test/gnupg_test_home/sup-test-2@foo.bar.asc +20 -22
- data/test/integration/test_maildir.rb +1 -1
- data/test/integration/test_mbox.rb +1 -1
- data/test/test_crypto.rb +14 -2
- data/test/test_header_parsing.rb +1 -1
- data/test/test_helper.rb +6 -3
- data/test/test_message.rb +115 -341
- data/test/test_messages_dir.rb +4 -28
- data/test/test_yaml_regressions.rb +1 -1
- data/test/unit/test_contact.rb +33 -0
- data/test/unit/test_locale_fiddler.rb +15 -0
- data/test/unit/test_person.rb +37 -0
- data/test/unit/util/test_query.rb +10 -4
- data/test/unit/util/test_string.rb +6 -0
- metadata +107 -43
- data/test/gnupg_test_home/key1.gen +0 -15
- data/test/gnupg_test_home/key2.gen +0 -15
@@ -0,0 +1,29 @@
|
|
1
|
+
Return-path: <fake_sender@example.invalid>
|
2
|
+
Envelope-to: fake_receiver@localhost
|
3
|
+
Delivery-date: Sun, 09 Dec 2007 21:48:19 +0200
|
4
|
+
Received: from fake_sender by localhost.localdomain with local (Exim 4.67)
|
5
|
+
(envelope-from <fake_sender@example.invalid>)
|
6
|
+
id 1J1S8R-0006lA-MJ
|
7
|
+
for fake_receiver@localhost; Sun, 09 Dec 2007 21:48:19 +0200
|
8
|
+
Date: Sun, 9 Dec 2007 21:48:19 +0200
|
9
|
+
Mailing-List: contact example-help@example.invalid; run by ezmlm
|
10
|
+
Precedence: bulk
|
11
|
+
List-Id: <example.list-id.example.invalid>
|
12
|
+
List-Post: <mailto:example@example.invalid>
|
13
|
+
List-Help: <mailto:example-help@example.invalid>
|
14
|
+
List-Unsubscribe: <mailto:example-unsubscribe@example.invalid>
|
15
|
+
List-Subscribe: <mailto:example-subscribe@example.invalid>
|
16
|
+
Delivered-To: mailing list example@example.invalid
|
17
|
+
Delivered-To: moderator for example@example.invalid
|
18
|
+
From: Fake Sender <fake_sender@example.invalid>
|
19
|
+
To: Fake Receiver <fake_receiver@localhost>
|
20
|
+
Subject: Re: Test message subject
|
21
|
+
Message-ID: <20071209194819.GA25972@example.invalid>
|
22
|
+
References: <E1J1Rvb-0006k2-CE@localhost.localdomain>
|
23
|
+
MIME-Version: 1.0
|
24
|
+
Content-Type: text/plain; charset=us-ascii
|
25
|
+
Content-Disposition: inline
|
26
|
+
In-Reply-To: <E1J1Rvb-0006k2-CE@localhost.localdomain>
|
27
|
+
User-Agent: Sup/0.3
|
28
|
+
|
29
|
+
Test message!
|
@@ -0,0 +1,46 @@
|
|
1
|
+
From: Fake Sender <fake_sender@example.invalid>
|
2
|
+
To: Fake Receiver <fake_receiver@localhost>
|
3
|
+
Date: Sun, 21 Jun 2020 06:25:49 -0000
|
4
|
+
Subject: Attachments with charset
|
5
|
+
MIME-Version: 1.0
|
6
|
+
Content-Type: multipart/mixed; boundary="===============2385509127900810307=="
|
7
|
+
|
8
|
+
--===============2385509127900810307==
|
9
|
+
Content-Type: text/plain; charset="utf-8"
|
10
|
+
Content-Transfer-Encoding: 7bit
|
11
|
+
|
12
|
+
This is the body.
|
13
|
+
|
14
|
+
--===============2385509127900810307==
|
15
|
+
Content-Type: text/plain; charset="us-ascii"
|
16
|
+
Content-Transfer-Encoding: 7bit
|
17
|
+
MIME-Version: 1.0
|
18
|
+
Content-Disposition: attachment; filename="ascii.txt"
|
19
|
+
|
20
|
+
This is ASCII
|
21
|
+
|
22
|
+
--===============2385509127900810307==
|
23
|
+
Content-Type: text/plain; charset="koi8-r"
|
24
|
+
Content-Transfer-Encoding: quoted-printable
|
25
|
+
MIME-Version: 1.0
|
26
|
+
Content-Disposition: attachment; filename="cyrillic.txt"
|
27
|
+
|
28
|
+
=F0=D2=C9=D7=C5=D4
|
29
|
+
|
30
|
+
--===============2385509127900810307==
|
31
|
+
Content-Type: text/plain; charset="utf-8"
|
32
|
+
Content-Transfer-Encoding: base64
|
33
|
+
MIME-Version: 1.0
|
34
|
+
Content-Disposition: attachment; filename="emoji.txt"
|
35
|
+
|
36
|
+
8J+Yggo=
|
37
|
+
|
38
|
+
--===============2385509127900810307==
|
39
|
+
Content-Type: text/plain
|
40
|
+
Content-Transfer-Encoding: quoted-printable
|
41
|
+
Content-Disposition: attachment; filename="bad.txt"
|
42
|
+
MIME-Version: 1.0
|
43
|
+
|
44
|
+
Embedded=F0garbage
|
45
|
+
--===============2385509127900810307==--
|
46
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
Return-Path: <zimbra.user@example.invalid>
|
2
|
+
Delivered-To: <recipient@example.invalid>
|
3
|
+
Received: from zmail16.collab.prod.int.phx2.redhat.com (zmail16.collab.prod.int.phx2.redhat.com [10.5.83.18])
|
4
|
+
by mx4-phx2.redhat.com (8.13.8/8.13.8) with ESMTP id q3A5xQ06025053
|
5
|
+
for <recipient@example.invalid>; Tue, 10 Apr 2012 01:59:26 -0400
|
6
|
+
Date: Tue, 10 Apr 2012 01:59:26 -0400 (EDT)
|
7
|
+
From: Zimbra User <zimbra.user@example.invalid>
|
8
|
+
To: Recipient <recipient@example.invalid>
|
9
|
+
Subject: Re: Zimbra
|
10
|
+
Message-ID: <0fe105df-e67b-419e-8599-50aaff7260e8@zmail16.collab.prod.int.phx2.redhat.com>
|
11
|
+
In-Reply-To: <1334037315-sup-8577@example.invalid>
|
12
|
+
Content-Type: text/plain; charset=utf-8
|
13
|
+
Content-Transfer-Encoding: 7bit
|
14
|
+
MIME-Version: 1.0
|
15
|
+
X-Mailer: Zimbra 7.1.2_GA_3268 (ZimbraWebClient - FF3.0 (Linux)/7.1.2_GA_3268)
|
16
|
+
|
17
|
+
----- Original Message -----
|
18
|
+
> From: "Recipient" <recipient@example.invalid>
|
19
|
+
> To: "Zimbra User" <zimbra.user@example.invalid>
|
20
|
+
> Sent: Tuesday, April 10, 2012 3:56:15 PM
|
21
|
+
> Subject: Re: Zimbra
|
22
|
+
>
|
23
|
+
> This is the quoted original message.
|
24
|
+
>
|
25
|
+
|
26
|
+
|
27
|
+
This is the reply from the Zimbra user.
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -1,35 +1,89 @@
|
|
1
|
-
|
1
|
+
#!/bin/bash
|
2
2
|
#
|
3
3
|
# re-generate test keys for the sup test base
|
4
4
|
#
|
5
5
|
# https://github.com/sup-heliotrope/sup/wiki/Development%3A-Crypto
|
6
|
+
#
|
7
|
+
# Requires GPG 2.1+ installed as "gpg2"
|
8
|
+
#
|
9
|
+
# GPG 2.1+ by default uses pubring.kbx - but this isn't backwards compatible
|
10
|
+
# with GPG 1 or GPG 2.0.
|
11
|
+
# Workaround:
|
12
|
+
# - Create empty pubring.gpg file, which causes GPG 2.1+ to use this
|
13
|
+
# backwards-compatible store.
|
14
|
+
# - Manually export private key copy to secring.gpg, which would be used
|
15
|
+
# by GPG 1.
|
16
|
+
|
17
|
+
set -e -u -o pipefail
|
6
18
|
|
7
19
|
pushd $(dirname $0)
|
8
20
|
|
9
|
-
|
21
|
+
echo "Generating keys in: $(pwd)..."
|
10
22
|
|
11
|
-
echo "
|
23
|
+
echo "Checking gpg2 version"
|
24
|
+
gpg2 --version | head -1
|
12
25
|
|
13
|
-
|
26
|
+
echo "Deleting all existing test keys"
|
27
|
+
rm -f \
|
28
|
+
*.gpg \
|
29
|
+
*.asc \
|
30
|
+
private-keys-v1.d/*.key \
|
31
|
+
.gpg-v21-migrated
|
14
32
|
|
15
|
-
echo "
|
16
|
-
gpg
|
33
|
+
echo "Generating key pair for test receiver (email sup-test-2@foo.bar.asc)"
|
34
|
+
touch pubring.gpg # So GPG 2.1+ writes to pubring.gpg instead of pubring.kbx
|
35
|
+
gpg2 \
|
36
|
+
--homedir . \
|
37
|
+
--batch \
|
38
|
+
--pinentry-mode loopback \
|
39
|
+
--passphrase '' \
|
40
|
+
--quick-generate-key sup-test-2@foo.bar rsa encrypt,sign 0
|
17
41
|
|
18
|
-
echo "
|
42
|
+
echo "Exporting public key only for test receiver (file sup-test-2@foo.bar.asc)"
|
43
|
+
gpg2 \
|
44
|
+
--homedir . \
|
45
|
+
--armor \
|
46
|
+
--output sup-test-2@foo.bar.asc \
|
47
|
+
--export sup-test-2@foo.bar
|
19
48
|
|
20
|
-
|
49
|
+
echo "Backing up secret key for test receiver (file receiver_secring.gpg)"
|
50
|
+
gpg2 \
|
51
|
+
--homedir . \
|
52
|
+
--export-secret-keys \
|
53
|
+
>receiver_secring.gpg
|
21
54
|
|
22
|
-
|
23
|
-
|
24
|
-
mv pubring.gpg receiver_pubring.gpg
|
55
|
+
echo "Backing up pubring.gpg for test receiver (file receiver_pubring.gpg)"
|
56
|
+
cp -a pubring.gpg receiver_pubring.gpg
|
25
57
|
|
26
|
-
echo "
|
27
|
-
gpg
|
58
|
+
echo "Clearing key store, so we can start from a blank slate for next key(s)"
|
59
|
+
rm -f pubring.gpg trustdb.gpg private-keys-v1.d/*.key .gpg-v21-migrated
|
28
60
|
|
29
|
-
echo "
|
30
|
-
gpg
|
61
|
+
echo "Generating key pair for sender (email sup-test-1@foo.bar)"
|
62
|
+
touch pubring.gpg # So GPG 2.1+ writes to pubring.gpg instead of pubring.kbx
|
63
|
+
gpg2 \
|
64
|
+
--homedir . \
|
65
|
+
--batch \
|
66
|
+
--pinentry-mode loopback \
|
67
|
+
--passphrase '' \
|
68
|
+
--quick-generate-key sup-test-1@foo.bar rsa encrypt,sign 0
|
31
69
|
|
70
|
+
echo "Importing public key for receiver, into sender's key store"
|
71
|
+
gpg2 \
|
72
|
+
--homedir . \
|
73
|
+
--import sup-test-2@foo.bar.asc
|
32
74
|
|
75
|
+
echo "Copy private key also to secring.gpg (old format used by GPG 1)"
|
76
|
+
gpg2 \
|
77
|
+
--homedir . \
|
78
|
+
--export-secret-keys \
|
79
|
+
>secring.gpg
|
33
80
|
|
34
|
-
|
81
|
+
echo "Done."
|
82
|
+
|
83
|
+
echo "We now have two non-expiring public keys (receiver & sender):"
|
84
|
+
gpg2 --homedir . --list-keys
|
35
85
|
|
86
|
+
echo "And we also have only *one* corresponding private key (sender only):"
|
87
|
+
gpg2 --homedir . --list-secret-keys
|
88
|
+
|
89
|
+
popd
|
Binary file
|
@@ -1,25 +1,23 @@
|
|
1
1
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
2
|
-
Version: GnuPG v2
|
3
2
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
=Jo82
|
3
|
+
mQGNBF7leTkBDAC3auy8xodH6jxoISylFZTpVqy/0L2ul879YUb/QbC58+F/H36S
|
4
|
+
CjLfPxFlq0FAOXHelOvktxaybg+BG5UpSvTgBLbcArq5nctee+04TMXCzQzrG2V1
|
5
|
+
zb9gIRT665fX3+WYncSIXdr4LAp7r8Jw3RT3tTOZqbaencumCWaJblnvfFwPrMKf
|
6
|
+
AXWa/NVndNMAXmJ5uBf1MRr45KXaQ2tczPIeHqSOKhKNnKZPRqPs0fg4i3d0Vb6G
|
7
|
+
yItgtJapfBo50FV+PvtodMHo3LDlz/BBjdEJHSvghqEjb1S7xGo+hdXs+lfCMfa0
|
8
|
+
3PAWoj+OeHNorbK0YbVKOtS0E0xYvScbyC7bfwtA9yb3LZYmy7VHsKJmQfygCNQ6
|
9
|
+
wIKQGAVN1NcQcJsvWyAwk9+WMN5oqB5lb76u40beoWlUjSJRlph2VvWvkGuh/huU
|
10
|
+
sVGqcN7EO4SFkwi2YQLoWfQRGur3mids/PQTBywpGE1SyziPZK76pT6SqP8b+OpI
|
11
|
+
CG1QbcTZzYpbv6kAEQEAAbQSc3VwLXRlc3QtMkBmb28uYmFyiQHOBBMBCgA4FiEE
|
12
|
+
e0oXvVeqMzUcfd1s2bF8xbTizW8FAl7leTkCGw8FCwkIBwIGFQoJCAsCBBYCAwEC
|
13
|
+
HgECF4AACgkQ2bF8xbTizW92TAv/WGlYfDTKNEmJ0K+kxt33T2ldmZXaJKL04Mft
|
14
|
+
h5s5KlRZWDNpkCC/L55uyaeEg+Uy+BEEQKLAEeJrrLMV8UMJwMPDOizSTT9uLyiz
|
15
|
+
b8RjnQw4iMT8wt9TQboXGaTMslwdXvFPii7w44KgCimE7VuPetJuLMLMbnl147G8
|
16
|
+
+QhkNUsrB51TuPS8xZJ4qjbH+K/Y2NlvwLtJrxNE3SRQuy2ApYJxKPZIj1KpUL8M
|
17
|
+
7Jy/2hI8DaRm/0Fpu8HwRIVsd6/dgdkqdj1uVyLj+wyhgdzqV5WrPLFCRVhd3icd
|
18
|
+
lPNRIDjg8YKCh353LVHjKwefOW4SnkOPn4uVMdCP9gUFd9zpMP9lMFpjk0o0tcYO
|
19
|
+
NiFrOclS4q5qZ5jrj1MnBF0NaGhuC83DDgRfKV+p5noVeJxg0nXYZSlsSMfAT/K7
|
20
|
+
FbdNEg0XUsrLgWVzhvWv/ebMetFPSfGHIveZ7lhiq1qpA5hLBNfSSBb1JJsFmtQt
|
21
|
+
cEUluymdNe5W7Y6UGs1CpvcIvbj+
|
22
|
+
=Cy9S
|
25
23
|
-----END PGP PUBLIC KEY BLOCK-----
|
data/test/test_crypto.rb
CHANGED
@@ -25,10 +25,11 @@ require 'tmpdir'
|
|
25
25
|
|
26
26
|
module Redwood
|
27
27
|
|
28
|
-
class TestCryptoManager <
|
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=> {:
|
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
|
@@ -60,6 +61,8 @@ class TestCryptoManager < ::Minitest::Unit::TestCase
|
|
60
61
|
if CryptoManager.have_crypto? then
|
61
62
|
signed = CryptoManager.sign @from_email,@to_email,"ABCDEFG"
|
62
63
|
assert_instance_of RMail::Message, signed
|
64
|
+
assert_equal("multipart/signed; protocol=application/pgp-signature; micalg=pgp-sha256",
|
65
|
+
signed.header["Content-Type"])
|
63
66
|
assert_equal "ABCDEFG", signed.body[0]
|
64
67
|
assert signed.body[1].body.length > 0 , "signature length must be > 0"
|
65
68
|
assert (signed.body[1].body.include? "-----BEGIN PGP SIGNATURE-----") , "Expecting PGP armored data"
|
@@ -104,6 +107,15 @@ class TestCryptoManager < ::Minitest::Unit::TestCase
|
|
104
107
|
CryptoManager.verify signed.body[0], signed.body[1], true
|
105
108
|
end
|
106
109
|
end
|
110
|
+
|
111
|
+
def test_verify_unknown_keytype
|
112
|
+
if CryptoManager.have_crypto?
|
113
|
+
signed = CryptoManager.sign @from_email_ecc, @to_email, "ABCDEFG"
|
114
|
+
assert_instance_of RMail::Message, signed
|
115
|
+
assert_instance_of String, (signed.body[1].body)
|
116
|
+
CryptoManager.verify signed.body[0], signed.body[1], true
|
117
|
+
end
|
118
|
+
end
|
107
119
|
end
|
108
120
|
|
109
121
|
end
|
data/test/test_header_parsing.rb
CHANGED
data/test/test_helper.rb
CHANGED
@@ -2,6 +2,9 @@ require "rubygems" rescue nil
|
|
2
2
|
require 'minitest/autorun'
|
3
3
|
require "rr"
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
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
|
data/test/test_message.rb
CHANGED
@@ -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 <
|
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
|
-
|
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
|
-
|
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
|
-
|
128
|
-
|
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
|
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
|
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
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
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
|
-
|
286
|
-
|
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
|
-
|
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> </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,58 @@ 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
|
180
|
+
|
181
|
+
# TODO: Add more asserts
|
182
|
+
end
|
183
|
+
|
184
|
+
def test_text_attachment_decoding
|
185
|
+
message = fixture('text-attachments-with-charset.eml')
|
424
186
|
|
187
|
+
source = DummySource.new("sup-test://test_text_attachment_decoding")
|
188
|
+
source.messages = [ message ]
|
189
|
+
source_info = 0
|
190
|
+
|
191
|
+
sup_message = Message.build_from_source(source, source_info)
|
425
192
|
sup_message.load_from_source!
|
193
|
+
|
194
|
+
chunks = sup_message.load_from_source!
|
195
|
+
assert_equal(5, chunks.length)
|
196
|
+
assert(chunks[0].is_a? Redwood::Chunk::Text)
|
197
|
+
## The first attachment declares charset=us-ascii
|
198
|
+
assert(chunks[1].is_a? Redwood::Chunk::Attachment)
|
199
|
+
assert_equal(["This is ASCII"], chunks[1].lines)
|
200
|
+
## The second attachment declares charset=koi8-r and has some Cyrillic
|
201
|
+
assert(chunks[2].is_a? Redwood::Chunk::Attachment)
|
202
|
+
assert_equal(["\u041f\u0440\u0438\u0432\u0435\u0442"], chunks[2].lines)
|
203
|
+
## The third attachment declares charset=utf-8 and has an emoji
|
204
|
+
assert(chunks[3].is_a? Redwood::Chunk::Attachment)
|
205
|
+
assert_equal(["\u{1f602}"], chunks[3].lines)
|
206
|
+
## The fourth attachment declares no charset and has a non-ASCII byte,
|
207
|
+
## which will be replaced with U+FFFD REPLACEMENT CHARACTER
|
208
|
+
assert(chunks[4].is_a? Redwood::Chunk::Attachment)
|
209
|
+
assert_equal(["Embedded\ufffdgarbage"], chunks[4].lines)
|
426
210
|
end
|
427
211
|
|
428
|
-
def
|
212
|
+
def test_mailing_list_header
|
213
|
+
message = fixture('mailing-list-header.eml')
|
429
214
|
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
(
|
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
|
215
|
+
source = DummySource.new("sup-test://test_mailing_list_header")
|
216
|
+
source.messages = [ message ]
|
217
|
+
source_info = 0
|
218
|
+
|
219
|
+
sup_message = Message.build_from_source(source, source_info)
|
220
|
+
sup_message.load_from_source!
|
221
|
+
|
222
|
+
assert(sup_message.list_subscribe.nil?)
|
223
|
+
assert_equal("<https://lists.openembedded.org/g/openembedded-devel/unsub>",
|
224
|
+
sup_message.list_unsubscribe)
|
225
|
+
assert_equal("openembedded-devel@lists.openembedded.org", sup_message.list_address.email)
|
226
|
+
assert_equal("openembedded-devel", sup_message.list_address.name)
|
227
|
+
end
|
228
|
+
|
229
|
+
def test_blank_header_lines
|
230
|
+
message = fixture('blank-header-fields.eml')
|
503
231
|
|
504
232
|
source = DummySource.new("sup-test://test_blank_header_lines")
|
505
233
|
source.messages = [ message ]
|
@@ -514,17 +242,63 @@ EOS
|
|
514
242
|
|
515
243
|
# Look at another header field whose first line was blank.
|
516
244
|
list_unsubscribe = sup_message.list_unsubscribe
|
517
|
-
assert_equal("<http://mailman2.widget.com/mailman/listinfo/monitor-list>,\n
|
245
|
+
assert_equal("<http://mailman2.widget.com/mailman/listinfo/monitor-list>,\n\t" +
|
518
246
|
"<mailto:monitor-list-request@widget.com?subject=unsubscribe>",
|
519
247
|
list_unsubscribe)
|
520
248
|
|
521
249
|
end
|
522
250
|
|
251
|
+
def test_malicious_attachment_names
|
252
|
+
message = fixture('malicious-attachment-names.eml')
|
253
|
+
|
254
|
+
source = DummySource.new("sup-test://test_blank_header_lines")
|
255
|
+
source.messages = [ message ]
|
256
|
+
source_info = 0
|
257
|
+
|
258
|
+
sup_message = Message.build_from_source(source, source_info)
|
259
|
+
chunks = sup_message.load_from_source!
|
260
|
+
|
261
|
+
# See if attachment filenames can be safely used for saving.
|
262
|
+
# We do that by verifying that any folder-related character (/ or \)
|
263
|
+
# are not interpreted: the filename must not be interpreted into a
|
264
|
+
# path.
|
265
|
+
fn = chunks[3].safe_filename
|
266
|
+
assert_equal(fn, File.basename(fn))
|
267
|
+
end
|
523
268
|
# TODO: test different error cases, malformed messages etc.
|
524
269
|
|
525
270
|
# TODO: test different quoting styles, see that they are all divided
|
526
271
|
# to chunks properly
|
527
272
|
|
273
|
+
def test_zimbra_quote_with_bottom_post
|
274
|
+
# Zimbra does an Outlook-style "Original Message" delimiter and then *also*
|
275
|
+
# prefixes each quoted line with a > marker. That's okay until the sender
|
276
|
+
# tries to do the right thing and reply after the quote.
|
277
|
+
# In this case we want to just look at the > markers when determining where
|
278
|
+
# the quoted chunk ends.
|
279
|
+
message = fixture('zimbra-quote-with-bottom-post.eml')
|
280
|
+
|
281
|
+
source = DummySource.new("sup-test://test_zimbra_quote_with_bottom_post")
|
282
|
+
source.messages = [ message ]
|
283
|
+
source_info = 0
|
284
|
+
|
285
|
+
sup_message = Message.build_from_source(source, source_info)
|
286
|
+
chunks = sup_message.load_from_source!
|
287
|
+
|
288
|
+
assert_equal(3, chunks.length)
|
289
|
+
|
290
|
+
# TODO this chunk should ideally be part of the quote chunk after it.
|
291
|
+
assert(chunks[0].is_a? Redwood::Chunk::Text)
|
292
|
+
assert_equal(1, chunks[0].lines.length)
|
293
|
+
assert_equal("----- Original Message -----", chunks[0].lines.first)
|
294
|
+
|
295
|
+
assert(chunks[1].is_a? Redwood::Chunk::Quote)
|
296
|
+
|
297
|
+
assert(chunks[2].is_a? Redwood::Chunk::Text)
|
298
|
+
assert_equal(3, chunks[2].lines.length)
|
299
|
+
assert_equal("This is the reply from the Zimbra user.",
|
300
|
+
chunks[2].lines[2])
|
301
|
+
end
|
528
302
|
end
|
529
303
|
|
530
304
|
end
|