publicsuffix: domain labels may not be empty

EffectiveTLDPlusOne hands it argument to PublicSuffix which produces
output for all its arguments, even for non-domain names like ".com.au"
and does not report an error.

This CL captures this type of malformed input to EffectiveTLDPlusOne
and returns an error if any label in the domain name is empty (or the
domain is fully qualified).
This is still not a proper input validation e.g. IP addresses can
still be fed into EffectiveTLDPlusOne without error.

Fixes golang/go#30652

Change-Id: I12b0945bc3c7e5d192a71c5488361a60a48454b1
Reviewed-on: https://go-review.googlesource.com/c/net/+/172537
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Nigel Tao <nigeltao@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/publicsuffix/list.go b/publicsuffix/list.go
index 8405ac1..200617e 100644
--- a/publicsuffix/list.go
+++ b/publicsuffix/list.go
@@ -165,6 +165,10 @@
 // EffectiveTLDPlusOne returns the effective top level domain plus one more
 // label. For example, the eTLD+1 for "foo.bar.golang.org" is "golang.org".
 func EffectiveTLDPlusOne(domain string) (string, error) {
+	if strings.HasPrefix(domain, ".") || strings.HasSuffix(domain, ".") || strings.Contains(domain, "..") {
+		return "", fmt.Errorf("publicsuffix: empty label in domain %q", domain)
+	}
+
 	suffix, _ := PublicSuffix(domain)
 	if len(domain) <= len(suffix) {
 		return "", fmt.Errorf("publicsuffix: cannot derive eTLD+1 for domain %q", domain)
diff --git a/publicsuffix/list_test.go b/publicsuffix/list_test.go
index 98f8442..090c431 100644
--- a/publicsuffix/list_test.go
+++ b/publicsuffix/list_test.go
@@ -489,6 +489,14 @@
 	{"www.xn--85x722f.xn--fiqs8s", "xn--85x722f.xn--fiqs8s"},
 	{"shishi.xn--fiqs8s", "shishi.xn--fiqs8s"},
 	{"xn--fiqs8s", ""},
+
+	// Invalid input
+	{".", ""},
+	{"de.", ""},
+	{".de", ""},
+	{".com.au", ""},
+	{"com.au.", ""},
+	{"com..au", ""},
 }
 
 func TestEffectiveTLDPlusOne(t *testing.T) {