X Tutup
Skip to content

gh-145552: smtplib: quoteaddr() returns malformed address for input '<'#145553

Open
stefanzetzsche wants to merge 9 commits intopython:mainfrom
stefanzetzsche:fix/smtplib_quoteaddr_malformed
Open

gh-145552: smtplib: quoteaddr() returns malformed address for input '<'#145553
stefanzetzsche wants to merge 9 commits intopython:mainfrom
stefanzetzsche:fix/smtplib_quoteaddr_malformed

Conversation

@stefanzetzsche
Copy link

@stefanzetzsche stefanzetzsche commented Mar 5, 2026

Problem

quoteaddr() formats addresses for SMTP MAIL FROM: and RCPT TO: commands, which require angle-bracket format (<addr>). It first tries email.utils.parseaddr(); when that fails (for inputs like '<', '< ', '@'), a fallback path checks if the input starts with < and returns it verbatim — without verifying it also ends with >.

The startswith('<') check was introduced in 4c14bba as part of #51733. Before that commit, unparseable input was unconditionally wrapped in <>.

Reproducer

from smtplib import quoteaddr
print(repr(quoteaddr('<')))   # '<' — missing closing >

Why not unconditional wrapping?

Simply removing the startswith('<') branch and always wrapping with "<%s>" would break the null sender <>, which is a valid SMTP construct (RFC 5321 bounce path). parseaddr('<>') returns ('', '') — a parse failure — so unconditional wrapping would produce <<>>, which is malformed. The startswith('<') check exists specifically to preserve already-bracketed input that parseaddr can't handle.

Fix

Keep the startswith('<') check but add an endswith('>') guard. Already-bracketed input (like <>) passes through; half-open input (like <) falls through to unconditional wrapping:

if addrstring.strip().startswith('<'):
    if addrstring.strip().endswith('>'):
        return addrstring
return "<%s>" % addrstring

stefanzetzsche and others added 2 commits March 5, 2026 15:03
Input starting with '<' but missing closing '>' was returned verbatim.
Ensure the result always ends with '>'.
Add testQuoteAddr for basic quoteaddr behavior and
testQuoteAddrMalformedAngleBracket for inputs starting with '<'
but missing closing '>'. The latter fails without the fix.
@bedevere-app
Copy link

bedevere-app bot commented Mar 5, 2026

Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply the skip news label instead.

@python-cla-bot
Copy link

python-cla-bot bot commented Mar 5, 2026

All commit authors signed the Contributor License Agreement.

CLA signed

@stefanzetzsche stefanzetzsche marked this pull request as ready for review March 5, 2026 15:20
@stefanzetzsche stefanzetzsche requested a review from a team as a code owner March 5, 2026 15:20
@stefanzetzsche
Copy link
Author

@bitdancer

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

X Tutup