GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — email.parser can insert extraneous spaces when parsing rfc2047 headers with policy.default · Issue #128110 · python/cpython

email.parser can insert extraneous spaces when parsing rfc2047 headers with policy.default  #128110

New issue
Copy link
New issue
Copy link
Closed
#130749
Closed
email.parser can insert extraneous spaces when parsing rfc2047 headers with policy.default #128110
#130749
Copy link
Labels
stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytopic-emailtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

Description

@medmunds
medmunds
opened on Dec 20, 2024
Issue body actions

Bug report

Bug description:

When using email.parser with the modern email.policy.default, the parser incorrectly inserts a space between adjacent rfc2047 encoded-words that are separated by folding whitespace. This can result in splitting words or names in unexpected places in the parsed headers.

Example:

Python 3.13.1 (main, Dec  3 2024, 17:59:52) [Clang 16.0.0 (clang-1600.0.26.4)] on darwin
>>> from email import message_from_bytes, policy
>>> from email.message import EmailMessage

>>> address = "Bérénice-Amélie Rosemonde Dûbois-Bénard <[email protected]>"
>>> message = EmailMessage()
>>> message["From"] = address
>>> message_bytes = message.as_bytes()

>>> default_parsed = message_from_bytes(message_bytes, policy=policy.default)
>>> default_parsed_from = default_parsed["From"].addresses[0]
>>> assert default_parsed_from == address
Traceback (most recent call last):
  File "<python-input-22>", line 1, in <module>
    assert default_parsed_from == address
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError

>>> print(default_parsed_from); print(address)
Bérénice-Amélie Rosemonde Dûbois-Béna rd <[email protected]>
Bérénice-Amélie Rosemonde Dûbois-Bénard <[email protected]>

>>> print(default_parsed["From"].addresses[0].display_name)
Bérénice-Amélie Rosemonde Dûbois-Béna rd

Notice the unexpected space in the parsed version. (I have more-problematic examples involving variations of the Scunthorpe problem, but they're not suitable for GitHub. This example uses Python's modern email API to generate the message, but the bug applies to parsing messages from any source.)

This seems to be caused by two consecutive rfc2047 encoded-words [edit: whether or not they cross a fold, see later comment]:

>>> print(message_bytes.decode())
From: =?utf-8?b?QsOpcsOpbmljZS1BbcOpbGllIFJvc2Vtb25kZSBEw7tib2lzLULDqW5h?=
 =?utf-8?q?rd?= <[email protected]>

RFC 2047 section 6.2 requires that space that separates adjacent encoded-words be ignored. (Specifically to allow splitting encoded-words at any character—behavior that the policy.default email.generator relies on.)

Note that the legacy compat32 parser did not have this problem. (The legacy parser requires separately calling legacy email.header.decode_header() to decode rfc2047.)

>>> from email.header import decode_header
>>> compat32_parsed = message_from_bytes(message_bytes, policy=policy.compat32)
>>> compat32_parsed_from = "".join(
...     segment if charset is None and isinstance(segment, str)
...     else segment.decode(charset or "ascii")
...     for segment, charset in decode_header(compat32_parsed["From"])
... )
>>> assert compat32_parsed_from == address  # (success)
>>> print("original:", address); print("compat32:", compat32_parsed_from); print(" default:", default_parsed_from)
original: Bérénice-Amélie Rosemonde Dûbois-Bénard <[email protected]>
compat32: Bérénice-Amélie Rosemonde Dûbois-Bénard <[email protected]>
 default: Bérénice-Amélie Rosemonde Dûbois-Béna rd <[email protected]>

CPython versions tested on:

3.12, 3.13

Operating systems tested on:

Linux, macOS

Linked PRs

  • gh-128110: Fix rfc2047 handling in email parser address headers #130749
  • [3.15] gh-128110: Fix rfc2047 whitespace handling in email parser address headers (GH-130749) #149787
  • [3.14] gh-128110: Fix rfc2047 whitespace handling in email parser address headers (GH-130749) #149788
  • [3.13] gh-128110: Fix rfc2047 whitespace handling in email parser address headers (GH-130749) #149789
Reacted by Nickson Yap

Activity

