diff --git a/internal/export/idna/idna10.0.0.go b/internal/export/idna/idna10.0.0.go index 0e7571d1..5cc75e68 100644 --- a/internal/export/idna/idna10.0.0.go +++ b/internal/export/idna/idna10.0.0.go @@ -351,7 +351,7 @@ func (p *Profile) process(s string, toASCII bool) (string, error) { if err == nil && p.verifyDNSLength && s == "" { err = &labelError{s, "A4"} } - labels := labelIter{orig: s} + labels := labelIter{orig: s, verifyDNSLength: p.verifyDNSLength} for ; !labels.done(); labels.next() { label := labels.label() if label == "" { @@ -538,11 +538,12 @@ 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 + orig string + slice []string + curStart int + curEnd int + i int + verifyDNSLength bool } func (l *labelIter) reset() { @@ -574,7 +575,8 @@ 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. +// next sets the value to the next label. It skips the last label if it is empty +// and l.verifyDNSLength is false. func (l *labelIter) next() { l.i++ if l.slice != nil { @@ -583,7 +585,7 @@ func (l *labelIter) next() { } } else { l.curStart = l.curEnd + 1 - if l.curStart == len(l.orig)-1 && l.orig[l.curStart] == '.' { + if !l.verifyDNSLength && l.curStart == len(l.orig)-1 && l.orig[l.curStart] == '.' { l.curStart = len(l.orig) } } diff --git a/internal/export/idna/idna10.0.0_test.go b/internal/export/idna/idna10.0.0_test.go index c3365bc6..657f59f6 100644 --- a/internal/export/idna/idna10.0.0_test.go +++ b/internal/export/idna/idna10.0.0_test.go @@ -67,7 +67,8 @@ func TestLabelErrors(t *testing.T) { {lengthA, ".b", ".b", "A4"}, {lengthA, "\u3002b", ".b", "A4"}, {lengthA, "..b", "..b", "A4"}, - {lengthA, "b..", "b..", ""}, + {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. @@ -81,6 +82,7 @@ func TestLabelErrors(t *testing.T) { {resolve, "\u3002b", ".b", ""}, {resolve, "..b", "..b", ""}, {resolve, "b..", "b..", ""}, + {resolve, "ƀ..", "xn--lha..", ""}, {resolve, "\xed", "", "P1"}, // Raw punycode diff --git a/internal/export/idna/idna9.0.0.go b/internal/export/idna/idna9.0.0.go index f217b1a4..698471d7 100644 --- a/internal/export/idna/idna9.0.0.go +++ b/internal/export/idna/idna9.0.0.go @@ -351,7 +351,7 @@ func (p *Profile) process(s string, toASCII bool) (string, error) { if err == nil && p.verifyDNSLength && s == "" { err = &labelError{s, "A4"} } - labels := labelIter{orig: s} + labels := labelIter{orig: s, verifyDNSLength: p.verifyDNSLength} for ; !labels.done(); labels.next() { label := labels.label() if label == "" { @@ -500,11 +500,12 @@ 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 + orig string + slice []string + curStart int + curEnd int + i int + verifyDNSLength bool } func (l *labelIter) reset() { @@ -536,7 +537,8 @@ 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. +// next sets the value to the next label. It skips the last label if it is empty +// and l.verifyDNSLength is false. func (l *labelIter) next() { l.i++ if l.slice != nil { @@ -545,7 +547,7 @@ func (l *labelIter) next() { } } else { l.curStart = l.curEnd + 1 - if l.curStart == len(l.orig)-1 && l.orig[l.curStart] == '.' { + if !l.verifyDNSLength && l.curStart == len(l.orig)-1 && l.orig[l.curStart] == '.' { l.curStart = len(l.orig) } } diff --git a/internal/export/idna/idna9.0.0_test.go b/internal/export/idna/idna9.0.0_test.go index 91a1e90d..26f36225 100644 --- a/internal/export/idna/idna9.0.0_test.go +++ b/internal/export/idna/idna9.0.0_test.go @@ -71,13 +71,15 @@ func TestLabelErrors(t *testing.T) { {lengthA, ".b", "b", ""}, {lengthA, "\u3002b", "b", ""}, {lengthA, "..b", "b", ""}, - {lengthA, "b..", "b..", ""}, + {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, "\xed", "", "P1"}, // Raw punycode