Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(api): keep leading dots after the beginning * is removed #97

Merged
merged 1 commit into from
Oct 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 17 additions & 9 deletions internal/api/domain.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,27 @@ import (
//nolint:gochecknoglobals
// profile does C2 in UTS#46 with all checks on + removing leading dots.
// This is the main conversion profile in use.
var profile = idna.New(
idna.MapForLookup(),
idna.BidiRule(),
// idna.Transitional(false), // https://go-review.googlesource.com/c/text/+/317729/
idna.RemoveLeadingDots(true),
var (
profileDroppingLeadingDots = idna.New(
idna.MapForLookup(),
idna.BidiRule(),
// idna.Transitional(false), // https://go-review.googlesource.com/c/text/+/317729/
idna.RemoveLeadingDots(true),
)
profileKeepingLeadingDots = idna.New(
idna.MapForLookup(),
idna.BidiRule(),
// idna.Transitional(false), // https://go-review.googlesource.com/c/text/+/317729/
idna.RemoveLeadingDots(false),
)
)

// safelyToUnicode takes an ASCII form and returns the Unicode form
// when the round trip gives the same ASCII form back without errors.
// Otherwise, the input ASCII form is returned.
func safelyToUnicode(ascii string) (string, bool) {
unicode, errToA := profile.ToUnicode(ascii)
roundTrip, errToU := profile.ToASCII(unicode)
unicode, errToA := profileKeepingLeadingDots.ToUnicode(ascii)
roundTrip, errToU := profileKeepingLeadingDots.ToASCII(unicode)
if errToA != nil || errToU != nil || roundTrip != ascii {
return ascii, false
}
Expand All @@ -35,7 +43,7 @@ func safelyToUnicode(ascii string) (string, bool) {
// gives back the same ASCII form without errors. Otherwise,
// the ASCII form (possibly using Punycode) is stored to avoid ambiguity.
func NewDomain(domain string) (Domain, error) {
normalized, err := profile.ToASCII(domain)
normalized, err := profileDroppingLeadingDots.ToASCII(domain)

// Remove the final dot for consistency
normalized = strings.TrimRight(normalized, ".")
Expand All @@ -45,7 +53,7 @@ func NewDomain(domain string) (Domain, error) {
return Wildcard(""), nil
case strings.HasPrefix(normalized, "*."):
// redo the normalization after removing the offending "*"
normalized, err := profile.ToASCII(strings.TrimPrefix(normalized, "*."))
normalized, err := profileKeepingLeadingDots.ToASCII(strings.TrimPrefix(normalized, "*."))
return Wildcard(normalized), err
default:
return FQDN(normalized), err
Expand Down
2 changes: 1 addition & 1 deletion internal/api/domain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ func TestNewDomain(t *testing.T) {
{"..。..a.com", f("a.com"), true, ""},
{"*.xn--a.xn--a.xn--a.com", w("xn--a.xn--a.xn--a.com"), false, `idna: invalid label "\u0080"`},
{"*.a.com...。", w("a.com"), true, ""},
{"*...。..a.com", w("a.com"), true, ""},
{"*...。..a.com", w(".....a.com"), true, ""},
{"*......", w(""), true, ""},
{"*。。。。。。", w(""), true, ""},
} {
Expand Down