Master
fmt.Println(emailRegex.MatchString(`"\"@example.com`))
Produces true, it should produce false.
The fault is a missing \\\\ to match a backspace in the subexpression covering quoted-pair, as a result although the quoted-string should require \ and " to be quoted, both are accepted even without escaping.
@puellanivis thanks for reporting, would you be able to make a PR to fix :)
Working through what it would take to fix this regular expression, I stumbled upon something that there is an even bigger problem with this regexp that everyone is passing around: it improperly includes folding-white-space (FWS).
This means even if this bug is corrected, this code would still accept the email address (quote encoded): "\"\r\n user\"@example.org" even though the RFC specifically notes that the CRLF in the FWS is “invisible” and thus not semantically part of the email addres, thus using that byte sequence as an address would actually canonically be " user"@example.org.
The remaining interesting point is that there is no way to legally encode a CR or LF into an email address at all. The escaping backslash is considered invisible, and as such literally escapes the following byte sequence, thus (quote-encoded) "\"\\r\"@example.org" as an email address is canonically equivalent to "r"@example.org due to how escaping workings. And while "\"\\\t\"@example.org" demonstrates how to properly escape a TAB, the quote-pair definition does not allow escaping of either CR or LF.
Basically, everyone inherited a pretty bad email regexp, and while it’s had tweaks here and there, it is far more complex than it needs to be, in part because it is attempting to match far more than it actually should.
I could propose a better alternative, but it will intentionally not be compatible with what this has been matching before.
@puellanivis I’m ok with a fix that might not be compatible as it seems like a bug.
It doesn’t even have to be a regex.
Looking forward to anything you can come up with :)
@puellanivis any follow-up proposed solution here?
Well, I had https://github.com/puellanivis/pedantic-regexps/blob/master/email.go that I wrote out awhile ago, but it’s not all kind of collected into one single expression. I had to build it up by parts, because it was otherwise just too unwieldy to even reason about. But I imagine anyone could copy paste the regexp out of the TestEmail log, but it’s also 4170 bytes _all on its own_. :cold_sweat:
(A lot of that might just be from a large set of disjoint unicode character matches, though)
Most helpful comment
Working through what it would take to fix this regular expression, I stumbled upon something that there is an even bigger problem with this regexp that everyone is passing around: it improperly includes folding-white-space (FWS).
This means even if this bug is corrected, this code would still accept the email address (quote encoded):
"\"\r\n user\"@example.org"even though the RFC specifically notes that the CRLF in the FWS is “invisible” and thus not semantically part of the email addres, thus using that byte sequence as an address would actually canonically be" user"@example.org.The remaining interesting point is that there is no way to legally encode a CR or LF into an email address at all. The escaping backslash is considered invisible, and as such literally escapes the following byte sequence, thus (quote-encoded)
"\"\\r\"@example.org"as an email address is canonically equivalent to"r"@example.orgdue to how escaping workings. And while"\"\\\t\"@example.org"demonstrates how to properly escape a TAB, thequote-pairdefinition does not allow escaping of either CR or LF.Basically, everyone inherited a pretty bad email regexp, and while it’s had tweaks here and there, it is far more complex than it needs to be, in part because it is attempting to match far more than it actually should.
I could propose a better alternative, but it will intentionally not be compatible with what this has been matching before.