Skip to content

Quote the local part after NFC normalization in validate_email - #192

Open
Keerthana-64 wants to merge 1 commit into
JoshData:mainfrom
Keerthana-64:nfc-quoted-local-part
Open

Keerthana-64 wants to merge 1 commit into
JoshData:mainfrom
Keerthana-64:nfc-quoted-local-part

Conversation

@Keerthana-64

Copy link
Copy Markdown
Contributor

validate_email re-validates the local part after NFC normalization (the 2.2.0 fix for #142, where U+037E greek question mark becomes a semicolon), but it normalizes ret.local_part, which has already had unnecessary quotes dropped, and re-validates it with quoted_local_part taken from the input. with allow_quoted_local=True, "a\u037eb"@example.com passes the first check as a plain internationalized dot-atom, loses its quotes, becomes a;b under NFC, is accepted by the second check under quoted-string rules, and comes back as normalized a;b@example.com, which validate_email itself rejects. that bare semicolon is the #142 problem: Python's EmailMessage reads a To header of x;victim@example.com as x, <>, and getaddresses(strict=False) splits it into x, an empty entry and victim@example.com, while "x;victim"@example.com stays one address. normalizing unescaped_local_part and taking local_part from the second validate_email_local_part call quotes the result according to its normalized form; ascii_local_part and smtputf8 still come from the original, as discussed in #185. across about 95,000 random quoted and unquoted local parts under four option sets, 3,698 of 140,427 valid results on main had a normalized form that failed validation or changed when validated again, and none do with this change. the only other differences are that a quoted local part which becomes a plain dot-atom only after normalization (< or > plus U+0338) now drops its quotes like other unnecessarily quoted ones, and one that also contains a unicode space is now rejected, since its normalized form already was. the new test case fails on main and passes here; flake8 and the suite pass on 3.10 to 3.15, mypy on 3.10 to 3.14.

validate_email normalized ret.local_part, which has already had
unnecessary quotes removed, and re-validated it with the quoted flag
from the input. with allow_quoted_local=True, "a\u037eb"@example.com
therefore came back as a;b@example.com without quotes. normalize the
unescaped local part instead and take the quoting from the second
validation.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant