diff --git a/Lib/email/_header_value_parser.py b/Lib/email/_header_value_parser.py index 91243378dc0441..90b7f82efd2093 100644 --- a/Lib/email/_header_value_parser.py +++ b/Lib/email/_header_value_parser.py @@ -3011,7 +3011,10 @@ def _fold_as_ew(to_encode, lines, maxlen, last_ew, ew_combine_allowed, charset, to_encode_word = to_encode_word[:-1] encoded_word = _ew.encode(to_encode_word, charset=encode_as) excess = len(encoded_word) - remaining_space - lines[-1] += encoded_word + # If encoding a single character pushes this line over the limit, + # give up on it and go to the next line. + if to_encode_word != "": + lines[-1] += encoded_word to_encode = to_encode[len(to_encode_word):] leading_whitespace = '' diff --git a/Lib/test/test_email/test__header_value_parser.py b/Lib/test/test_email/test__header_value_parser.py index 179e236ecdfd7f..ec61b45c54ae59 100644 --- a/Lib/test/test_email/test__header_value_parser.py +++ b/Lib/test/test_email/test__header_value_parser.py @@ -3084,6 +3084,14 @@ def test_ews_combined_before_wrap(self): "mich. And that's\n" " all I'm sayin.\n") + def test_unicode_near_end_of_line(self): + self._test(parser.get_unstructured("Mein Kaktus ist sehr attraktiv. Er " + "hat viele Stacheln und liebt " + "übriggebliebenes Eigelb."), + "Mein Kaktus ist sehr attraktiv. Er hat viele " + "Stacheln und liebt \n" + " =?utf-8?q?=C3=BCbriggebliebenes?= Eigelb.\n") + def test_unicode_after_unknown_not_combined(self): self._test(parser.get_unstructured("=?unknown-8bit?q?=A4?=\xa4"), "=?unknown-8bit?q?=A4?==?utf-8?q?=C2=A4?=\n") diff --git a/Misc/NEWS.d/next/Library/2025-06-29-15-25-56.gh-issue-136052.P1HgAD.rst b/Misc/NEWS.d/next/Library/2025-06-29-15-25-56.gh-issue-136052.P1HgAD.rst new file mode 100644 index 00000000000000..5b4a46143e3d94 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-06-29-15-25-56.gh-issue-136052.P1HgAD.rst @@ -0,0 +1 @@ +Do not create empty MIME encoded-words when preparing e-mail headers.