]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.13] gh-142006: Fix HeaderWriteError in email.policy.default caused by extra newlin...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Sat, 6 Dec 2025 21:40:07 +0000 (22:40 +0100)
committerGitHub <noreply@github.com>
Sat, 6 Dec 2025 21:40:07 +0000 (16:40 -0500)
gh-142006: Fix HeaderWriteError in email.policy.default caused by extra newline (GH-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.
(cherry picked from commit 07eff899d8a8ee4c4b1be7cb223fe25687f6216c)

Co-authored-by: Paresh Joshi <rahulj9223@gmail.com>
Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
Lib/email/_header_value_parser.py
Lib/test/test_email/test__header_value_parser.py
Misc/NEWS.d/next/Library/2025-11-27-10-49-13.gh-issue-142006.nzJDG5.rst [new file with mode: 0644]

index 91243378dc04416622bbd0ade23effea6c90f274..41401f8f8d54da2d162812d877c2a9aa453680f8 100644 (file)
@@ -2788,6 +2788,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):
index 64bc3677e87db0fa8044240a8c934e83bc70664c..561ded77334fc90babdeee1e00f8b9bf181eed2a 100644 (file)
@@ -3255,5 +3255,15 @@ class TestFolding(TestEmailBase):
             " 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 (file)
index 0000000..4964389
--- /dev/null
@@ -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.