Skip to content

Commit 0b64fd5

Browse files
beledouxdenissethmlarson
authored andcommitted
email: correctly indent with a least one space folded comments
1 parent 3199cfc commit 0b64fd5

File tree

2 files changed

+78
-2
lines changed

2 files changed

+78
-2
lines changed

Lib/email/_header_value_parser.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2941,7 +2941,10 @@ def _refold_parse_tree(parse_tree, *, policy):
29412941
# the way encoded strings handle continuation lines, we need to
29422942
# be prepared to encode any whitespace if the next line turns
29432943
# out to start with an encoded word.
2944-
lines.append(newline + tstr)
2944+
line = newline + tstr
2945+
if line[0] not in WSP:
2946+
line = ' ' + line
2947+
lines.append(line)
29452948

29462949
whitespace_accumulator = []
29472950
for char in lines[-1]:
@@ -2977,7 +2980,10 @@ def _refold_parse_tree(parse_tree, *, policy):
29772980
# We can't figure out how to wrap, it, so give up.
29782981
newline = _steal_trailing_WSP_if_exists(lines)
29792982
if newline or part.startswith_fws():
2980-
lines.append(newline + tstr)
2983+
line = newline + tstr
2984+
if line[0] not in WSP:
2985+
line = ' ' + line
2986+
lines.append(line)
29812987
else:
29822988
# We can't fold it onto the next line either...
29832989
lines[-1] += tstr

Lib/test/test_email/test__header_value_parser.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3294,6 +3294,76 @@ def test_address_list_with_specials_in_long_quoted_string(self):
32943294
with self.subTest(to=to):
32953295
self._test(parser.get_address_list(to)[0], folded, policy=policy)
32963296

3297+
def test_address_list_with_long_unwrapable_comment(self):
3298+
policy = self.policy.clone(max_line_length=40)
3299+
cases = [
3300+
# (to, folded)
3301+
3302+
# 1. Unwrappable Comments
3303+
3304+
# Entire line is <= 40 characters, 40 characters exactly
3305+
# No folding
3306+
('spy@example.org(loremipsumdolorsitametc)', 'spy@example.org(loremipsumdolorsitametc)\n'),
3307+
('(loremipsumdolorsitametc)spy@example.org', '(loremipsumdolorsitametc)spy@example.org\n'),
3308+
# Entire line is > 40 characters, 41 characters
3309+
# Folding triggered
3310+
('spy@example.org(loremipsumdolorsitametco)','spy@example.org\n (loremipsumdolorsitametco)\n'),
3311+
('(loremipsumdolorsitametco)spy@example.org', '(loremipsumdolorsitametco)spy@example.org\n'),
3312+
# Entire line is > 40 characters, 54 characters, `len(tstr) <= maxlen - len(lines[-1])` is `True`
3313+
# Folding triggered
3314+
# Comment part < 40 characthers, 39 characters, `len(tstr) + 1 <= maxlen` is `True`
3315+
# No attempt to fold the subpart
3316+
('spy@example.org(loremipsumdolorsitametconsecteturadip)',
3317+
'spy@example.org\n'
3318+
' (loremipsumdolorsitametconsecteturadip)\n'),
3319+
('(loremipsumdolorsitametconsecteturadip)spy@example.org',
3320+
'(loremipsumdolorsitametconsecteturadip)spy@example.org\n'),
3321+
# Entire line is > 40 characters, 55 characters, `len(tstr) <= maxlen - len(lines[-1])` is `True`
3322+
# Folding triggered
3323+
# Comment part >= 40 characters, 40 characters exactly, `len(tstr) + 1 <= maxlen` is `False`
3324+
# Attempt to fold the subpart
3325+
('spy@example.org(loremipsumdolorsitametconsecteturadipi)',
3326+
'spy@example.org\n'
3327+
' (loremipsumdolorsitametconsecteturadipi)\n'),
3328+
('(loremipsumdolorsitametconsecteturadipi)spy@example.org',
3329+
'(loremipsumdolorsitametconsecteturadipi)spy@example.org\n'),
3330+
3331+
# 2. Wrappable comments
3332+
3333+
# Entire line is <= 40 characters, 40 characters exactly
3334+
# No folding
3335+
('spy@example.org(loremipsumd olorsitamet)', 'spy@example.org(loremipsumd olorsitamet)\n'),
3336+
('(loremipsumd olorsitamet)spy@example.org', '(loremipsumd olorsitamet)spy@example.org\n'),
3337+
# Entire line is > 40 characters, 41 characters
3338+
# Folding triggered
3339+
# Comment part < 40 characters
3340+
('spy@example.org(loremipsumd olorsitametc)', 'spy@example.org\n (loremipsumd olorsitametc)\n'),
3341+
('(loremipsumd olorsitametc)spy@example.org', '(loremipsumd olorsitametc)spy@example.org\n'),
3342+
# Entire line is > 40 characters, 56 characters
3343+
# Folding triggered
3344+
# Comment part > 40 characters, 41 characters
3345+
('spy@example.org(loremipsumd loremipsumdolorsitametconse)', 'spy@example.org(loremipsumd\n loremipsumdolorsitametconse)\n'),
3346+
('(loremipsumd loremipsumdolorsitametconse)spy@example.org', '(loremipsumd\n loremipsumdolorsitametconse)spy@example.org\n'),
3347+
# Entire line is > 40 characters, 70 characters
3348+
# Folding triggered
3349+
# Comment part > 40 characters, 55 characters
3350+
# One word in the comment > 40 characters, 41 characters
3351+
('spy@example.org(loremipsumd loremipsumdolorsitametconsecteturadipisci)', 'spy@example.org(loremipsumd\n loremipsumdolorsitametconsecteturadipisci)\n'),
3352+
('(loremipsumd loremipsumdolorsitametconsecteturadipisci)spy@example.org', '(loremipsumd\n loremipsumdolorsitametconsecteturadipisci)spy@example.org\n'),
3353+
3354+
# 3. Nested comments
3355+
3356+
('spy@example.org((loremipsumdolorsitametconsecteturadi))', 'spy@example.org(\n (loremipsumdolorsitametconsecteturadi))\n'),
3357+
('spy@example.org((loremipsumdolorsitametconsecteturadip))', 'spy@example.org(\n (loremipsumdolorsitametconsecteturadip)\n )\n'),
3358+
('spy@example.org((loremipsumdolorsitam)(loremipsumdolorsitam))', 'spy@example.org((loremipsumdolorsitam)\n (loremipsumdolorsitam))\n'),
3359+
('spy@example.org((loremipsumdolorsitametc)(loremipsumdolorsitametc))', 'spy@example.org(\n (loremipsumdolorsitametc)\n (loremipsumdolorsitametc))\n'),
3360+
('spy@example.org(loremipsumdolorsitametc(loremipsumdolorsitametc))', 'spy@example.org(loremipsumdolorsitametc\n (loremipsumdolorsitametc))\n'),
3361+
('spy@example.org((loremipsumdolorsitametc)loremipsumdolorsitametc)', 'spy@example.org(\n (loremipsumdolorsitametc)\n loremipsumdolorsitametc)\n'),
3362+
]
3363+
for (to, folded) in cases:
3364+
with self.subTest(to=to):
3365+
self._test(parser.get_address_list(to)[0], folded, policy=policy)
3366+
32973367
# XXX Need tests with comments on various sides of a unicode token,
32983368
# and with unicode tokens in the comments. Spaces inside the quotes
32993369
# currently don't do the right thing.

0 commit comments

Comments
 (0)