email.go validates with the well-known ~450-character RFC 5322 regexp from a StackOverflow answer. It's effectively unauditable, and it diverges from the RFC in both directions (rejects valid quoted local parts, accepts some odd domains).
net/mail.ParseAddress is the standard library's address parser and is the better tool for "is this a syntactically valid address".
The Name/Address checks reject display names (Alice <a@b.com>), bare angle brackets, trailing content, and address lists — so only a plain a@b.com passes.
Behaviour change
ParseAddress does not require the domain to contain a dot, so alice@localhost now validates. If a public-looking domain is required, that should be a separate, explicit check (a Match on the domain, or an MX lookup) rather than baked into Email.
The PR also rewrites FuzzEmail, which currently asserts that every input is invalid (it only passes because the seed corpus is empty) — now it checks that Email never returns an unexpected error type, never panics, and gives a stable verdict. Ran clean for 15s of fuzzing locally.
`email.go` validates with the well-known ~450-character RFC 5322 regexp from a StackOverflow answer. It's effectively unauditable, and it diverges from the RFC in both directions (rejects valid quoted local parts, accepts some odd domains).
`net/mail.ParseAddress` is the standard library's address parser and is the better tool for "is this a syntactically valid address".
**PR #8** swaps to it:
```go
addr, err := mail.ParseAddress(value)
if err != nil || addr.Name != "" || addr.Address != value {
return ErrInvalidEmail
}
```
The `Name`/`Address` checks reject display names (`Alice <a@b.com>`), bare angle brackets, trailing content, and address lists — so only a plain `a@b.com` passes.
### Behaviour change
`ParseAddress` does **not** require the domain to contain a dot, so `alice@localhost` now validates. If a public-looking domain is required, that should be a separate, explicit check (a `Match` on the domain, or an MX lookup) rather than baked into `Email`.
The PR also rewrites `FuzzEmail`, which currently asserts that *every* input is invalid (it only passes because the seed corpus is empty) — now it checks that `Email` never returns an unexpected error type, never panics, and gives a stable verdict. Ran clean for 15s of fuzzing locally.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
email.govalidates with the well-known ~450-character RFC 5322 regexp from a StackOverflow answer. It's effectively unauditable, and it diverges from the RFC in both directions (rejects valid quoted local parts, accepts some odd domains).net/mail.ParseAddressis the standard library's address parser and is the better tool for "is this a syntactically valid address".PR #8 swaps to it:
The
Name/Addresschecks reject display names (Alice <a@b.com>), bare angle brackets, trailing content, and address lists — so only a plaina@b.compasses.Behaviour change
ParseAddressdoes not require the domain to contain a dot, soalice@localhostnow validates. If a public-looking domain is required, that should be a separate, explicit check (aMatchon the domain, or an MX lookup) rather than baked intoEmail.The PR also rewrites
FuzzEmail, which currently asserts that every input is invalid (it only passes because the seed corpus is empty) — now it checks thatEmailnever returns an unexpected error type, never panics, and gives a stable verdict. Ran clean for 15s of fuzzing locally.