Fix IDN: sanitize_email rejects valid Punycode domains
This commit is contained in:
@@ -20,6 +20,7 @@ If you are upgrading from v0.16.x, replace the binary (or run `docker pull`). If
|
|||||||
- Prometheus: event counters are exported with incorrect metric names.
|
- Prometheus: event counters are exported with incorrect metric names.
|
||||||
- Registry: Changing the type of an existing account from `user` to `group` panics.
|
- Registry: Changing the type of an existing account from `user` to `group` panics.
|
||||||
- Masked emails: Return `UnknownRecipient` only for disabled or expired masked emails.
|
- Masked emails: Return `UnknownRecipient` only for disabled or expired masked emails.
|
||||||
|
- IDN: `sanitize_email` rejects valid Punycode domains.
|
||||||
|
|
||||||
## [0.16.11] - 2026-06-25
|
## [0.16.11] - 2026-06-25
|
||||||
|
|
||||||
|
|||||||
@@ -285,10 +285,16 @@ pub fn sanitize_email(email: &str) -> Option<String> {
|
|||||||
|
|
||||||
for ch in chars {
|
for ch in chars {
|
||||||
match ch {
|
match ch {
|
||||||
'.' | '-' | '_' => {
|
'.' => {
|
||||||
if !last_ch.is_alphanumeric() {
|
if !last_ch.is_alphanumeric() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
result.push('.');
|
||||||
|
}
|
||||||
|
'-' | '_' => {
|
||||||
|
if last_ch == NIL_CHAR || last_ch == '.' {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
result.push(ch);
|
result.push(ch);
|
||||||
}
|
}
|
||||||
' ' | '\x09'..='\x0d' => continue,
|
' ' | '\x09'..='\x0d' => continue,
|
||||||
@@ -477,6 +483,18 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn a_label_email_domains_are_accepted_and_idempotent() {
|
||||||
|
assert_eq!(
|
||||||
|
sanitize_email("user@xn--fsqu00a.com").as_deref(),
|
||||||
|
Some("user@xn--fsqu00a.com")
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
sanitize_email("User@例子.com").as_deref(),
|
||||||
|
sanitize_email("user@xn--fsqu00a.com").as_deref()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn to_ascii_domain_borrows_ascii_owns_idn() {
|
fn to_ascii_domain_borrows_ascii_owns_idn() {
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
|
|||||||
Reference in New Issue
Block a user