sup 0.20.0 → 1.0
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.
- 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
|