Skip to content

Commit 8e763eb

Browse files
idna: *Profile.process to throw labelError if verifyDNSLength = true 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
1 parent f99f2cf commit 8e763eb

File tree

4 files changed

+38
-32
lines changed

4 files changed

+38
-32
lines changed

internal/export/idna/idna10.0.0.go

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -348,10 +348,10 @@ func (p *Profile) process(s string, toASCII bool) (string, error) {
348348
// TODO: allow for a quick check of the tables data.
349349
// It seems like we should only create this error on ToASCII, but the
350350
// UTS 46 conformance tests suggests we should always check this.
351-
if err == nil && p.verifyDNSLength && s == "" {
351+
if err == nil && p.verifyDNSLength && (s == "" || s[len(s)-1] == '.') {
352352
err = &labelError{s, "A4"}
353353
}
354-
labels := labelIter{orig: s, verifyDNSLength: p.verifyDNSLength}
354+
labels := labelIter{orig: s}
355355
for ; !labels.done(); labels.next() {
356356
label := labels.label()
357357
if label == "" {
@@ -413,12 +413,9 @@ func (p *Profile) process(s string, toASCII bool) (string, error) {
413413
}
414414
s = labels.result()
415415
if toASCII && p.verifyDNSLength && err == nil {
416-
// Compute the length of the domain name minus the root label and its dot.
416+
// Compute the length of the domain name.
417417
n := len(s)
418-
if n > 0 && s[n-1] == '.' {
419-
n--
420-
}
421-
if len(s) < 1 || n > 253 {
418+
if n < 1 || n > 253 {
422419
err = &labelError{s, "A4"}
423420
}
424421
}
@@ -538,12 +535,11 @@ func validateAndMap(p *Profile, s string) (vm string, bidi bool, err error) {
538535

539536
// A labelIter allows iterating over domain name labels.
540537
type labelIter struct {
541-
orig string
542-
slice []string
543-
curStart int
544-
curEnd int
545-
i int
546-
verifyDNSLength bool
538+
orig string
539+
slice []string
540+
curStart int
541+
curEnd int
542+
i int
547543
}
548544

549545
func (l *labelIter) reset() {
@@ -575,8 +571,7 @@ func (l *labelIter) label() string {
575571
return l.orig[l.curStart:l.curEnd]
576572
}
577573

578-
// next sets the value to the next label. It skips the last label if it is empty
579-
// and l.verifyDNSLength is false.
574+
// next sets the value to the next label. It skips the last label if it is empty.
580575
func (l *labelIter) next() {
581576
l.i++
582577
if l.slice != nil {
@@ -585,7 +580,7 @@ func (l *labelIter) next() {
585580
}
586581
} else {
587582
l.curStart = l.curEnd + 1
588-
if !l.verifyDNSLength && l.curStart == len(l.orig)-1 && l.orig[l.curStart] == '.' {
583+
if l.curStart == len(l.orig)-1 && l.orig[l.curStart] == '.' {
589584
l.curStart = len(l.orig)
590585
}
591586
}

internal/export/idna/idna10.0.0_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,12 @@ func TestLabelErrors(t *testing.T) {
6767
{lengthA, ".b", ".b", "A4"},
6868
{lengthA, "\u3002b", ".b", "A4"},
6969
{lengthA, "..b", "..b", "A4"},
70+
{lengthA, "b.", "b.", "A4"},
71+
{lengthA, "ƀ.", "xn--lha.", "A4"},
7072
{lengthA, "b..", "b..", "A4"},
7173
{lengthA, "ƀ..", "xn--lha..", "A4"},
74+
{lengthA, "b...", "b...", "A4"},
75+
{lengthA, "ƀ...", "xn--lha...", "A4"},
7276

7377
// Sharpened Bidi rules for Unicode 10.0.0. Apply for ALL labels in ANY
7478
// of the labels is RTL.
@@ -81,8 +85,12 @@ func TestLabelErrors(t *testing.T) {
8185
{resolve, ".b", ".b", ""},
8286
{resolve, "\u3002b", ".b", ""},
8387
{resolve, "..b", "..b", ""},
88+
{resolve, "b.", "b.", ""},
89+
{resolve, "ƀ.", "xn--lha.", ""},
8490
{resolve, "b..", "b..", ""},
8591
{resolve, "ƀ..", "xn--lha..", ""},
92+
{resolve, "b...", "b...", ""},
93+
{resolve, "ƀ...", "xn--lha...", ""},
8694
{resolve, "\xed", "", "P1"},
8795

8896
// Raw punycode

internal/export/idna/idna9.0.0.go

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -348,10 +348,10 @@ func (p *Profile) process(s string, toASCII bool) (string, error) {
348348
}
349349
// It seems like we should only create this error on ToASCII, but the
350350
// UTS 46 conformance tests suggests we should always check this.
351-
if err == nil && p.verifyDNSLength && s == "" {
351+
if err == nil && p.verifyDNSLength && (s == "" || s[len(s)-1] == '.') {
352352
err = &labelError{s, "A4"}
353353
}
354-
labels := labelIter{orig: s, verifyDNSLength: p.verifyDNSLength}
354+
labels := labelIter{orig: s}
355355
for ; !labels.done(); labels.next() {
356356
label := labels.label()
357357
if label == "" {
@@ -404,12 +404,9 @@ func (p *Profile) process(s string, toASCII bool) (string, error) {
404404
}
405405
s = labels.result()
406406
if toASCII && p.verifyDNSLength && err == nil {
407-
// Compute the length of the domain name minus the root label and its dot.
407+
// Compute the length of the domain name.
408408
n := len(s)
409-
if n > 0 && s[n-1] == '.' {
410-
n--
411-
}
412-
if len(s) < 1 || n > 253 {
409+
if n < 1 || n > 253 {
413410
err = &labelError{s, "A4"}
414411
}
415412
}
@@ -500,12 +497,11 @@ func validateAndMap(p *Profile, s string) (string, error) {
500497

501498
// A labelIter allows iterating over domain name labels.
502499
type labelIter struct {
503-
orig string
504-
slice []string
505-
curStart int
506-
curEnd int
507-
i int
508-
verifyDNSLength bool
500+
orig string
501+
slice []string
502+
curStart int
503+
curEnd int
504+
i int
509505
}
510506

511507
func (l *labelIter) reset() {
@@ -537,8 +533,7 @@ func (l *labelIter) label() string {
537533
return l.orig[l.curStart:l.curEnd]
538534
}
539535

540-
// next sets the value to the next label. It skips the last label if it is empty
541-
// and l.verifyDNSLength is false.
536+
// next sets the value to the next label. It skips the last label if it is empty.
542537
func (l *labelIter) next() {
543538
l.i++
544539
if l.slice != nil {
@@ -547,7 +542,7 @@ func (l *labelIter) next() {
547542
}
548543
} else {
549544
l.curStart = l.curEnd + 1
550-
if !l.verifyDNSLength && l.curStart == len(l.orig)-1 && l.orig[l.curStart] == '.' {
545+
if l.curStart == len(l.orig)-1 && l.orig[l.curStart] == '.' {
551546
l.curStart = len(l.orig)
552547
}
553548
}

internal/export/idna/idna9.0.0_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,15 +71,23 @@ func TestLabelErrors(t *testing.T) {
7171
{lengthA, ".b", "b", ""},
7272
{lengthA, "\u3002b", "b", ""},
7373
{lengthA, "..b", "b", ""},
74+
{lengthA, "b.", "b.", "A4"},
75+
{lengthA, "ƀ.", "xn--lha.", "A4"},
7476
{lengthA, "b..", "b..", "A4"},
7577
{lengthA, "ƀ..", "xn--lha..", "A4"},
78+
{lengthA, "b...", "b...", "A4"},
79+
{lengthA, "ƀ...", "xn--lha...", "A4"},
7680

7781
{resolve, "a..b", "a..b", ""},
7882
{resolve, ".b", "b", ""},
7983
{resolve, "\u3002b", "b", ""},
8084
{resolve, "..b", "b", ""},
85+
{resolve, "b.", "b.", ""},
86+
{resolve, "ƀ.", "xn--lha.", ""},
8187
{resolve, "b..", "b..", ""},
8288
{resolve, "ƀ..", "xn--lha..", ""},
89+
{resolve, "b...", "b...", ""},
90+
{resolve, "ƀ...", "xn--lha...", ""},
8391
{resolve, "\xed", "", "P1"},
8492

8593
// Raw punycode

0 commit comments

Comments
 (0)