Skip to content

Commit

Permalink
idna: *Profile.process to throw labelError if verifyDNSLength = true …
Browse files Browse the repository at this point in the history
…and s ends with trailing dot.

From UTS46, no trailing dots are allowed when ToASCII is called with verifyDNSLength = true. This negates the need for an additional l.verifyDNSLength flag in the previous commit.

See https://www.unicode.org/L2/L2021/21170-utc169-properties-recs.pdf under section F2

Fixes golang/go#47182
  • Loading branch information
elliotwutingfeng committed Jun 22, 2023
1 parent f99f2cf commit 8e763eb
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 32 deletions.
27 changes: 11 additions & 16 deletions internal/export/idna/idna10.0.0.go
Original file line number Diff line number Diff line change
Expand Up @@ -348,10 +348,10 @@ func (p *Profile) process(s string, toASCII bool) (string, error) {
// TODO: allow for a quick check of the tables data.
// It seems like we should only create this error on ToASCII, but the
// UTS 46 conformance tests suggests we should always check this.
if err == nil && p.verifyDNSLength && s == "" {
if err == nil && p.verifyDNSLength && (s == "" || s[len(s)-1] == '.') {
err = &labelError{s, "A4"}
}
labels := labelIter{orig: s, verifyDNSLength: p.verifyDNSLength}
labels := labelIter{orig: s}
for ; !labels.done(); labels.next() {
label := labels.label()
if label == "" {
Expand Down Expand Up @@ -413,12 +413,9 @@ func (p *Profile) process(s string, toASCII bool) (string, error) {
}
s = labels.result()
if toASCII && p.verifyDNSLength && err == nil {
// Compute the length of the domain name minus the root label and its dot.
// Compute the length of the domain name.
n := len(s)
if n > 0 && s[n-1] == '.' {
n--
}
if len(s) < 1 || n > 253 {
if n < 1 || n > 253 {
err = &labelError{s, "A4"}
}
}
Expand Down Expand Up @@ -538,12 +535,11 @@ func validateAndMap(p *Profile, s string) (vm string, bidi bool, err error) {

// A labelIter allows iterating over domain name labels.
type labelIter struct {
orig string
slice []string
curStart int
curEnd int
i int
verifyDNSLength bool
orig string
slice []string
curStart int
curEnd int
i int
}

func (l *labelIter) reset() {
Expand Down Expand Up @@ -575,8 +571,7 @@ func (l *labelIter) label() string {
return l.orig[l.curStart:l.curEnd]
}

// next sets the value to the next label. It skips the last label if it is empty
// and l.verifyDNSLength is false.
// next sets the value to the next label. It skips the last label if it is empty.
func (l *labelIter) next() {
l.i++
if l.slice != nil {
Expand All @@ -585,7 +580,7 @@ func (l *labelIter) next() {
}
} else {
l.curStart = l.curEnd + 1
if !l.verifyDNSLength && l.curStart == len(l.orig)-1 && l.orig[l.curStart] == '.' {
if l.curStart == len(l.orig)-1 && l.orig[l.curStart] == '.' {
l.curStart = len(l.orig)
}
}
Expand Down
8 changes: 8 additions & 0 deletions internal/export/idna/idna10.0.0_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,12 @@ func TestLabelErrors(t *testing.T) {
{lengthA, ".b", ".b", "A4"},
{lengthA, "\u3002b", ".b", "A4"},
{lengthA, "..b", "..b", "A4"},
{lengthA, "b.", "b.", "A4"},
{lengthA, "ƀ.", "xn--lha.", "A4"},
{lengthA, "b..", "b..", "A4"},
{lengthA, "ƀ..", "xn--lha..", "A4"},
{lengthA, "b...", "b...", "A4"},
{lengthA, "ƀ...", "xn--lha...", "A4"},

// Sharpened Bidi rules for Unicode 10.0.0. Apply for ALL labels in ANY
// of the labels is RTL.
Expand All @@ -81,8 +85,12 @@ func TestLabelErrors(t *testing.T) {
{resolve, ".b", ".b", ""},
{resolve, "\u3002b", ".b", ""},
{resolve, "..b", "..b", ""},
{resolve, "b.", "b.", ""},
{resolve, "ƀ.", "xn--lha.", ""},
{resolve, "b..", "b..", ""},
{resolve, "ƀ..", "xn--lha..", ""},
{resolve, "b...", "b...", ""},
{resolve, "ƀ...", "xn--lha...", ""},
{resolve, "\xed", "", "P1"},

// Raw punycode
Expand Down
27 changes: 11 additions & 16 deletions internal/export/idna/idna9.0.0.go
Original file line number Diff line number Diff line change
Expand Up @@ -348,10 +348,10 @@ func (p *Profile) process(s string, toASCII bool) (string, error) {
}
// It seems like we should only create this error on ToASCII, but the
// UTS 46 conformance tests suggests we should always check this.
if err == nil && p.verifyDNSLength && s == "" {
if err == nil && p.verifyDNSLength && (s == "" || s[len(s)-1] == '.') {
err = &labelError{s, "A4"}
}
labels := labelIter{orig: s, verifyDNSLength: p.verifyDNSLength}
labels := labelIter{orig: s}
for ; !labels.done(); labels.next() {
label := labels.label()
if label == "" {
Expand Down Expand Up @@ -404,12 +404,9 @@ func (p *Profile) process(s string, toASCII bool) (string, error) {
}
s = labels.result()
if toASCII && p.verifyDNSLength && err == nil {
// Compute the length of the domain name minus the root label and its dot.
// Compute the length of the domain name.
n := len(s)
if n > 0 && s[n-1] == '.' {
n--
}
if len(s) < 1 || n > 253 {
if n < 1 || n > 253 {
err = &labelError{s, "A4"}
}
}
Expand Down Expand Up @@ -500,12 +497,11 @@ func validateAndMap(p *Profile, s string) (string, error) {

// A labelIter allows iterating over domain name labels.
type labelIter struct {
orig string
slice []string
curStart int
curEnd int
i int
verifyDNSLength bool
orig string
slice []string
curStart int
curEnd int
i int
}

func (l *labelIter) reset() {
Expand Down Expand Up @@ -537,8 +533,7 @@ func (l *labelIter) label() string {
return l.orig[l.curStart:l.curEnd]
}

// next sets the value to the next label. It skips the last label if it is empty
// and l.verifyDNSLength is false.
// next sets the value to the next label. It skips the last label if it is empty.
func (l *labelIter) next() {
l.i++
if l.slice != nil {
Expand All @@ -547,7 +542,7 @@ func (l *labelIter) next() {
}
} else {
l.curStart = l.curEnd + 1
if !l.verifyDNSLength && l.curStart == len(l.orig)-1 && l.orig[l.curStart] == '.' {
if l.curStart == len(l.orig)-1 && l.orig[l.curStart] == '.' {
l.curStart = len(l.orig)
}
}
Expand Down
8 changes: 8 additions & 0 deletions internal/export/idna/idna9.0.0_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,23 @@ func TestLabelErrors(t *testing.T) {
{lengthA, ".b", "b", ""},
{lengthA, "\u3002b", "b", ""},
{lengthA, "..b", "b", ""},
{lengthA, "b.", "b.", "A4"},
{lengthA, "ƀ.", "xn--lha.", "A4"},
{lengthA, "b..", "b..", "A4"},
{lengthA, "ƀ..", "xn--lha..", "A4"},
{lengthA, "b...", "b...", "A4"},
{lengthA, "ƀ...", "xn--lha...", "A4"},

{resolve, "a..b", "a..b", ""},
{resolve, ".b", "b", ""},
{resolve, "\u3002b", "b", ""},
{resolve, "..b", "b", ""},
{resolve, "b.", "b.", ""},
{resolve, "ƀ.", "xn--lha.", ""},
{resolve, "b..", "b..", ""},
{resolve, "ƀ..", "xn--lha..", ""},
{resolve, "b...", "b...", ""},
{resolve, "ƀ...", "xn--lha...", ""},
{resolve, "\xed", "", "P1"},

// Raw punycode
Expand Down

0 comments on commit 8e763eb

Please sign in to comment.