if e.Domain == host {
return true
}
- return !e.HostOnly && strings.HasSuffix(host, "."+e.Domain)
+ return !e.HostOnly && hasDotSuffix(host, e.Domain)
}
// pathMatch implements "path-match" according to RFC 6265 section 5.1.4.
return false
}
+// hasDotSuffix returns whether s ends in "."+suffix.
+func hasDotSuffix(s, suffix string) bool {
+ return len(s) > len(suffix) && s[len(s)-len(suffix)-1] == '.' && s[len(s)-len(suffix):] == suffix
+}
+
// byPathLength is a []entry sort.Interface that sorts according to RFC 6265
// section 5.4 point 2: by longest path and then by earliest creation time.
type byPathLength []entry
// See RFC 6265 section 5.3 #5.
if j.psList != nil {
- if ps := j.psList.PublicSuffix(domain); ps != "" && !strings.HasSuffix(domain, "."+ps) {
+ if ps := j.psList.PublicSuffix(domain); ps != "" && !hasDotSuffix(domain, ps) {
if host == domain {
// This is the one exception in which a cookie
// with a domain attribute is a host cookie.
// The domain must domain-match host: www.mycompany.com cannot
// set cookies for .ourcompetitors.com.
- if host != domain && !strings.HasSuffix(host, "."+domain) {
+ if host != domain && !hasDotSuffix(host, domain) {
return "", false, errIllegalDomain
}
return jar
}
+var hasDotSuffixTests = [...]struct {
+ s, suffix string
+}{
+ {"", ""},
+ {"", "."},
+ {"", "x"},
+ {".", ""},
+ {".", "."},
+ {".", ".."},
+ {".", "x"},
+ {".", "x."},
+ {".", ".x"},
+ {".", ".x."},
+ {"x", ""},
+ {"x", "."},
+ {"x", ".."},
+ {"x", "x"},
+ {"x", "x."},
+ {"x", ".x"},
+ {"x", ".x."},
+ {".x", ""},
+ {".x", "."},
+ {".x", ".."},
+ {".x", "x"},
+ {".x", "x."},
+ {".x", ".x"},
+ {".x", ".x."},
+ {"x.", ""},
+ {"x.", "."},
+ {"x.", ".."},
+ {"x.", "x"},
+ {"x.", "x."},
+ {"x.", ".x"},
+ {"x.", ".x."},
+ {"com", ""},
+ {"com", "m"},
+ {"com", "om"},
+ {"com", "com"},
+ {"com", ".com"},
+ {"com", "x.com"},
+ {"com", "xcom"},
+ {"com", "xorg"},
+ {"com", "org"},
+ {"com", "rg"},
+ {"foo.com", ""},
+ {"foo.com", "m"},
+ {"foo.com", "om"},
+ {"foo.com", "com"},
+ {"foo.com", ".com"},
+ {"foo.com", "o.com"},
+ {"foo.com", "oo.com"},
+ {"foo.com", "foo.com"},
+ {"foo.com", ".foo.com"},
+ {"foo.com", "x.foo.com"},
+ {"foo.com", "xfoo.com"},
+ {"foo.com", "xfoo.org"},
+ {"foo.com", "foo.org"},
+ {"foo.com", "oo.org"},
+ {"foo.com", "o.org"},
+ {"foo.com", ".org"},
+ {"foo.com", "org"},
+ {"foo.com", "rg"},
+}
+
+func TestHasDotSuffix(t *testing.T) {
+ for _, tc := range hasDotSuffixTests {
+ got := hasDotSuffix(tc.s, tc.suffix)
+ want := strings.HasSuffix(tc.s, "."+tc.suffix)
+ if got != want {
+ t.Errorf("s=%q, suffix=%q: got %v, want %v", tc.s, tc.suffix, got, want)
+ }
+ }
+}
+
var canonicalHostTests = map[string]string{
"www.example.com": "www.example.com",
"WWW.EXAMPLE.COM": "www.example.com",