Next
  1. medmunds
    added
    type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
    on Dec 20, 2024
  2. skirpichev
    added
    stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory
    topic-email
    on Dec 20, 2024
  3. srinivasreddy commented on Dec 20, 2024

    @srinivasreddy
    srinivasreddy
    on Dec 20, 2024
    Contributor
    More actions

    @medmunds you are working on fixing this ? If not, I am working on it

  4. medmunds commented on Dec 20, 2024

    @medmunds
    medmunds
    on Dec 20, 2024
    ContributorAuthor
    More actions

    @srinivasreddy I already have a bunch of email-related PRs that have been stuck awaiting review for months, so I'm not working on new PRs until those move forward. If you have a fix for this issue, that's great!

  5. medmunds commented on Dec 22, 2024

    @medmunds
    medmunds
    on Dec 22, 2024
    ContributorAuthor
    More actions

    On further investigation, it seems parsing with policy.default fails to remove "any 'linear-white-space' that separates a pair of adjacent 'encoded-word's" whether or not folding is involved:

    >>> message_from_bytes(b"From: =??q?ab?= =??q?cd?= <foo@example>\n", policy=policy.default)["From"]
    'ab cd <foo@example>'
    # expected: 'abcd <foo@example>'
  6. medmunds
    changed the title [-]email.parser inserts extraneous spaces when parsing folded rfc2047 headers with policy.default [/-] [+]email.parser can insert extraneous spaces when parsing rfc2047 headers with policy.default [/+] on Dec 22, 2024
  7. srinivasreddy commented on Dec 23, 2024

    @srinivasreddy
    srinivasreddy
    on Dec 23, 2024
    Contributor
    More actions

    I started the work on it.

    Reacted by Mike Edmunds
  8. medmunds commented on Dec 23, 2024

    @medmunds
    medmunds
    on Dec 23, 2024
    ContributorAuthor
    More actions

    Also, it looks like the problem only affects address headers:

    >>> # Subject header is correct:
    >>> message_from_bytes(b"Subject: =??q?ab?= =??q?cd?=\n", policy=policy.default)["Subject"]
    'abcd'
    >>> # Address header has the bug:
    >>> message_from_bytes(b"To: =??q?ab?= =??q?cd?= <foo@example>\n", policy=policy.default)["To"]
    'ab cd <foo@example>'
  9. medmunds commented on Dec 24, 2024

    @medmunds
    medmunds
    on Dec 24, 2024
    ContributorAuthor
    More actions

    Until this gets fixed, here's a workaround that can repair an EmailMessage with misparsed headers. And a short check to see if you need the workaround.

  10. medmunds commented on Feb 27, 2025

    @medmunds
    medmunds
    on Feb 27, 2025
    ContributorAuthor
    More actions

    @srinivasreddy are you still working on this?

  11. srinivasreddy commented on Feb 28, 2025

    @srinivasreddy
    srinivasreddy
    on Feb 28, 2025
    Contributor
    More actions

    @medmunds apologies . I didn’t get enough time for this . This ticket is up for grabs .

  12. medmunds
    added 2 commits that reference this issue on Mar 1, 2025

    pythongh-128110: Fix rfc2047 handling in email parser address headers

    049c367

    pythongh-128110: Fix rfc2047 handling in email parser address headers

    ef61984
  13. jakajancar commented on May 27, 2025

    @jakajancar
    jakajancar
    on May 27, 2025
    More actions

    Also, it looks like the problem only affects address headers:

    Not sure if related or not, but Message-ID also has a whitespace problem:

    #134812

  14. 2 remaining items

  15. sarahboyce
    added 3 commits that reference this issue on Jul 16, 2025

    Refs #35581 -- Added workaround for Python bug in mail tests.

    8281746

    Refs #35581 -- Added workaround for Python bug in mail tests.

    17947b8

    Refs #35581 -- Added workaround for Python bug in mail tests.

    40d6eb2
  16. pull
    added a commit that references this issue on Jul 16, 2025

    Refs #35581 -- Added workaround for Python bug in mail tests.

    5214307
  17. ArneTR
    added a commit that references this issue on Jul 17, 2025

    Refs #35581 -- Added workaround for Python bug in mail tests.

    645c218
  18. medmunds
    added a commit that references this issue on Jul 21, 2025

    Refs #35581 -- Added workaround for Python bug in mail tests.

    2d367d8
  19. JulianMaurin
    added a commit that references this issue on Aug 2, 2025

    Refs #35581 -- Added workaround for Python bug in mail tests.

    4fc5aa5
  20. rcj0003
    added a commit that references this issue on Sep 11, 2025

    Refs #35581 -- Added workaround for Python bug in mail tests.

    886df6e
  21. multiflexi commented on Feb 26, 2026

    @multiflexi
    multiflexi
    on Feb 26, 2026
    More actions

    I think the issue affects Subject as well:
    [TLP:CLEAR] [Max CVSS 10.0] Cisco Catalyst SD-WAN opravuje aktivně zneužívanou zranitelnost
    gets encoded with add_header() as:
    b'Subject: [TLP:CLEAR] [Max CVSS 10.0] Cisco Catalyst SD-WAN opravuje \n =?utf-8?q?aktivn=C4=9B?= =?utf-8?q?zneu=C5=BE=C3=ADvanou?= zranitelnost\n\n'
    which gets decoded as aktivnězneužívanou instead of aktivně zneužívanou.

    When I change the string to aaaaaaaaaaa[TLP:CLEAR] [Max CVSS 10.0] Cisco Catalyst SD-WAN opravuje aktivně zneužívanou zranitelnost, the issue changes and it produces 2 spaces between opravuje and aktivně.

  22. medmunds commented on May 11, 2026

    @medmunds
    medmunds
    on May 11, 2026
    ContributorAuthor
    More actions

    I think the issue affects Subject as well:
    [TLP:CLEAR] [Max CVSS 10.0] Cisco Catalyst SD-WAN opravuje aktivně zneužívanou zranitelnost
    gets encoded with add_header() as:
    b'Subject: [TLP:CLEAR] [Max CVSS 10.0] Cisco Catalyst SD-WAN opravuje \n =?utf-8?q?aktivn=C4=9B?= =?utf-8?q?zneu=C5=BE=C3=ADvanou?= zranitelnost\n\n'
    which gets decoded as aktivnězneužívanou instead of aktivně zneužívanou.

    @multiflexi I can't reproduce that in Python 3.14.4 (or 3.15.0a8). The space between the two words seems to be correctly encoded as _ inside a single encoded-word:

    >>> from email import policy, message_from_bytes
    >>> from email.message import EmailMessage
    >>> msg = EmailMessage()
    >>> subject = "[TLP:CLEAR] [Max CVSS 10.0] Cisco Catalyst SD-WAN opravuje aktivně zneužívanou zranitelnost"
    >>> msg.add_header("Subject", subject)
    >>> print(msg.as_bytes().decode())
    Subject: [TLP:CLEAR] [Max CVSS 10.0] Cisco Catalyst SD-WAN opravuje
     =?utf-8?q?aktivn=C4=9B_zneu=C5=BE=C3=ADvanou?= zranitelnost
    >>> ### The space gets ^ encoded as '_'
    >>> parsed = message_from_bytes(msg.as_bytes(), policy=policy.default)
    >>> parsed["Subject"]
    '[TLP:CLEAR] [Max CVSS 10.0] Cisco Catalyst SD-WAN opravuje aktivně zneužívanou zranitelnost'
    >>> parsed["Subject"] == subject
    True

    If you're still seeing it, please open a new issue with the exact Python version you're using and sample code to reproduce the problem. If the subject you show gets encoded as ... =?utf-8?q?aktivn=C4=9B?= =?utf-8?q?zneu=C5=BE=C3=ADvanou?= ..., that's a bug in the email generator. (That encoded subject would correctly decode as ... aktivnězneužívanou ... because the space between the encoded-words should be ignored per rfc2047.)

  23. bitdancer
    added a commit that references this issue on May 11, 2026

    gh-128110: Fix rfc2047 whitespace handling in email parser address he…

    7a4c6df
  24. bitdancer
    closed this as completedin #130749on May 11, 2026
  25. bitdancer
    added 3 commits that reference this issue on May 13, 2026

    [3.15] gh-128110: Fix rfc2047 whitespace handling in email parser add…

    fb35004

    [3.14] gh-128110: Fix rfc2047 whitespace handling in email parser add…

    20175bb

    [3.13] gh-128110: Fix rfc2047 whitespace handling in email parser add…

    82db654
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytopic-emailtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.