[3.13] gh-144156: Fix email header folding concatenating encoded words (GH-144692) by bitdancer · Pull Request #145195 · python/cpython · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 37 additions & 36 deletions Lib/email/_header_value_parser.py
44 changes: 44 additions & 0 deletions Lib/test/test_email/test_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,50 @@ def test_defaults_handle_spaces_at_start_of_continuation_line(self):
g.flatten(msg)
self.assertEqual(s.getvalue(), expected)

# gh-144156: fold between non-encoded and encoded words don't need to encoded
# the separating space
def test_defaults_handle_spaces_at_start_of_continuation_line_2(self):
source = ("Re: [SOS-1495488] Commande et livraison - Demande de retour - "
"bibijolie - 251210-AABBCC - Abo actualités digitales 20 semaines "
"d’abonnement à 24 heures, Bilan, Tribune de Genève et tous les titres Tamedia")
expected = (
b"Subject: "
b"Re: [SOS-1495488] Commande et livraison - Demande de retour -\n"
b" bibijolie - 251210-AABBCC - Abo =?utf-8?q?actualit=C3=A9s?= digitales 20\n"
b" semaines =?utf-8?q?d=E2=80=99abonnement_=C3=A0?= 24 heures, Bilan, Tribune de\n"
b" =?utf-8?q?Gen=C3=A8ve?= et tous les titres Tamedia\n\n"
)
msg = EmailMessage()
msg['Subject'] = source
s = io.BytesIO()
g = BytesGenerator(s)
g.flatten(msg)
self.assertEqual(s.getvalue(), expected)

def test_ew_folding_round_trip_1(self):
print()
source = "aaaaaaaaa фффффффф "
msg = EmailMessage()
msg['Subject'] = source
s = io.BytesIO()
g = BytesGenerator(s, maxheaderlen=30)
g.flatten(msg)
flat = s.getvalue()
reparsed = message_from_bytes(flat, policy=policy.default)['Subject']
self.assertMultiLineEqual(reparsed, source)

def test_ew_folding_round_trip_2(self):
print()
source = "aaa aaaaaaa aaa ффф фффф "
msg = EmailMessage()
msg['Subject'] = source
s = io.BytesIO()
g = BytesGenerator(s, maxheaderlen=30)
g.flatten(msg)
flat = s.getvalue()
reparsed = message_from_bytes(flat, policy=policy.default)['Subject']
self.assertMultiLineEqual(reparsed, source)

def test_cte_type_7bit_handles_unknown_8bit(self):
source = ("Subject: Maintenant je vous présente mon "
"collègue\n\n").encode('utf-8')
Expand Down
4 changes: 2 additions & 2 deletions Lib/test/test_email/test_headerregistry.py
Original file line number Diff line number Diff line change
Expand Up @@ -1703,7 +1703,7 @@ def test_fold_unstructured_with_overlong_word(self):
'singlewordthatwontfit')
self.assertEqual(
h.fold(policy=policy.default.clone(max_line_length=20)),
'Subject: \n'
'Subject:\n'
' =?utf-8?q?thisisa?=\n'
' =?utf-8?q?verylon?=\n'
' =?utf-8?q?glineco?=\n'
Expand All @@ -1719,7 +1719,7 @@ def test_fold_unstructured_with_two_overlong_words(self):
'singlewordthatwontfit plusanotherverylongwordthatwontfit')
self.assertEqual(
h.fold(policy=policy.default.clone(max_line_length=20)),
'Subject: \n'
'Subject:\n'
' =?utf-8?q?thisisa?=\n'
' =?utf-8?q?verylon?=\n'
' =?utf-8?q?glineco?=\n'
Expand Down
2 changes: 1 addition & 1 deletion Lib/test/test_email/test_policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ def test_non_ascii_chars_do_not_cause_inf_loop(self):
actual = policy.fold('Subject', 'ą' * 12)
self.assertEqual(
actual,
'Subject: \n' +
'Subject:\n' +
12 * ' =?utf-8?q?=C4=85?=\n')

def test_short_maxlen_error(self):
Expand Down
Loading