Skip to content

Commit bf2e3df

Browse files
author
Ralf Schlatterbeck
committed
Fix charset of first text-part of outgoing multipart messages...
...thanks Dirk Geschke for reporting, see http://thread.gmane.org/gmane.comp.bug-tracking.roundup.user/10223 This also adds some regression tests to test incoming latin1 and outgoing single- and multipart utf-8 and latin1 messages
1 parent 898e957 commit bf2e3df

File tree

4 files changed

+256
-0
lines changed

4 files changed

+256
-0
lines changed

CHANGES.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ Fixed:
3030
(thanks Ezio Melotti)
3131
- fixed registration, issue2550665 (thanks Timo Paulssen)
3232
- make sorting of multilinks in the web interface more robust, issue2550663
33+
- Fix charset of first text-part of outgoing multipart messages, thanks Dirk
34+
Geschke for reporting, see
35+
http://thread.gmane.org/gmane.comp.bug-tracking.roundup.user/10223
3336

3437

3538
2010-07-12 1.4.15

doc/acknowledgements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ Hernan Martinez Foffani,
4242
Stuart D. Gathman,
4343
Martin Geisler,
4444
Ajit George,
45+
Dirk Geschke,
4546
Frank Gibbons,
4647
Johannes Gijsbers,
4748
Christian Glass,

