mirror of
https://github.com/golang/go
synced 2024-11-19 09:54:49 -07:00
net: make SplitHostPort return an empty host on error
This change also refactors SplitHostPort to avoid using gotos and naked returns. Fixes #14827 Change-Id: I4dca528936757fd06da76c23af8a0f6175bbedd1 Reviewed-on: https://go-review.googlesource.com/20726 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
8edb72587f
commit
5630cb7518
@ -421,13 +421,16 @@ func TestSplitHostPort(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, tt := range splitFailureTests {
|
for _, tt := range splitFailureTests {
|
||||||
if _, _, err := SplitHostPort(tt.hostPort); err == nil {
|
if host, port, err := SplitHostPort(tt.hostPort); err == nil {
|
||||||
t.Errorf("SplitHostPort(%q) should have failed", tt.hostPort)
|
t.Errorf("SplitHostPort(%q) should have failed", tt.hostPort)
|
||||||
} else {
|
} else {
|
||||||
e := err.(*AddrError)
|
e := err.(*AddrError)
|
||||||
if e.Err != tt.err {
|
if e.Err != tt.err {
|
||||||
t.Errorf("SplitHostPort(%q) = _, _, %q; want %q", tt.hostPort, e.Err, tt.err)
|
t.Errorf("SplitHostPort(%q) = _, _, %q; want %q", tt.hostPort, e.Err, tt.err)
|
||||||
}
|
}
|
||||||
|
if host != "" || port != "" {
|
||||||
|
t.Errorf("SplitHostPort(%q) = %q, %q, err; want %q, %q, err on failure", tt.hostPort, host, port, "", "")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -110,69 +110,61 @@ func ipv6only(addr IPAddr) bool {
|
|||||||
// must be enclosed in square brackets, as in "[::1]:80",
|
// must be enclosed in square brackets, as in "[::1]:80",
|
||||||
// "[ipv6-host]:http" or "[ipv6-host%zone]:80".
|
// "[ipv6-host]:http" or "[ipv6-host%zone]:80".
|
||||||
func SplitHostPort(hostport string) (host, port string, err error) {
|
func SplitHostPort(hostport string) (host, port string, err error) {
|
||||||
|
const (
|
||||||
|
missingPort = "missing port in address"
|
||||||
|
tooManyColons = "too many colons in address"
|
||||||
|
)
|
||||||
|
addrErr := func(addr, why string) (host, port string, err error) {
|
||||||
|
return "", "", &AddrError{Err: why, Addr: addr}
|
||||||
|
}
|
||||||
j, k := 0, 0
|
j, k := 0, 0
|
||||||
|
|
||||||
// The port starts after the last colon.
|
// The port starts after the last colon.
|
||||||
i := last(hostport, ':')
|
i := last(hostport, ':')
|
||||||
if i < 0 {
|
if i < 0 {
|
||||||
goto missingPort
|
return addrErr(hostport, missingPort)
|
||||||
}
|
}
|
||||||
|
|
||||||
if hostport[0] == '[' {
|
if hostport[0] == '[' {
|
||||||
// Expect the first ']' just before the last ':'.
|
// Expect the first ']' just before the last ':'.
|
||||||
end := byteIndex(hostport, ']')
|
end := byteIndex(hostport, ']')
|
||||||
if end < 0 {
|
if end < 0 {
|
||||||
err = &AddrError{Err: "missing ']' in address", Addr: hostport}
|
return addrErr(hostport, "missing ']' in address")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
switch end + 1 {
|
switch end + 1 {
|
||||||
case len(hostport):
|
case len(hostport):
|
||||||
// There can't be a ':' behind the ']' now.
|
// There can't be a ':' behind the ']' now.
|
||||||
goto missingPort
|
return addrErr(hostport, missingPort)
|
||||||
case i:
|
case i:
|
||||||
// The expected result.
|
// The expected result.
|
||||||
default:
|
default:
|
||||||
// Either ']' isn't followed by a colon, or it is
|
// Either ']' isn't followed by a colon, or it is
|
||||||
// followed by a colon that is not the last one.
|
// followed by a colon that is not the last one.
|
||||||
if hostport[end+1] == ':' {
|
if hostport[end+1] == ':' {
|
||||||
goto tooManyColons
|
return addrErr(hostport, tooManyColons)
|
||||||
}
|
}
|
||||||
goto missingPort
|
return addrErr(hostport, missingPort)
|
||||||
}
|
}
|
||||||
host = hostport[1:end]
|
host = hostport[1:end]
|
||||||
j, k = 1, end+1 // there can't be a '[' resp. ']' before these positions
|
j, k = 1, end+1 // there can't be a '[' resp. ']' before these positions
|
||||||
} else {
|
} else {
|
||||||
host = hostport[:i]
|
host = hostport[:i]
|
||||||
if byteIndex(host, ':') >= 0 {
|
if byteIndex(host, ':') >= 0 {
|
||||||
goto tooManyColons
|
return addrErr(hostport, tooManyColons)
|
||||||
}
|
}
|
||||||
if byteIndex(host, '%') >= 0 {
|
if byteIndex(host, '%') >= 0 {
|
||||||
goto missingBrackets
|
return addrErr(hostport, "missing brackets in address")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if byteIndex(hostport[j:], '[') >= 0 {
|
if byteIndex(hostport[j:], '[') >= 0 {
|
||||||
err = &AddrError{Err: "unexpected '[' in address", Addr: hostport}
|
return addrErr(hostport, "unexpected '[' in address")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if byteIndex(hostport[k:], ']') >= 0 {
|
if byteIndex(hostport[k:], ']') >= 0 {
|
||||||
err = &AddrError{Err: "unexpected ']' in address", Addr: hostport}
|
return addrErr(hostport, "unexpected ']' in address")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
port = hostport[i+1:]
|
port = hostport[i+1:]
|
||||||
return
|
return host, port, nil
|
||||||
|
|
||||||
missingPort:
|
|
||||||
err = &AddrError{Err: "missing port in address", Addr: hostport}
|
|
||||||
return
|
|
||||||
|
|
||||||
tooManyColons:
|
|
||||||
err = &AddrError{Err: "too many colons in address", Addr: hostport}
|
|
||||||
return
|
|
||||||
|
|
||||||
missingBrackets:
|
|
||||||
err = &AddrError{Err: "missing brackets in address", Addr: hostport}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func splitHostZone(s string) (host, zone string) {
|
func splitHostZone(s string) (host, zone string) {
|
||||||
|
Loading…
Reference in New Issue
Block a user