Skip to content

email: encoded headers lose their quoting when refolded #87720

Closed

Description

@EmilStyrke
BPO 43554
Nosy @warsaw, @bitdancer, @maxking
Files
  • test_folding_bug.py: unittest displaying the issue
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = None
    created_at = <Date 2021-03-19.09:45:02.487>
    labels = ['type-bug', 'library', '3.9']
    title = 'email: encoded headers lose their quoting when refolded'
    updated_at = <Date 2021-03-19.18:30:12.248>
    user = 'https://bugs.python.org/EmilStyrke'

    bugs.python.org fields:

    activity = <Date 2021-03-19.18:30:12.248>
    actor = 'shihai1991'
    assignee = 'none'
    closed = False
    closed_date = None
    closer = None
    components = ['Library (Lib)']
    creation = <Date 2021-03-19.09:45:02.487>
    creator = 'Emil.Styrke'
    dependencies = []
    files = ['49893']
    hgrepos = []
    issue_num = 43554
    keywords = []
    message_count = 1.0
    messages = ['389061']
    nosy_count = 4.0
    nosy_names = ['barry', 'r.david.murray', 'Emil.Styrke', 'maxking']
    pr_nums = []
    priority = 'normal'
    resolution = None
    stage = None
    status = 'open'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue43554'
    versions = ['Python 3.9']

    Linked PRs

    Activity

    1. EmilStyrke commented on Mar 19, 2021

      EmilStyrkemannequin
      MannequinAuthor

      When a header with an encoded (QP or Base64) display_name is refolded, it may lose (some of) its encoding. If it then contains illegal "atext" tokens, an invalid header will result.

      For example, From: =?utf-8?Q?a=2C=20123456789012345678901234567890123456?= <[email protected]> will become From: a, 123456789012345678901234567890123456 <[email protected]> This contains a comma character which needs to be quoted: correct rendering would be From: "a, 123456789012345678901234567890123456" <[email protected]>. Note that this example isn't even folded to multiple lines, since the decoded text is short enough to fit in one line.

      This can be triggered by BytesParser(policy=policy.default).parsebytes("From: =?utf-8?Q?a=2C=20123456789012345678901234567890123456?= <[email protected]>").as_bytes(), but the offending code seems to be in or below email.policy.EmailPolicy.fold. See attached file for examples with and without folding.

    2. added
      stdlibStandard Library Python modules in the Lib/ directory
      type-bugAn unexpected behavior, bug, or error
      on Mar 19, 2021
    3. transferred this issue fromon Apr 10, 2022
    4. brychcy commented on May 12, 2025

      @brychcy
    5. medmunds commented on May 26, 2025

      @medmunds
      Contributor

      rfc2047 RFC-2047 encoded-word

    6. nessita commented on Oct 8, 2026

      @nessita
      Contributor

      Ping! This still reproduces on 3.14.8 and 3.15.0rc3. An encoded-word display name that decodes to ASCII containing specials is refolded without quoting:

      $ python3.15
      Python 3.15.0rc3 (main, Oct  3 2026, 05:15:06) [GCC 13.3.0] on linux
      >>> import email.message, email.policy
      ... m = email.message.EmailMessage(policy=email.policy.default)
      ... m["To"] = "=?utf-8?q?x=2C_y=40example=2Ecom?= <[email protected]>"
      ... print(m.as_bytes())
      ...
      b'To: x, [email protected] <[email protected]>\n\n'
      $ python3.14
      Python 3.14.8 (main, Oct  1 2026, 15:42:08) [GCC 13.3.0] on linux
      >>> import email.message, email.policy
      ... m = email.message.EmailMessage(policy=email.policy.default)
      ... m["To"] = "=?utf-8?q?x=2C_y=40example=2Ecom?= <[email protected]>"
      ... print(m.as_bytes())
      ...
      b'To: x, [email protected] <[email protected]>\n\n'

      The header parses as a single mailbox but serializes as one that re-parses differently. This behavior has also been (incorrectly) reported to the Django security team; the root cause is here, so fixing it upstream would address those reports at the source.

      PR #134271 fixes this and has been approved by @medmunds, who maintains much of Django's email handling and is familiar with this area of the email package. Currently it is awaiting core review but marked stale, I can confirm it does solve the reported issue though.

    7. bitdancer commented on Oct 8, 2026

      @bitdancer
      Member

      Huh. I thought I merged that a while ago. Oops.

      I've updated the PR. Can you give me a quick once over on it to make sue I didn't make any stupid typos, and I'll merge it?

    8. added 2 commits that reference this issue on Oct 9, 2026
    9. medmunds commented on Oct 9, 2026

      @medmunds
      Contributor

      Closed by #134271.

    10. added a commit that references this issue on Oct 9, 2026
    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

      3.9 (EOL)end of lifestdlibStandard Library Python modules in the Lib/ directorytopic-emailtype-bugAn unexpected behavior, bug, or error

      Projects

      No projects

        Milestone

        No milestone

        Relationships

        None yet

        Development

        No branches or pull requests

        Issue actions