From 49267dbbd69f14bba406248c92c9bfaa7d64a192 Mon Sep 17 00:00:00 2001 From: Damien Neil Date: Wed, 1 Jul 2026 16:00:33 -0700 Subject: [PATCH] idna: reject all-ASCII xn-- labels on all Go versions Manually backported this specific change from x/text. For golang/go#78760 For golang/go#80298 Change-Id: I216ddcf5e85da2d6395bcc93873fe3ab6a6a6964 Reviewed-on: https://go-review.googlesource.com/c/net/+/798020 Reviewed-by: Nicholas Husin LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com Reviewed-by: Nicholas Husin Reviewed-by: David Chase --- idna/idna10.0.0.go | 15 ++++++++++++++- idna/idna_test.go | 14 ++++++++++++-- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/idna/idna10.0.0.go b/idna/idna10.0.0.go index 7b37178847..0743e9169f 100644 --- a/idna/idna10.0.0.go +++ b/idna/idna10.0.0.go @@ -362,7 +362,8 @@ func (p *Profile) process(s string, toASCII bool) (string, error) { continue } if strings.HasPrefix(label, acePrefix) { - u, err2 := decode(label[len(acePrefix):]) + enc := label[len(acePrefix):] + u, err2 := decode(enc) if err2 != nil { if err == nil { err = err2 @@ -370,6 +371,9 @@ func (p *Profile) process(s string, toASCII bool) (string, error) { // Spec says keep the old label. continue } + if err == nil && len(u) > 0 && isASCII(u) { + err = punyError(enc) + } isBidi = isBidi || bidirule.DirectionString(u) != bidi.LeftToRight labels.set(u) if err == nil && p.fromPuny != nil { @@ -424,6 +428,15 @@ func (p *Profile) process(s string, toASCII bool) (string, error) { return s, err } +func isASCII(s string) bool { + for _, c := range []byte(s) { + if c >= 0x80 { + return false + } + } + return true +} + func normalize(p *Profile, s string) (mapped string, isBidi bool, err error) { // TODO: consider first doing a quick check to see if any of these checks // need to be done. This will make it slower in the general case, but diff --git a/idna/idna_test.go b/idna/idna_test.go index 0b067cac97..2d58bff59d 100644 --- a/idna/idna_test.go +++ b/idna/idna_test.go @@ -104,5 +104,15 @@ func TestIDNASeparators(t *testing.T) { } } -// TODO(nigeltao): test errors, once we've specified when ToASCII and ToUnicode -// return errors. +func TestIDNAErrors(t *testing.T) { + for _, tc := range []string{ + "xn--example-.com", + } { + if got, err := ToASCII(tc); err == nil { + t.Errorf("ToASCII(%q) = %q, want error", tc, got) + } + if got, err := ToUnicode(tc); err == nil { + t.Errorf("ToUnicode(%q) = %q, want error", tc, got) + } + } +}