Skip to content

Commit 07eff89

Browse files
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>
1 parent 100e316 commit 07eff89

File tree

3 files changed

+14
-0
lines changed

3 files changed

+14
-0
lines changed

‎Lib/email/_header_value_parser.py‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2792,6 +2792,9 @@ 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+
# gh-142006: if the line is now empty, remove it entirely.
2796+
if not lines[-1]:
2797+
lines.pop()
27952798
return wsp
27962799

27972800
def _refold_parse_tree(parse_tree, *, policy):

‎Lib/test/test_email/test__header_value_parser.py‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3255,5 +3255,15 @@ def test_long_filename_attachment(self):
32553255
" filename*1*=_TEST_TES.txt\n",
32563256
)
32573257

3258+
def test_fold_unfoldable_element_stealing_whitespace(self):
3259+
# gh-142006: When an element is too long to fit on the current line
3260+
# the previous line's trailing whitespace should not trigger a double newline.
3261+
policy = self.policy.clone(max_line_length=10)
3262+
# The non-whitespace text needs to exactly fill the max_line_length (10).
3263+
text = ("a" * 9) + ", " + ("b" * 20)
3264+
expected = ("a" * 9) + ",\n " + ("b" * 20) + "\n"
3265+
token = parser.get_address_list(text)[0]
3266+
self._test(token, expected, policy=policy)
3267+
32583268
if __name__ == '__main__':
32593269
unittest.main()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
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.

0 commit comments

Comments
 (0)