Skip to content

Commit 42d48ed

Browse files
committed
Fix gh-142006: email.policy.default adds extra newline to headers
1 parent f7b6036 commit 42d48ed

2 files changed

Lines changed: 18 additions & 0 deletions

File tree

Lib/email/_header_value_parser.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2792,6 +2792,10 @@ def _steal_trailing_WSP_if_exists(lines):
27922792
if lines and lines[-1] and lines[-1][-1] in WSP:
27932793
wsp = lines[-1][-1]
27942794
lines[-1] = lines[-1][:-1]
2795+
# FIX: If the line is now empty (it was only a space), remove it entirely
2796+
# to prevent creating an empty line (double newline) in the output.
2797+
if not lines[-1]:
2798+
lines.pop()
27952799
return wsp
27962800

27972801
def _refold_parse_tree(parse_tree, *, policy):

Lib/test/test_email/test_policy.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,20 @@ def test_fold_zero_max_line_length(self):
165165
self.assertEqual(p1.fold('Subject', msg['Subject']), expected)
166166
self.assertEqual(p2.fold('Subject', msg['Subject']), expected)
167167

168+
def test_fold_address_list_with_stolen_whitespace(self):
169+
long_address = (
170+
"loooooooooooooooooooooooooooooooooooong@dooooooooooooomainname.example.com, "
171+
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.example.com"
172+
)
173+
msg = email.message_from_string(f"To: {long_address}\n\n", policy=email.policy.default)
174+
175+
# This should not raise HeaderWriteError
176+
output = msg.as_string()
177+
# Verify the output format is correct and clean
178+
self.assertIn(long_address.split(',')[0], output)
179+
# Ensure header section doesn't have double newlines
180+
self.assertNotIn('\n\n', output.split('\n\n')[0])
181+
168182
def test_register_defect(self):
169183
class Dummy:
170184
def __init__(self):

0 commit comments

Comments
 (0)