roundup/roundupdb.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,7 @@ def send_message(self, issueid, msgid, note, sendto, from_address=None,
472472
if message_files:
473473
# first up the text as a part
474474
part = MIMEText(body)
475+
part.set_charset(charset)
475476
encode_quopri(part)
476477
message.attach(part)
477478

test/test_mailgw.py

Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,29 @@ def testNewIssueNoAuthorEmail(self):
458458
--bCsyhTFzCvuiizWF--
459459
460460
--bxyzzy--
461+
'''
462+
463+
multipart_msg_latin1 = '''From: mary <[email protected]>
464+
465+
Message-Id: <followup_dummy_id>
466+
In-Reply-To: <dummy_test_message_id>
467+
Subject: [issue1] Testing...
468+
Content-Type: multipart/alternative; boundary=001485f339f8f361fb049188dbba
469+
470+
471+
--001485f339f8f361fb049188dbba
472+
Content-Type: text/plain; charset=ISO-8859-1
473+
Content-Transfer-Encoding: quoted-printable
474+
475+
umlaut =E4=F6=FC=C4=D6=DC=DF
476+
477+
--001485f339f8f361fb049188dbba
478+
Content-Type: text/html; charset=ISO-8859-1
479+
Content-Transfer-Encoding: quoted-printable
480+
481+
<html>umlaut =E4=F6=FC=C4=D6=DC=DF</html>
482+
483+
--001485f339f8f361fb049188dbba--
461484
'''
462485

463486
def testMultipartKeepAlternatives(self):
@@ -495,6 +518,234 @@ def testMultipartDropAlternatives(self):
495518
self.assertEqual(f.content, content [n])
496519
self.assertEqual(msg.content, 'test attachment second text/plain')
497520

521+
def testMultipartCharsetUTF8NoAttach(self):
522+
c = 'umlaut \xc3\xa4\xc3\xb6\xc3\xbc\xc3\x84\xc3\x96\xc3\x9c\xc3\x9f'
523+
self.doNewIssue()
524+
self.db.config.NOSY_MAX_ATTACHMENT_SIZE = 0
525+
self._handle_mail(self.multipart_msg_latin1)
526+
messages = self.db.issue.get('1', 'messages')
527+
messages.sort()
528+
msg = self.db.msg.getnode (messages[-1])
529+
assert(len(msg.files) == 1)
530+
name = 'unnamed'
531+
content = '<html>' + c + '</html>\n'
532+
for n, id in enumerate (msg.files):
533+
f = self.db.file.getnode (id)
534+
self.assertEqual(f.name, name)
535+
self.assertEqual(f.content, content)
536+
self.assertEqual(msg.content, c)
537+
self.compareMessages(self._get_mail(),
538+
539+
540+
Content-Type: text/plain; charset="utf-8"
541+
Subject: [issue1] Testing...
542+
543+
From: "Contrary, Mary" <[email protected]>
544+
Reply-To: Roundup issue tracker
545+
546+
MIME-Version: 1.0
547+
Message-Id: <followup_dummy_id>
548+
In-Reply-To: <dummy_test_message_id>
549+
X-Roundup-Name: Roundup issue tracker
550+
X-Roundup-Loop: hello
551+
X-Roundup-Issue-Status: chatting
552+
X-Roundup-Issue-Files: unnamed
553+
Content-Transfer-Encoding: quoted-printable
554+
555+
556+
Contrary, Mary <[email protected]> added the comment:
557+
558+
umlaut =C3=A4=C3=B6=C3=BC=C3=84=C3=96=C3=9C=C3=9F
559+
File 'unnamed' not attached - you can download it from http://tracker.examp=
560+
le/cgi-bin/roundup.cgi/bugs/file1.
561+
562+
----------
563+
status: unread -> chatting
564+
565+
_______________________________________________________________________
566+
Roundup issue tracker <[email protected]>
567+
<http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
568+
_______________________________________________________________________
569+
''')
570+
571+
def testMultipartCharsetLatin1NoAttach(self):
572+
c = 'umlaut \xc3\xa4\xc3\xb6\xc3\xbc\xc3\x84\xc3\x96\xc3\x9c\xc3\x9f'
573+
self.doNewIssue()
574+
self.db.config.NOSY_MAX_ATTACHMENT_SIZE = 0
575+
self.db.config.MAIL_CHARSET = 'iso-8859-1'
576+
self._handle_mail(self.multipart_msg_latin1)
577+
messages = self.db.issue.get('1', 'messages')
578+
messages.sort()
579+
msg = self.db.msg.getnode (messages[-1])
580+
assert(len(msg.files) == 1)
581+
name = 'unnamed'
582+
content = '<html>' + c + '</html>\n'
583+
for n, id in enumerate (msg.files):
584+
f = self.db.file.getnode (id)
585+
self.assertEqual(f.name, name)
586+
self.assertEqual(f.content, content)
587+
self.assertEqual(msg.content, c)
588+
self.compareMessages(self._get_mail(),
589+
590+
591+
Content-Type: text/plain; charset="iso-8859-1"
592+
Subject: [issue1] Testing...
593+
594+
From: "Contrary, Mary" <[email protected]>
595+
Reply-To: Roundup issue tracker
596+
597+
MIME-Version: 1.0
598+
Message-Id: <followup_dummy_id>
599+
In-Reply-To: <dummy_test_message_id>
600+
X-Roundup-Name: Roundup issue tracker
601+
X-Roundup-Loop: hello
602+
X-Roundup-Issue-Status: chatting
603+
X-Roundup-Issue-Files: unnamed
604+
Content-Transfer-Encoding: quoted-printable
605+
606+
607+
Contrary, Mary <[email protected]> added the comment:
608+
609+
umlaut =E4=F6=FC=C4=D6=DC=DF
610+
File 'unnamed' not attached - you can download it from http://tracker.examp=
611+
le/cgi-bin/roundup.cgi/bugs/file1.
612+
613+
----------
614+
status: unread -> chatting
615+
616+
_______________________________________________________________________
617+
Roundup issue tracker <[email protected]>
618+
<http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
619+
_______________________________________________________________________
620+
''')
621+
622+
def testMultipartCharsetUTF8AttachFile(self):
623+
c = 'umlaut \xc3\xa4\xc3\xb6\xc3\xbc\xc3\x84\xc3\x96\xc3\x9c\xc3\x9f'
624+
self.doNewIssue()
625+
self._handle_mail(self.multipart_msg_latin1)
626+
messages = self.db.issue.get('1', 'messages')
627+
messages.sort()
628+
msg = self.db.msg.getnode (messages[-1])
629+
assert(len(msg.files) == 1)
630+
name = 'unnamed'
631+
content = '<html>' + c + '</html>\n'
632+
for n, id in enumerate (msg.files):
633+
f = self.db.file.getnode (id)
634+
self.assertEqual(f.name, name)
635+
self.assertEqual(f.content, content)
636+
self.assertEqual(msg.content, c)
637+
self.compareMessages(self._get_mail(),
638+
639+
640+
Content-Type: multipart/mixed; boundary="utf-8"
641+
Subject: [issue1] Testing...
642+
643+
From: "Contrary, Mary" <[email protected]>
644+
Reply-To: Roundup issue tracker
645+
646+
MIME-Version: 1.0
647+
Message-Id: <followup_dummy_id>
648+
In-Reply-To: <dummy_test_message_id>
649+
X-Roundup-Name: Roundup issue tracker
650+
X-Roundup-Loop: hello
651+
X-Roundup-Issue-Status: chatting
652+
X-Roundup-Issue-Files: unnamed
653+
Content-Transfer-Encoding: quoted-printable
654+
655+
656+
--utf-8
657+
MIME-Version: 1.0
658+
Content-Type: text/plain; charset="utf-8"
659+
Content-Transfer-Encoding: quoted-printable
660+
661+
662+
Contrary, Mary <[email protected]> added the comment:
663+
664+
umlaut =C3=A4=C3=B6=C3=BC=C3=84=C3=96=C3=9C=C3=9F
665+
666+
----------
667+
status: unread -> chatting
668+
669+
_______________________________________________________________________
670+
Roundup issue tracker <[email protected]>
671+
<http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
672+
_______________________________________________________________________
673+
--utf-8
674+
Content-Type: text/html
675+
MIME-Version: 1.0
676+
Content-Transfer-Encoding: base64
677+
Content-Disposition: attachment;
678+
filename="unnamed"
679+
680+
PGh0bWw+dW1sYXV0IMOkw7bDvMOEw5bDnMOfPC9odG1sPgo=
681+
682+
--utf-8--
683+
''')
684+
685+
def testMultipartCharsetLatin1AttachFile(self):
686+
c = 'umlaut \xc3\xa4\xc3\xb6\xc3\xbc\xc3\x84\xc3\x96\xc3\x9c\xc3\x9f'
687+
self.doNewIssue()
688+
self.db.config.MAIL_CHARSET = 'iso-8859-1'
689+
self._handle_mail(self.multipart_msg_latin1)
690+
messages = self.db.issue.get('1', 'messages')
691+
messages.sort()
692+
msg = self.db.msg.getnode (messages[-1])
693+
assert(len(msg.files) == 1)
694+
name = 'unnamed'
695+
content = '<html>' + c + '</html>\n'
696+
for n, id in enumerate (msg.files):
697+
f = self.db.file.getnode (id)
698+
self.assertEqual(f.name, name)
699+
self.assertEqual(f.content, content)
700+
self.assertEqual(msg.content, c)
701+
self.compareMessages(self._get_mail(),
702+
703+
704+
Content-Type: multipart/mixed; boundary="utf-8"
705+
Subject: [issue1] Testing...
706+
707+
From: "Contrary, Mary" <[email protected]>
708+
Reply-To: Roundup issue tracker
709+
710+
MIME-Version: 1.0
711+
Message-Id: <followup_dummy_id>
712+
In-Reply-To: <dummy_test_message_id>
713+
X-Roundup-Name: Roundup issue tracker
714+
X-Roundup-Loop: hello
715+
X-Roundup-Issue-Status: chatting
716+
X-Roundup-Issue-Files: unnamed
717+
Content-Transfer-Encoding: quoted-printable
718+
719+
720+
--utf-8
721+
MIME-Version: 1.0
722+
Content-Type: text/plain; charset="iso-8859-1"
723+
Content-Transfer-Encoding: quoted-printable
724+
725+
726+
Contrary, Mary <[email protected]> added the comment:
727+
728+
umlaut =E4=F6=FC=C4=D6=DC=DF
729+
730+
----------
731+
status: unread -> chatting
732+
733+
_______________________________________________________________________
734+
Roundup issue tracker <[email protected]>
735+
<http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
736+
_______________________________________________________________________
737+
--utf-8
738+
Content-Type: text/html
739+
MIME-Version: 1.0
740+
Content-Transfer-Encoding: base64
741+
Content-Disposition: attachment;
742+
filename="unnamed"
743+
744+
PGh0bWw+dW1sYXV0IMOkw7bDvMOEw5bDnMOfPC9odG1sPgo=
745+
746+
--utf-8--
747+
''')
748+
498749
def testSimpleFollowup(self):
499750
self.doNewIssue()
500751
self._handle_mail('''Content-Type: text/plain;

0 commit comments

Comments
 (0)