return false
}
+ if mode == encodeHost {
+ // §3.2.2 Host allows
+ // sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
+ // as part of reg-name.
+ // We add : because we include :port as part of host.
+ // We add [ ] because we include [ipv6]:port as part of host
+ switch c {
+ case '!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=', ':', '[', ']':
+ return false
+ }
+ }
+
switch c {
case '-', '_', '.', '~': // §2.3 Unreserved characters (mark)
return false
// that too.
return c == '@' || c == '/' || c == '?' || c == ':'
- case encodeHost: // §3.2.1
- // The RFC allows ':'.
- return c != ':'
-
case encodeQueryComponent: // §3.4
// The RFC reserves (so we must escape) everything.
return true
// everything, so escape nothing.
return false
}
-
- case '[', ']': // §2.2 Reserved characters (reserved)
- switch mode {
- case encodeHost: // §3.2.1
- // The RFC allows '[', ']'.
- return false
- }
}
// Everything else must be escaped.
},
"",
},
+ // issue 12036
+ {
+ "mysql://a,b,c/bar",
+ &URL{
+ Scheme: "mysql",
+ Host: "a,b,c",
+ Path: "/bar",
+ },
+ "",
+ },
+ // worst case host
+ {
+ "scheme://!$&'()*+,;=hello!:port/path",
+ &URL{
+ Scheme: "scheme",
+ Host: "!$&'()*+,;=hello!:port",
+ Path: "/path",
+ },
+ "",
+ },
}
// more useful string for debugging than fmt's struct printer
{'a', encodeUserPassword, false},
{'a', encodeQueryComponent, false},
{'a', encodeFragment, false},
+ {'a', encodeHost, false},
{'z', encodePath, false},
{'A', encodePath, false},
{'Z', encodePath, false},
{',', encodeUserPassword, false},
{';', encodeUserPassword, false},
{'=', encodeUserPassword, false},
+
+ // Host (IP address, IPv6 address, registered name, port suffix; §3.2.2)
+ {'!', encodeHost, false},
+ {'$', encodeHost, false},
+ {'&', encodeHost, false},
+ {'\'', encodeHost, false},
+ {'(', encodeHost, false},
+ {')', encodeHost, false},
+ {'*', encodeHost, false},
+ {'+', encodeHost, false},
+ {',', encodeHost, false},
+ {';', encodeHost, false},
+ {'=', encodeHost, false},
+ {':', encodeHost, false},
+ {'[', encodeHost, false},
+ {']', encodeHost, false},
+ {'0', encodeHost, false},
+ {'9', encodeHost, false},
+ {'A', encodeHost, false},
+ {'z', encodeHost, false},
+ {'_', encodeHost, false},
+ {'-', encodeHost, false},
+ {'.', encodeHost, false},
}
func TestShouldEscape(t *testing.T) {