https://github.com/python/cpython/commit/07eff899d8a8ee4c4b1be7cb223fe25687f6216c
commit: 07eff899d8a8ee4c4b1be7cb223fe25687f6216c
branch: main
author: Paresh Joshi <[email protected]>
committer: bitdancer <[email protected]>
date: 2025-12-06T15:59:35-05:00
summary:
gh-142006: Fix HeaderWriteError in email.policy.default caused by extra newline
(#142008)
RDM: This fixes a subtle folding error that showed up when a token exactly
filled a line and was followed by whitespace and a token with no folding
whitespace that was longer than a line. In this particular circumstance the
whitespace after the first token got pushed on to the next line, and then
stolen to go in front of the next unfoldable token...leaving a completely empty
line in the line buffer. That line got turned in to a newline, which is RFC
illegal, and the newish security check caught it. The fix is to just delete
that empty line from the buffer.
Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
files:
A Misc/NEWS.d/next/Library/2025-11-27-10-49-13.gh-issue-142006.nzJDG5.rst
M Lib/email/_header_value_parser.py
M Lib/test/test_email/test__header_value_parser.py
diff --git a/Lib/email/_header_value_parser.py
b/Lib/email/_header_value_parser.py
index c7f665b3990512..cbff9694742490 100644
--- a/Lib/email/_header_value_parser.py
+++ b/Lib/email/_header_value_parser.py
@@ -2792,6 +2792,9 @@ def _steal_trailing_WSP_if_exists(lines):
if lines and lines[-1] and lines[-1][-1] in WSP:
wsp = lines[-1][-1]
lines[-1] = lines[-1][:-1]
+ # gh-142006: if the line is now empty, remove it entirely.
+ if not lines[-1]:
+ lines.pop()
return wsp
def _refold_parse_tree(parse_tree, *, policy):
diff --git a/Lib/test/test_email/test__header_value_parser.py
b/Lib/test/test_email/test__header_value_parser.py
index 179e236ecdfd7f..f7f9f9c4e2fbb5 100644
--- a/Lib/test/test_email/test__header_value_parser.py
+++ b/Lib/test/test_email/test__header_value_parser.py
@@ -3255,5 +3255,15 @@ def test_long_filename_attachment(self):
" filename*1*=_TEST_TES.txt\n",
)
+ def test_fold_unfoldable_element_stealing_whitespace(self):
+ # gh-142006: When an element is too long to fit on the current line
+ # the previous line's trailing whitespace should not trigger a double
newline.
+ policy = self.policy.clone(max_line_length=10)
+ # The non-whitespace text needs to exactly fill the max_line_length
(10).
+ text = ("a" * 9) + ", " + ("b" * 20)
+ expected = ("a" * 9) + ",\n " + ("b" * 20) + "\n"
+ token = parser.get_address_list(text)[0]
+ self._test(token, expected, policy=policy)
+
if __name__ == '__main__':
unittest.main()
diff --git
a/Misc/NEWS.d/next/Library/2025-11-27-10-49-13.gh-issue-142006.nzJDG5.rst
b/Misc/NEWS.d/next/Library/2025-11-27-10-49-13.gh-issue-142006.nzJDG5.rst
new file mode 100644
index 00000000000000..49643892ff9ccd
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-11-27-10-49-13.gh-issue-142006.nzJDG5.rst
@@ -0,0 +1 @@
+Fix a bug in the :mod:`email.policy.default` folding algorithm which
incorrectly resulted in a doubled newline when a line ending at exactly
max_line_length was followed by an unfoldable token.
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]