Skip to content

Commit 0a645fd

Browse files
committed
Parse RFC2047 formatted text properly in submission form. Fixes ietf-tools#2465. Commit ready for merge.
- Legacy-Id: 19120
1 parent a83d60d commit 0a645fd

4 files changed

Lines changed: 38 additions & 3 deletions

File tree

ietf/submit/models.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from ietf.message.models import Message
1717
from ietf.name.models import DraftSubmissionStateName, FormalLanguageName
1818
from ietf.utils.accesstoken import generate_random_key, generate_access_token
19+
from ietf.utils.text import parse_unicode
1920
from ietf.utils.models import ForeignKey
2021

2122

@@ -25,7 +26,7 @@ def parse_email_line(line):
2526
email.utils.parseaddr() but return a dictionary
2627
"""
2728
name, addr = email.utils.parseaddr(line) if '@' in line else (line, '')
28-
return dict(name=name, email=addr)
29+
return dict(name=parse_unicode(name), email=addr)
2930

3031
class Submission(models.Model):
3132
state = ForeignKey(DraftSubmissionStateName)
@@ -169,4 +170,4 @@ class Meta:
169170

170171

171172
class SubmissionExtResource(ExtResource):
172-
submission = ForeignKey(Submission, related_name='external_resources')
173+
submission = ForeignKey(Submission, related_name='external_resources')

ietf/submit/utils.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
from ietf.utils.accesstoken import generate_random_key
4242
from ietf.utils.draft import Draft
4343
from ietf.utils.mail import is_valid_email
44+
from ietf.utils.text import parse_unicode
4445
from ietf.person.name import unidecode_name
4546

4647

@@ -886,7 +887,7 @@ def accept_submission(request, submission, autopost=False):
886887
requires_prev_ad_approval = False
887888

888889
# Partial message for submission event
889-
sub_event_desc = 'Set submitter to \"%s\", replaces to %s' % (submission.submitter, pretty_replaces)
890+
sub_event_desc = 'Set submitter to \"%s\", replaces to %s' % (parse_unicode(submission.submitter), pretty_replaces)
890891
docevent_desc = None
891892
address_list = []
892893
if requires_ad_approval or requires_prev_ad_approval:

ietf/utils/tests.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
from ietf.utils.mail import send_mail_preformatted, send_mail_text, send_mail_mime, outbox, get_payload_text
4444
from ietf.utils.test_runner import get_template_paths, set_coverage_checking
4545
from ietf.utils.test_utils import TestCase
46+
from ietf.utils.text import parse_unicode
4647

4748
skip_wiki_glue_testing = False
4849
skip_message_svn = ""
@@ -506,3 +507,21 @@ def test_assertion(self):
506507
settings.SERVER_MODE = 'development'
507508
assertion('False')
508509
settings.SERVER_MODE = 'test'
510+
511+
class TestRFC2047Strings(TestCase):
512+
def test_parse_unicode(self):
513+
names = (
514+
('=?utf-8?b?4Yuz4YuK4Ym1IOGJoOGJgOGIiA==?=', 'ዳዊት በቀለ'),
515+
('=?utf-8?b?5Li9IOmDnA==?=', '丽 郜'),
516+
('=?utf-8?b?4KSV4KSu4KWN4KSs4KWL4KScIOCkoeCkvuCksA==?=', 'कम्बोज डार'),
517+
('=?utf-8?b?zpfPgc6szrrOu861zrnOsSDOm865z4zOvc+Ezrc=?=', 'Ηράκλεια Λιόντη'),
518+
('=?utf-8?b?15nXqdeo15DXnCDXqNeV15bXoNek15zXkw==?=', 'ישראל רוזנפלד'),
519+
('=?utf-8?b?5Li95Y2OIOeahw==?=', '丽华 皇'),
520+
('=?utf-8?b?77ul77qu766V77qzIO+tlu+7ru+vvu+6ju+7pw==?=', 'ﻥﺮﮕﺳ ﭖﻮﯾﺎﻧ'),
521+
('=?utf-8?b?77uh77uu77qz77uu76++IO+6su+7tO+7p++6jSDvurDvu6Pvuo7vu6jvr74=?=', 'ﻡﻮﺳﻮﯾ ﺲﻴﻧﺍ ﺰﻣﺎﻨﯾ'),
522+
('=?utf-8?b?ScOxaWdvIFNhbsOnIEliw6HDsWV6IGRlIGxhIFBlw7Fh?=', 'Iñigo Sanç Ibáñez de la Peña'),
523+
('Mart van Oostendorp', 'Mart van Oostendorp'),
524+
('', ''),
525+
)
526+
for encoded_str, unicode in names:
527+
self.assertEqual(unicode, parse_unicode(encoded_str))

ietf/utils/text.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# -*- coding: utf-8 -*-
33

44

5+
import email
56
import re
67
import textwrap
78
import unicodedata
@@ -193,3 +194,16 @@ def unwrap(s):
193194

194195
def normalize_text(s):
195196
return re.sub(r'[\s\n\r\u2028\u2029]+', ' ', s, flags=re.U).strip()
197+
198+
def parse_unicode(text):
199+
"Decodes unicode string from string encoded according to RFC2047"
200+
201+
decoded_string, charset = email.header.decode_header(text)[0]
202+
if charset is not None:
203+
try:
204+
text = decoded_string.decode(charset)
205+
except UnicodeDecodeError:
206+
pass
207+
else:
208+
text = decoded_string
209+
return text

0 commit comments

Comments
 (0)